|
Fall Semester 2002 |
1. A Multi-User Domain, or MUD, is a program (a server) that allows multiple
people (clients) to interact with each other and with a shared virtual
environment. The environment is typically a series of rooms or places
linked to each other by various exits. Each room or place has a textual
description that serves as the backdrop and sets the tone for the
interactions between users. Many early MUDs were set in dungeons, with
place descriptions reflecting the dark, underground nature of that
imaginary environment. In fact, the MUD acronym originally stood for
"Multi-User Dungeon". Some MUDs serve primarily as chat rooms for their
clients, while others have more of the flavor of old-style adventure games,
where the focus is on exploring the environment and problem solving. Others
are exercises in creativity and group dynamics, allowing users to add new
places and items to the MUD.
The next 5 examples show classes and interfaces used to define a simple
user-extensible MUD system. A program like this MUD example clearly
demonstrates how the RMI programming paradigm transcends the client/server
model. As we'll see. MudServer and MudPlace are
server objects that create the MUD environment within which users interact.
But at the same time, each user within the MUD is represented by a
MudPerson remote object that acts as a server when interacting
with other users. Rather than having a single server and a set of clients,
then, this system is really a distributed network of remote objects, all
communicating with each other. Which objects are servers and which are
clients really depends on your point of view.
In order to understand the MUD system, an overview of its architecture is
useful. The MudServer class is a simple remote object (and
standalone server program) that defines the entrance to a MUD and keeps
track of the names of all places within a MUD. Despite its name, the
MudServer object does not provide the services that that most
users think of as "the MUD". That is the job of the MudPlace
class.
Each MudPlace object represents a single place within the MUD.
Each place has a name, a description, and lists of the items in the place,
all of the people (users) currently in that place, all of the exits from
the place, and the other places to which those exits lead. An exit may
lead to an adjoining MudPlace on the same server, or it
may lead to a MudPlace object in a different MUD on a
different server altogether. Thus, the MUD environment that a user
interacts with is really a network of MudPlace objects.
It is the descriptions of places and items, and the complexity of
the linkages between places, that give the MUD the richness that
make it interesting to a user.
The users, or people, in a MUD are represented by MudPerson
objects. MudPerson is a remote object that defines two methods.
One method returns a description of the person (i.e., what other people see
when they look at this person) and the other method delivers a message to
the person (or to the user that the MudPerson represents).
These methods allow users to look at each other and to talk to each other.
When two users run into each other in a given MudPlace and
begin to talk to each other, the MudPlace and the server on
which the MUD is running are no longer relevant - the two
MudPerson objects can communicate directly with each
other through the power of RMI.
The examples that follow are long and somewhat complex, but are worth studying carefully. Given the complexity of the MUD system being developed, however, the classes and interfaces defined below are actually surprisingly simple. As you'll see, remote method invocation techniques are very powerful in systems like this one.
2. Remote MUD Interfaces
Example One (Mud.java) is a
Mud class that serves as a placeholder for nested classes
and interfaces (and one constant) used by the rest of the MUD system.
Most importantly, Mud defines three Remote
interfaces: RemoteMudServer, RemoteMudPerson,
and RemoteMudPlace. These define the remote methods that
are implemented by the MudServer, MudPerson,
and MudPlace objects, respectively.
3. The MUD Server
Example Two (MudServer.java)
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 above, 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 of the MUD so it can be
restored later.
4. The MUDPlace class
Example Three (MudPlace.java)
is the MudPlace class that implements the RemoteMudPlace
interface and acts as a server for a single place or room within the MUD. It is this
class that holds the description of a place and maintains the lists of the people and
items in a place and the exits from a place. This is a long class (and so is A348)
but many of the remote methods it defines have simple or even trivial implementations.
The go(), createPlace(), and linkTo() methods
are among the more complex and interesting methods; they manage the network of
connections between MudPlace objects.
Note that the MudPlace is Serializable, so that a
MudPlace (and all places it is connected to) can be serialized along
with the MudServer that refers to them. However, the names
and people fields are declared transient, so they are
not serialized along with the place.
4. The MUDPerson class
Example Four (MudPerson.java)
shows the MudPerson class. This is the simplest of the remote objects
in the MUD system. It implements the two remote methods defined by the RemoteMudPerson
interface and also defines a few non-remote methods used by the MudClient class of
Example Five (following shortly). The remote methods are quite simple: one simply returns a description
string to the caller and the other writes a message to a stream where the user can see it.
5. A MUD Client
Example Five (MudClient.java) is a client
program for the MUD system we've developed in the previous examples. It uses the Naming.lookup()
method to look up the RemoteMudServer object that represents a named MUD on a specified host. The
program then calls getEntrance() or getNamedPlace() method of this
RemoteMudServer object to obtain an initial MudPlace into which to insert the user.
Next, the program asks the user for a name and description of the MudPerson that will represent her
in the MUD, creates a MudPerson object with that name and description, and then places it in the initial
RemoteMudPlace. Finally, the program enters a loop that prompts the user to enter a command and
processes the command. Most of the commands that this client supports simply invoke one of the remote methods
of the RemoteMudPlace that represents the user's current location in the MUD. The end of the
command loop consists of a number of catch clauses that handle the large number of things that
can go wrong.
6. Summary
Here's how you compile and start the MUD server:
So now the server is running.frilled.cs.indiana.edu%pwd /nfs/grouchy/home/user2/www/classes/a348-dger/fall2002/notes/mud frilled.cs.indiana.edu%ls -l total 55 -rw-r--r-- 1 dgerman faculty 7346 Dec 5 00:30 Mud.java -rw-r--r-- 1 dgerman faculty 20816 Dec 5 00:31 MudClient.java -rw-r--r-- 1 dgerman faculty 1665 Dec 5 00:31 MudPerson.java -rw-r--r-- 1 dgerman faculty 18322 Dec 5 00:32 MudPlace.java -rw-r--r-- 1 dgerman faculty 6009 Dec 5 00:32 MudServer.java frilled.cs.indiana.edu%javac -d . *.java frilled.cs.indiana.edu%ls -l total 56 -rw-r--r-- 1 dgerman faculty 7346 Dec 5 00:30 Mud.java -rw-r--r-- 1 dgerman faculty 20816 Dec 5 00:31 MudClient.java -rw-r--r-- 1 dgerman faculty 1665 Dec 5 00:31 MudPerson.java -rw-r--r-- 1 dgerman faculty 18322 Dec 5 00:32 MudPlace.java -rw-r--r-- 1 dgerman faculty 6009 Dec 5 00:32 MudServer.java drwx------ 3 dgerman faculty 512 Dec 5 11:08 a348 frilled.cs.indiana.edu%du -a a348 1 a348/mudExample/Mud$RemoteMudServer.class 1 a348/mudExample/Mud$RemoteMudPerson.class 3 a348/mudExample/Mud$RemoteMudPlace.class 1 a348/mudExample/Mud$MudException.class 1 a348/mudExample/Mud$NotThere.class 1 a348/mudExample/Mud$AlreadyThere.class 1 a348/mudExample/Mud$NoSuchThing.class 1 a348/mudExample/Mud$NoSuchPerson.class 1 a348/mudExample/Mud$NoSuchExit.class 1 a348/mudExample/Mud$NoSuchPlace.class 1 a348/mudExample/Mud$ExitAlreadyExists.class 1 a348/mudExample/Mud$PlaceAlreadyExists.class 1 a348/mudExample/Mud$LinkFailed.class 1 a348/mudExample/Mud$BadPassword.class 2 a348/mudExample/Mud.class 10 a348/mudExample/MudClient.class 2 a348/mudExample/MudPerson.class 2 a348/mudExample/MudPlace$1.class 8 a348/mudExample/MudPlace.class 4 a348/mudExample/MudServer.class 45 a348/mudExample 46 a348 frilled.cs.indiana.edu%rmic a348.mudExample.MudPerson frilled.cs.indiana.edu%rmic a348.mudExample.MudPlace frilled.cs.indiana.edu%rmic a348.mudExample.MudServer frilled.cs.indiana.edu%hostname frilled.cs.indiana.edu frilled.cs.indiana.edu%rmiregistry & [3] 17188 frilled.cs.indiana.edu%java a348.mudExample.MudServer java.lang.ArrayIndexOutOfBoundsException: 0 Usage: java MudServeror: java MudServer frilled.cs.indiana.edu%java a348.mudExample.MudServer "Lindley Hall" a348AG LH102 "lecture hall with 102 seats and a projector" java.net.MalformedURLException: invalid URL string: a348.mudExample.Mud.Lindley Hall Usage: java MudServer or: java MudServer frilled.cs.indiana.edu%java a348.mudExample.MudServer "Lindley_Hall" a348AG LH102 "lecture hall with 102 seats and a projector"
In class we will show how one can connect to the server and play.
tucotuco.cs.indiana.edu% cd /l/www/classes/a348
cdtucotuco.cs.indiana.edu% fall2002
tucotuco.cs.indiana.edu% cd notes
tucotuco.cs.indiana.edu% cd mud
tucotuco.cs.indiana.edu% java a348.mudExample.MudClient frilled.cs.indiana.edu "Lindley_Hall"
Welcome to Lindley_Hall
Enter your name: Larry Bird
Please describe what people see when they look at you:
You can enter multiple lines. End with a '.' on a line by itself.
Or enter a '<<' followed by a filename
A man with with a suitcase.
.
You are in: LH102 of the Mud: Lindley_Hall
lecture hall with 102 seats and a projector
Things here:
People here: Larry Bird
Exits are:
Lindley_Hall.LH102> help
Commands are:
look: Look around
examine <thing>: examine the named thing in more detail
describe <person>: describe the named person
go <direction>: go in the named direction (i.e. a named exit)
say <message>: say something to everyone
do <message>: tell everyone that you are doing something
talk <person>: talk to one person. Will prompt for message
change: change how you are described. Will prompt for input
create <thing>: create a new thing. Prompts for description
destroy <thing>: destroy a thing.
open <direction>: create an adjoining place. Prompts for input
close <direction>: close an exit from this place.
link <direction>: create an exit to an existing place,
perhaps on another server. Will prompt for input.
dump <filename>: save server state. Prompts for password
quit: leave the Mud
help: display this message
Lindley_Hall.LH102>
Any number of concurrent users are allowed.