[ Team LiB ] Previous Section Next Section

21.6 The MUD Server

Example 21-5 shows the MudServer class. This class is a standalone program that starts a MUD running; it also provides the implementation of the RemoteMudServer interface. As noted before, a MudServer object merely serves as the entrance to a MUD: it is not the MUD itself. Therefore, this is a fairly simple class. One of its most interesting features is the use of the serialization classes of java.io and the compression classes of java.util.zip to save the state the MUD, so that it can be restored later.

Example 21-5. MudServer.java
package je3.rmi;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import java.io.*;
import java.util.Hashtable;
import java.util.zip.*;
import je3.rmi.Mud.*;

 * This class implements the RemoteMudServer interface.  It also defines a
 * main( ) method so you can run it as a standalone program that will
 * set up and initialize a MUD server.  Note that a MudServer maintains an
 * entrance point to a MUD, but it is not the MUD itself.  Most of the 
 * interesting MUD functionality is defined by the RemoteMudPlace interface
 * and implemented by the RemotePlace class.  In addition to being a remote
 * object, this class is also Serializable, so that the state of the MUD
 * can be saved to a file and later restored.  Note that the main( ) method
 * defines two ways of starting a MUD: one is to start it from scratch with
 * a single initial place, and another is to restore an existing MUD from a
 * file.
public class MudServer extends UnicastRemoteObject 
    implements RemoteMudServer, Serializable
    MudPlace entrance;  // The standard entrance to this MUD
    String password;    // The password required to dump( ) the state of the MUD
    String mudname;     // The name that this MUD is registered under
    Hashtable places;   // A mapping of place names to places in this MUD
     * Start a MUD from scratch, with the given name and password.  Create
     * an initial MudPlace object as the entrance, giving it the specified
     * name and description.
    public MudServer(String mudname, String password, 
                     String placename, String description)
        throws RemoteException
        this.mudname = mudname;
        this.password = password;
        this.places = new Hashtable( );
        // Create the entrance place
        try { this.entrance = new MudPlace(this, placename, description); } 
        catch (PlaceAlreadyExists e) {  } // Should never happen
    /** For serialization only.  Never call this constructor. */
    public MudServer( ) throws RemoteException {  }                   
    /** This remote method returns the name of the MUD */
    public String getMudName( ) throws RemoteException { return mudname; }
    /** This remote method returns the entrance place of the MUD */
    public RemoteMudPlace getEntrance( ) throws RemoteException { 
        return entrance; 
     * This remote method returns a RemoteMudPlace object for the named place.
     * In this sense, a MudServer acts like an RMI Registry object,
     * returning remote objects looked up by name.  It is simpler to do it this
     * way than to use an actual Registry object.  If the named place does not
     * exist, it throws a NoSuchPlace exception
    public RemoteMudPlace getNamedPlace(String name) 
              throws RemoteException, NoSuchPlace
        RemoteMudPlace p = (RemoteMudPlace) places.get(name);
        if (p == null) throw new NoSuchPlace( );
        return p;
     * Define a new placename to place mapping in our hashtable.  
     * This is not a remote method.  The MudPlace( ) constructor calls it
     * to register the new place it is creating.
    public void setPlaceName(RemoteMudPlace place, String name) 
        throws PlaceAlreadyExists
        if (places.containsKey(name)) throw new PlaceAlreadyExists( );
        places.put(name, place);
     * This remote method serializes and compresses the state of the MUD
     * to a named file, if the specified password matches the one specified
     * when the MUD was initially created.  Note that the state of a MUD
     * consists of all places in the MUD, with all things and exits in those
     * places.  The people in the MUD are not part of the state that is saved.
    public void dump(String password, String f) 
        throws RemoteException, BadPassword, IOException
        if ((this.password != null)&& !this.password.equals(password)) 
            throw new BadPassword( );
        ObjectOutputStream out = new ObjectOutputStream(
                                new GZIPOutputStream(new FileOutputStream(f)));
        out.close( );
     * This main( ) method defines the standalone program that starts up a MUD
     * server.  If invoked with a single argument, it treats that argument as
     * the name of a file containing the serialized and compressed state of an
     * existing MUD, and recreates it.  Otherwise, it expects four command-line
     * arguments: the name of the MUD, the password, the name of the entrance
     * place for the MUD, and a description of that entrance place.
     * Besides creating the MudServer object, this program sets an appropriate
     * security manager, and uses the default rmiregistry to register the
     * the MudServer under its given name.
    public static void main(String[  ] args) {
        try {
            MudServer server;
            if (args.length == 1) {
                // Read the MUD state in from a file
                FileInputStream f = new FileInputStream(args[0]);
                ObjectInputStream in =
                    new ObjectInputStream(new GZIPInputStream(f));
                server = (MudServer) in.readObject( );
            // Otherwise, create an initial MUD from scratch
            else server = new MudServer(args[0], args[1], args[2], args[3]);
            Naming.rebind(Mud.mudPrefix + server.mudname, server);
        // Display an error message if anything goes wrong.
        catch (Exception e) {
            System.out.println("Usage: java MudServer <savefile>\n" +
                               "   or: java MudServer <mudname> <password> " + 
                               "<placename> <description>");

    /** This constant is a version number for serialization */
    static final long serialVersionUID = 7453281245880199453L;
    [ Team LiB ] Previous Section Next Section