/*
* Copyright (c) 2000 David Flanagan. All rights reserved.
* This code is from the book Java Examples in a Nutshell, 2nd Edition.
* It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
* You may study, use, and modify it for any non-commercial purpose.
* You may distribute it non-commercially as long as you retain this notice.
* For a commercial use license, or to purchase the book (recommended),
* visit http://www.davidflanagan.com/javaexamples2.
*/
package com.davidflanagan.examples.rmi;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import java.io.*;
import java.util.*;
import com.davidflanagan.examples.rmi.Mud.*;
/**
* This class is a client program for the MUD. The main() method sets up
* a connection to a RemoteMudServer, gets the initial RemoteMudPlace object,
* and creates a MudPerson object to represent the user in the MUD. Then it
* calls runMud() to put the person in the place, begins processing
* user commands. The getLine() and getMultiLine() methods are convenience
* methods used throughout to get input from the user.
**/
public class MudClient {
/**
* The main program. It expects two or three arguments:
* 0) the name of the host on which the mud server is running
* 1) the name of the MUD on that host
* 2) the name of a place within that MUD to start at (optional).
*
* It uses the Naming.lookup() method to obtain a RemoteMudServer object
* for the named MUD on the specified host. Then it uses the getEntrance()
* or getNamedPlace() method of RemoteMudServer to obtain the starting
* RemoteMudPlace object. It prompts the user for a their name and
* description, and creates a MudPerson object. Finally, it passes
* the person and the place to runMud() to begin interaction with the MUD.
**/
public static void main(String[] args) {
try {
String hostname = args[0]; // Each MUD is uniquely identified by a
String mudname = args[1]; // host and a MUD name.
String placename = null; // Each place in a MUD has a unique name
if (args.length > 2) placename = args[2];
// Look up the RemoteMudServer object for the named MUD using
// the default registry on the specified host. Note the use of
// the Mud.mudPrefix constant to help prevent naming conflicts
// in the registry.
RemoteMudServer server =
(RemoteMudServer)Naming.lookup("rmi://" + hostname + "/" +
Mud.mudPrefix + mudname);
// If the user did not specify a place in the mud, use
// getEntrance() to get the initial place. Otherwise, call
// getNamedPlace() to find the initial place.
RemoteMudPlace location = null;
if (placename == null) location = server.getEntrance();
else location = (RemoteMudPlace) server.getNamedPlace(placename);
// Greet the user and ask for their name and description.
// This relies on getLine() and getMultiLine() defined below.
System.out.println("Welcome to " + mudname);
String name = getLine("Enter your name: ");
String description = getMultiLine("Please describe what " +
"people see when they look at you:");
// Define an output stream that the MudPerson object will use to
// display messages sent to it to the user. We'll use the console.
PrintWriter myout = new PrintWriter(System.out);
// Create a MudPerson object to represent the user in the MUD.
// Use the specified name and description, and the output stream.
MudPerson me = new MudPerson(name, description, myout);
// Lower this thread's priority one notch so that broadcast
// messages can appear even when we're blocking for I/O. This is
// necessary on the Linux platform, but may not be necessary on all
// platforms.
int pri = Thread.currentThread().getPriority();
Thread.currentThread().setPriority(pri-1);
// Finally, put the MudPerson into the RemoteMudPlace, and start
// prompting the user for commands.
runMud(location, me);
}
// If anything goes wrong, print a message and exit.
catch (Exception e) {
System.out.println(e);
System.out.println("Usage: java MudClient <host> <mud> [<place>]");
System.exit(1);
}
}
/**
* This method is the main loop of the MudClient. It places the person
* into the place (using the enter() method of RemoteMudPlace). Then it
* calls the look() method to describe the place to the user, and enters a
* command loop to prompt the user for a command and process the command
**/
public static void runMud(RemoteMudPlace entrance, MudPerson me)
throws RemoteException
{
RemoteMudPlace location = entrance; // The current place
String myname = me.getName(); // The person's name
String placename = null; // The name of the current place
String mudname = null; // The name of the mud of that place
try {
// Enter the MUD
location.enter(me, myname, myname + " has entered the MUD.");
// Figure out where we are (for the prompt)
mudname = location.getServer().getMudName();
placename = location.getPlaceName();
// Describe the place to the user
look(location);
}
catch (Exception e) {
System.out.println(e);
System.exit(1);
}
// Now that we've entered the MUD, begin a command loop to process
// the user's commands. Note that there is a huge block of catch
// statements at the bottom of the loop to handle all the things that
// could go wrong each time through the loop.
for(;;) { // Loop until the user types "quit"
try { // Catch any exceptions that occur in the loop
// Pause just a bit before printing the prompt, to give output
// generated indirectly by the last command a chance to appear.
try { Thread.sleep(200); } catch (InterruptedException e) {}
// Display a prompt, and get the user's input
String line = getLine(mudname + '.' + placename + "> ");
// Break the input into a command and an argument that consists
// of the rest of the line. Convert the command to lowercase.
String cmd, arg;
int i = line.indexOf(' ');
if (i == -1) { cmd = line; arg = null; }
else {
cmd = line.substring(0, i).toLowerCase();
arg = line.substring(i+1);
}
if (arg == null) arg = "";
// Now go process the command. What follows is a huge repeated
// if/else statement covering each of the commands supported by
// this client. Many of these commands simply invoke one of
// the remote methods of the current RemoteMudPlace object.
// Some have to do a bit of additional processing.
// LOOK: Describe the place and its things, people, and exits
if (cmd.equals("look")) look(location);
// EXAMINE: Describe a named thing
else if (cmd.equals("examine"))
System.out.println(location.examineThing(arg));
// DESCRIBE: Describe a named person
else if (cmd.equals("describe")) {
try {
RemoteMudPerson p = location.getPerson(arg);
评论0