CoffeeMud Web Server

  The CoffeeMud Web Server is a simple, extensible web server that runs as part of CoffeeMud; it uses HTTP 1.1 to communicate with a web browser. In addition to being able to serve standard HTML web pages, it also supports a  server-processed form of HTML called CMVP (Coffee MUD Virtual Pages) - this allows the server to insert information into the page before sending it to the browser. This document assumes you have some familiarty with HTTP, mime types, and stuff like that.

How to Connect

By default, the public (pub) web site listens on ports 80 and 27744 and the administrative (admin) web site on port 27777. To browse the default public web site, just open up the following URL in your browser:

http://localhost:27744/

To connect to the administrative web site, use the following URL:

http://localhost:27777/

Features

It supports GET, urlencoded and multipart POST requests, and HEAD requests.  It supports custom servlets, websocks, cookies, sessions, SSL, gzip and deflate encodings, pipelining, etag support, ranged requests, async IO (fast!), mapping mime types to java converter and filter classes, file caching, and more.  It supports numerous coded web macros, as well as inline server-side Javascripts to create custom pages.  It does not make coffee, but it does make CoffeeMud better. :)

Security

The web server uses explicitly mounted directories to control access to your CoffeeMud filesystem (CMFS).  You can mount more directories or remove existing ones by changing the MOUNT list in the configuration files (see below).   The default installation runs one of the two web servers with an "ADMIN=true" flag in its configuration, allowing it to access the more powerful CoffeeMud macros.  The web server also supports SSL (https).  However, this is not turned on by default, since it requires access to a special SSL web certificate from a respected certification agency, such as Verisign.  To learn more about setting this up, see the SSLPORT entry and the information under SSL CONFIGURATION in the common.ini configuration file.  Lastly, the configuration files have a BIND entry that can be used to restrict connections to your administration server, but is not set by default.

Configuration

The default installation of CoffeeMud has two inbuilt web servers, named 'pub' and 'admin'. The web servers are enabled with the line 'RUNWEBSERVERS=pub,admin' in 'coffeemud.ini'; absence of this line will cause the web servers not to be loaded.

INI files for the web servers live in the 'web/' directory off the CoffeeMud root; by default, all pages to be served go in web/(servername)/, though this can be overridden. Options are placed in either 'web/common.ini' or 'web/(servername).ini'; an option in the latter will override one in common.  This means that some configuration options are in web/pub.ini for the "pub" server, web/admin.ini for the "admin" server, and web/common.ini for Both.

The configuration options are:

  • PORT=xx : [REQUIRED] (e.g. PORT=80) (e.g. PORT=80,27744)
    SSLPORT
    =xx (e.g. SSLPORT=443)

    Sets the port number the web server will listen for HTTP and HTTPS requests on; this cannot be the same port as the main MUD server or another web servers. This list may be comma delimited to start more than one instance on different ports. Normally this would go in pub.ini and admin.ini.

  • DEBUGFLAG=xx : (e.g. DEBUGFLAG=off)

    An alternative way to turn on debugging messages in the web server.  The more appropriate way is the DEBUG entry in coffeemud.ini.  Values here include ON, OFF, FILE, or BOTH.

  • BIND=addr : (e.g. BIND=127.0.0.1)

    Causes the server to be bound to a specific address; this is useful on multi-homed machines or if you wish to prevent public access to the pages. Identical to MUD server usage.

    The Admin server should be bound to localhost (or 127.0.0.1) in admin.ini unless you really know what you're doing...

  • ADMINEMAIL=email address: 
    The administrators email address, for informational purposes only.
  • DEFAULTPAGE=filename : [REQUIRED] (e.g. DEFAULTFILE=index.cmvp)

    Sets the default filename to be appended if none is specified in the request.  This is in common.ini.

  • MOUNT*=/web/path
    This is where you specify how requested hosts and contexts will map to actual directories on your local hard drive.  The way it works is that you specify the word MOUNT followed by a forward slash character / and the optional host name and optional port, and the context, then set that equal to the coffeemud directory path that the given context should map to.  Be sure to end your hard drive path with a path separator /.  The example MOUNT/mydomain.com:80/remote=/web/pub maps the context /remote on the host
    "mydomain.com" on port 80 to the CoffeeMud local path "/web/pub" The example MOUNT/=/web/admin maps the root context / to the relative path "root\\" for all hosts and ports.
  • SSLKEYSTOREPATH=path/to/keystore.jks (e.g. SSLKEYSTOREPATH=keys/keystore.jks)
    SSLKEYSTOREPASSWORD=
    keystore file password (e.g. SSLKEYSTOREPASSWORD=mypassphrase)
    SSLKEYSTORETYPE=
    JKS (are there other useful values for this?)
    SSLKEYMANAGERENCODING=
    SunX509 (are there other useful values for this?)

    Allows you to turn on support for SSLv3 via a java keystore file (SSLKEYSTOREPATH), but you can specify any key file format that java supports, so long as you also specify its type (SSLKEYSTORETYPE).  If the keystore/file has a password, specify it also (SSLKEYSTOREPASSWORD). If any of this stuff is invalid, the web server will not attempt to listen on your SSL ports.  These are normally in common.ini

  • FILECACHEEXPIREMS=milliseconds (e.g. FILECACHEEXPIREMS=300000)
    FILECACHEMAXBYTES=
    #bytes (e.g. FILECACHEMAXBYTES=65535)
    FILECACHEMAXFILEBYTES=
    #bytes (e.g. FILECACHEMAXFILEBYTES=8192)
    FILECOMPMAXBYTES=
    #bytes (e.g. FILECOMPMAXBYTES=16485760)

    The data for your web site can be cached in memory for better performance.  To tune this feature, you can specify the amount of time a cache entry lives in memory (FILECACHEEXPIREMS), how much TOTAL file data will be stored in the cache before it starts forcing entries out of the cache to make more room (FILECACHEMAXBYTES), and the maximum size of any one file stored in the cache (FILECACHEMAXFILEBYTES). The maximum size of any file that can be compressed is  FILECOMPMAXBYTES. To turn any of these off entirely, specify a value of 0.  If you have lots of allocated java memory, however, making those numbers larger will help performance.  These are also in common.ini.

  • REQUESTMAXBODYBYTES=#bytes (e.g. REQUESTMAXBODYBYTES=2097152)
    REQUESTMAXIDLEMS=milliseconds (e.g. REQUESTMAXIDLEMS=30000)
    REQUESTLINEBUFBYTES=#bytes (e.g. REQUESTLINEBUFBYTES=65535)
    REQUESTMAXALIVESECS=seconds (e.g. REQUESTMAXALIVESECS=15)
    REQUESTMAXPERCONN=#requests (e.g. REQUESTMAXPERCONN=20)

    This is some fine tuning regarding constraints on http requests.  You can specify the maximum size of any request body (REQUESTMAXBODYBYTES), the number of milliseconds a connection can sit idle between requests (REQUESTMAXIDLEMS), The maximum size of any one line of request data, such individual headers, url length, etc (REQUESTLINEBUFBYTES), the longest amount of time a connection can hang around sending requests to the web server and receiving data (REQUESTMAXALIVESECS), and the maximum number of requests that can be made on a single connection (REQUESTMAXPERCONN). 

    All of these are normally defined in common.ini, except for REQUESTMAXALIVESECS, which is defined in pub.ini and admin.ini by default.

  • CORETHREADPOOLSIZE=#threads (e.g. CORETHREADPOOLSIZE=1)
    MAXTHREADS=#threads (e.g. MAXTHREADS=10)
    MAXTHREADIDLEMILLIS=milliseconds (e.g. MAXTHREADIDLEMILLIS=60000)
    MAXTHREADQUEUESIZE=#tasks (e.g. MAXTHREADQUEUESIZE=500)
    MAXTHREADTIMEOUTSECS=seconds (e.g. MAXTHREADTIMEOUTSECS=30)

    Now for the really geeky stuff.  The web server will try to process as many requests at the same time as it can by spawning threads when it needs to.  You can tweek this process right here.  You can specify the minimum number of threads to keep hanging around waiting
    to process requests (CORETHREADPOOLSIZE), as well as the absolute maximum number (MAXTHREADS). You can also specify the amount of time a thread goes unused before it is shut down (MAXTHREADIDLEMILLIS), the maximum number of tasks that can be queued up waiting for thread time (MAXTHREADQUEUESIZE), and the absolute maximum amount of time a thread is allowed to
    work on any one task (MAXTHREADTIMEOUTSECS).

    All of these are normally defined in common.ini, except for MAXTHREADTIMEOUTSECS, which is defined in pub.ini and admin.ini by default.

  • ADMIN=true/false

    This allows admin macros to run on this server or not (see below).  This is always in admin.ini, for obvious reasons.

  • MIME.*=xx
    Defines a new mime type.  For example, MIME.php=application/php
  • MIMECONVERT.*=javaclass
    For the Java programmers, there is an interface available at com.planet_ink.coffee_web.interfaces.HTTPOutputConverter for creating classes that transform data from a specific mime type by processing it. Since it only supports the mime types hard coded into com/planet_ink/coffee_web/http/MIMEType.java. this is of limited usefulness -- still, you can do cool things make make custom http page converters! When you create such a converter, you specify it here by mapping the class to a mime type name by using the word "MIMECONVERT" followed by a period, followed by the mime type name, and then setting that equal to the java class name where your HTTPOutputConverter can be found.  Have as many as you like! Of course, using a mime converter will invalidate any eTag processing, since the whole point is to change the contents of pages from disk. :)
    MIMECONVERT.cwhtml=com.planet_ink.coffee_web.converters.CWHTMLConverter
    MIMECONVERT.cmvp=com.planet_ink.coffee_mud.Libraries.WebMacroCreamer
  • ERRORPAGE=path/filename (e.g. ERRORPAGE=/web/pub.templates/errorpage.cwhtml)

    When an error or exception is generated, which page is displayed.  This is a LOCAL PATH,  either relative or absolute.  This is normally defined in the pub.ini and admin.ini files.

  • FORWARD*=address
    This is where you specify how requested hosts, ports, or contexts will be forwarded to other web servers and ports and contexts. The way it works is that you specify the word FORWARD followed by a forward slash character / and the optional host name and optional port and the context (or just /), and then set that equal to the host name of the remote web server, followed by a colon and the remote port number.  You can specify as many mappings as you like .. coffeewebserver will be pretty smart about  which is the proper one to use for any particular url.
    Remember to escape your colons and backslashes (if you use them)!!  Some examples:
    FORWARD/mydomain.net\:80/contextname=www.google.com\:80
    FORWARD/localhost\:8080/zimmers=www.zimmers.net\:80
  • CGIMOUNT*=/web/path
    This is where you specify how requested hosts and contexts will map to CoffeeMud paths on your local hard drive containing CGI (Common Gateway Interface) programs that the server is permitted to execute.  Any URL path parts after the mount directory is passed to the cgi-program. The mount path can also be an executeable file name. The way it works is that you specify the word CGIMOUNT followed by a forward slash character / and the optional host name and optional port, and the context, then set that equal to the CoffeeMud path that the given context should map to.  If thepath is a directory, any cgi-programs in it may be executed, and if it is a program file, it will be executed against the referenced path.  The URI context may also contain a "*" character for filtering purposes.  Be sure to end your path with a path separator /.  The example CGIMOUNT/mydomain.com:80/cgi-bin=root\\cgi-bin\\ maps the context /cgi-bin on the host
    "mydomain.com" on port 80 to the relative local path "root\\cgi-bin\\"  The example CGIMOUNT/*.php=cgi-bin\\php-cgi.exe executes the given cgi program against any .php files for
    all hosts and ports.
  • BROWSEPAGE=path/filename (e.g. BROWSEPAGE=/web/pub.templates/browsepage.cwhtml)

    When a directory is encountered which is permitted to be browsed (see BROWSE below), this is the local path, relative or absolute, of the page to display.  If the page is kept at cwhtml or another Convertable type, then the page will correctly fill in directory entries.

  • BROWSE*=xx
    This is where you specify which virtual paths which, after going through mount processing, resolve to directories that you will permit browsing of. Specify the word BROWSE followed by a forward slash character / and the optional host name and optional port, and the context, then  set that equal to anything you like (the value is reserved for future use at this point). The example BROWSE/mydomain.com:80/mysubdir=OK allows the context /mysubdir on the host "mydomain.com" on port 80 to be browsed.  The example BROWSE/=YES allows all directories, all hosts, all ports, to be browseable
  • ACCESSLOGS=xx : (e.g. ACCESSLOGS=off)

    An way to turn on web access  messages in the web server.  The more appropriate way is the DEBUG entry in coffeemud.ini. Values here include ON, OFF, FILE, or BOTH.

  • THROTTLEOUTPUT*=xx
    This is where you specify how many bytes, per second, are allowed to be sent to the specified host.  Specify THROTTLEOUTPUT followed by a forward slash character / and the optional host name and optional port and the context (or just /), and then set that equal to the number of bytes per second to allow in or out.  Specify as many entries as you like.  The throttle treats the number of bytes that applies as a cap to ALL requests, in or out, that apply to a specified host mask.  It will attempt to be fair about distributing load across numerous requests for a given host, and will treat each host mask as a separate pool from other hosts. Remember to escape your colons and backslashes (if you use them)!! Some examples:
    THROTTLEOUTPUT/mydomain.net\:80/contextname=1024
    THROTTLEOUTPUT/localhost\:8080/zimmers=10000000
  • DUPPOLICY=xx
    How to deal with url parameters or multi-part fields that have the same names.  For example: http://localhost?MYFIELD=bob&MYFIELD=joe&MYFIELD=tom
    Set DUPPOLICY to OVERWRITE to end up only one field where the last value wins.
    Set DUPPOLICY to ENUMERATE to append a number; e.g. MYFIELD=bob MYFIELD1=joe MYFIELD2=tom
  • CHUNKSIZE=xx
    CHUNKALLOW*=yy
    How to encourage or specify chunked encoding output from the server to clients.  Will only provide chunked output according to the CHUNKHOST entries below. Set CHUNKSIZE to the default chunk size to use when allowed. A value of  0 completely disables chunked responses under all circumstances.  To allow chunked responses at particular domains or urls, enter "CHUNKALLOW" followed by  a forward slash character / and the optional host name and optional port and the  context (or just /), and then set that equal to either an asterisk * or a comma delimited list of mime types to apply chunking to, followed by a colon, followed by the minimum size of a file, in bytes, that may be chunk encoded.  Specify as many entries as you like.  Here are some examples:
    CHUNKALLOW/*\:*/=*:1                  <-- this will chunk everything, basically
    CHUNKALLOW/mydomain.net\:80/contextname=*:1048576
    CHUNKALLOW/texas.localhost\:*/=application/octet-stream,h323,doc:9999999
  • SERVLET*=javaclass
    For you Java programmers, there is an interface available at com.planet_ink.coffee_web.interfaces.SimpleServlet for creating simple servlet classes.  There is also a SimpleServletRequest and SimpleServletResponse interface for doing your input and output.  When you create such a servlet, you can map it to a top-level url context by using the word "SERVLET" followed by a slash, followed by the root url context, and then setting that equal to the java class name where your SimpleServlet can be found.  Have as many as you like!
    # Check out the example servlets in com/planet_ink/coffee_web/servlets/*.java
  • DISABLE=true/false
    For developers and those who just don't like functional web servers, this is a comma-delimited list of integrated features you would like to have disabled.  Available features to disable are:  RANGED : the web server will ignore ranged headers and return 200/full document

Virtual Directories

To permit web access to the files in particular CoffeeMud directories, you can specify MOUNT/virtualdir=physicaldir in the pub.ini or admin.ini files; for example, MOUNT/guides=guides creates a virtual directory with access to the player guides.  If you want, you can also tie particular web hostnames and ports to particular directories.  For example MOUNT/mydomain.com:8080/files=/web/pub would allow browser urls such as http://www.mydomain.com:8080/files to access the /web/pub folder.

CoffeeMud Virtual Pages

Kind of misnamed (these pages in their original, very different incarnation didn't exist at all), this is typically a HTML or plaintext file that is preprocessed by the server before being dispatched to the browser. Preprocessing is a simple search-and-replace; NO ACCOUNT is taken of where the macro appears within the file (ie, macros within comments or quoted strings will be replaced).

Macros are always surrounded by the AT sign (@), and are thus delineated in the page. Any parameters required for a macro always follow the macro name and a Question Mark (?). Further parameters are separated by the Ampersand (&) character. Each parameter may optionally be an equation, where the name is on the left of an equal sign, and its value on the right. An example of all this in action would be:

@MacroName?PARAMETER&PARM2=VALUE&PARM3@

Macros may be embedded in each other ONLY if the embedded macros are part of the parameters of the host macro, which means they must follow the Question Mark. Also, for each level of embedding, an extra At sign (@) character is used around the macro. To avoid confusion, the closing At signs (@) should be separated by spaces. Here is an example of embedded Macros (in this case, two macros are used for each of two parameters to a first macro (MacroOne):

@MacroOne?@@MacroTwo?PARM@@&@@MacroThree?PARM@@ @

Notice the space before the final At sign (@). Now, here is an example of double-embedding, where MacroThree is embedded as the parameter to MacroTwo, which is embedded as the parameter to MacroOne:

@MacroOne?@@MacroTwo?@@@MacroThree?PARM@@@ @@ @

Here are the macros defined so far. Keep in mind the difference between a Macro parameter (things which follow the first Question mark in a macro), and a Request Parameter (data submitted from a <FORM> on a web page, or on the URL line of a GET request). Macro parms will be abbreviated to MacParm, while Request Parameters will be abbreviated to ReqParm.

Macro Description
AbilityAffectNext Sets the ReqParam ABILITY to the next Ability which no class qualifies for. MacParms may include the types of Abilities to show. ABILITYTYPE ReqParm may also be set to an Ability type to show. A MacParm of NOT negates the list. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
AbilityBlessingNext This iterates through deity blessings. Set ReqParm DEITY to a valid deity name, call it with MacParm RESET to clear ABILITY ReqParm. Call it with MacParm NEXT to set ABILITY ReqParm to next blessing the deity has.
AbilityCursesNext This iterates through deity curses. Set ReqParm DEITY to a valid deity name, call it with MacParm RESET to clear ABILITY ReqParm. Call it with MacParm NEXT to set ABILITY ReqParm to next curse the deity has.
AbilityData Requires ReqParm ABILITY be set an an Ability ID. Returns information about the ability from the Macro parms. Valid MacParms include things like name, help, ranges, quality, target, alignment, domain, qualifyQ (if ReqParm CLASS is set to a valid character class), auto.
AbilityDomainNext Sets the ReqParam DOMAIN to the next Spell Domain. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
AbilityGainReport Set the optional ReqParm CLASS.  This generates an entire table which caches every player in your database and calculates the average proficiency of every skill from every class (or the specified one).
AbilityID Requires ReqParm ABILITY be set an an Ability ID. Returns that ID.
AbilityName Requires ReqParm ABILITY be set an an Ability ID. Returns the name of the Ability designated.
AbilityNext Sets the ReqParam ABILITY to the next Ability asked for. MacParms may include the types of Abilities to show. ABILITYTYPE ReqParm may also be set to an Ability type to show, DOMAIN to set the Ability Domain to show, FLAGS (~ delimited) to show Abilities by flag name, GENERIC for generic abilities only, UNQUALIFIEDOK to include all directories, NOT to negate the requirements, ALL to show all, SORTEDBYNAME. ReqParam may also contain some of these values as well. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
AbilityPlayerNext This Macro is a mess -- it iterates through player abilities. The simplest way to use it is to set ReqParm PLAYER to a valid player name, call it with MacParm RESET to clear ABILITY ReqParm. Call it with MacParm NEXT to set ABILITY ReqParm to next ability the player has.
AbilityPowersNext This iterates through deity curses. Set ReqParm DEITY to a valid deity name, call it with MacParm RESET to clear ABILITY ReqParm. Call it with MacParm NEXT to set ABILITY ReqParm to next power the deity might give.
AbilityRaceNext This iterates through racial abilities. Set ReqParm RACE to a valid race name, call it with MacParm RESET to clear ABILITY ReqParm. Call it with MacParm NEXT to set ABILITY ReqParm to next ability the race has.
AbilityTypeNext Sets the ReqParm ABILITYTYPE to the next Ability Type. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
AccountCreate Given MacParm CREATE, will create a new account from the incoming data.
AccountData Given ReqParm ACCOUNT, and various MacParm values, this will return information about a player account.
AccountID Returns the value of the ReqParm ACCOUNT.
AccountNext Sets ReqParm ACCOUNT to the name of the next player account. The MacParm RESET will reset. Returns @break@ after the last account.
AccountOnline Given the ReqParm ACCOUNT, will return "true" if the player account is online right now. Other MacParms include: BANBYNAME, BANBYIP, BANBYEMAIL, EXPIRENEVER, EXPIRENOW, or BOOT.
AccountPlayerNext Sets ReqParm PLAYER to the name of the next character in the account from ReqParm "ACCOUNT". The MacParm RESET will reset. Returns @break@ after the last account.
AchievementData Given ReqParm ACHIEVEMENT, and various MacParm values, this will return information about an achievement definition.
AchievementID Returns the value of the ReqParm ACHIEVEMENT.
AchievementNext Sets ReqParm ACHIEVEMENT to the ID of the next achievement definition. MacParm or ReqParm AGENT is required to limit the list. The MacParm RESET will reset. Returns @break@ after the last achievement.
AddFile The parameters for this macro are a list of file names. Inserts the contents of the files into the current document. If the MacParm "WEBIFY" precedes a file name in the list, then the macro will reformat the text file for the web, translating any CoffeeMud color codes, spaces, line breaks, and other special characters not normally displayable on the web.
AddRandomFile The parameters for this macro are a list of file names. This macro inserts the contents of one of the files at random into the current document. If the parameter LINKONLY is included, this macro will instead insert the path and file name of the random file.
AddRandomFileFromDir The parameters for this macro are a list of directory names. This macro inserts the contents of one of the files at random from one of the directories into the current document. If the parameter LINKONLY is included, this macro will instead insert the path and file name of the random file.
AddRequestParameter The parameters for this macro are one or more ReqParm names and values. For example @AddRequestParameter?PARM1=VALUE&PARM2=VALUE@. This is usually used to provide literal data for other macros which may require certain Request parameter data.
Special values for VALUE are:
++ to increment the variable numerically
-- to decrement the variable numerically
** to multiply the variable by 2
##( ... ) to apply the value to the variable as a math formula found between the ().
AllQualifyData Given ReqParm ALLQUALID, and various MacParm values, this will return information about an all qualifying skill definition.
AllQualifyNext Sets ReqParm ALLQUALID to the ID of the next all qualifying skill definition. The MacParm RESET will reset. Returns @break@ after the skill.
AreaChildNext
Requires ReqParm PARENTAREA to be set to a valid area name.  Sets the ReqParm AREA to the next child Area. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing. MacParm HIDDENOK includes hidden areas.
AreaData Requires ReqParm AREA be set to a valid area name. Returns information about that area depending on the MacParms. Valid MacParms include: HELP, CLIMATES, THEME, BEHAVIORS, AFFECTS, NAME, AUTHOR, CLASSES, SUBOPS, DESCRIPTION, SEASON, TODCODE, WEATHER, MOON, STATS, HASCHILD, HASPARENT
AreaID Requires ReqParm AREA be set to a valid area name. Returns that name.
AreaIDEncoded Requires ReqParm AREA be set to a valid area name. Returns that name, but url encoded.
AreaItemNext Sets the ReqParm ITEMHASH, AITEMROOM, AITEMNAME, AITEMHASH to the next item saved in an Area. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found.
AreaMobNext Sets the ReqParm MOBHASH, AMOBROOM, AMOBNAME, AMOBHASH to the next mob saved in an Area. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found.
AreaName Requires ReqParm AREA be set to a valid area name. Returns that name.
AreaNameEncoded Requires ReqParm AREA be set to a valid area name. Returns that name encoded for an HTTP GET request.
AreaNext Sets the ReqParm AREA to the next Area. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing. MacParm HIDDENOK includes hidden areas.
AreaScriptData
AreaScriptKey
AreaScriptNext
AreaTbl Returns a formatted HTML table containing all the areas currently installed in the game; as with @PLAYERLIST@, the enclosing <TABLE>..</TABLE> must still be specified. Each <TD> element has style-sheet class cmAreaTblEntry. The area list may only be obtained while the mud server is running; otherwise a simple table containing a game-not-running message is returned.
AreaXML
Authenticate Requires ReqParms LOGIN and PASSWORD to be unencrypted login data, or AUTH to be encrypted login data. If MacParm AUTH specified, will return the encrypted login data. Otherwise, returns "true" if login is valid, and "false" otherwise.
AutoAwardData
AutoAwardID
AutoAwardNext
AutoTitleData
AutoTitleID
AutoTitleNext
back Denotes the looping point for a @loop@ block. See the @loop@ macro.
BankAccountInfo Requires ReqParm BANKCHAIN and either PLAYER or CLAN be set to a valid name. Accepts MacParm HASACCT, BALANCE, DEBTAMT, DEBTRSN, DEBTDUE, DEBTINT, NUMITEMS, ITEMSWORTH, ITEMSLIST.
BankChainName Returns the value of ReqParm BANKCHAIN.
BankChainNext Sets the ReqParm BANKCHAIN to the next existing bank chain. If ReqParm PLAYER or CLAN is non-empty, will return only chains where the name given has an account with the chain.  Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
BanListMgr Handles the banned user list. MacParm RESET will clear ReqParm BANNEDONE. MacParm NEXT will set BANNEDONE to the next banned user or ip. MacParm NEXT returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" also found. MacParm DELETE will delete banneded name/ip that ReqParm BANNEDONE is se to. MacParm ADD will create a new banned name/ip from ReqParm NEWBANNEDONE.
BaseCharClassName Requires ReqParm BASECLASS be set to a valid base character class id. Returns the name of that class.
BaseCharClassNext Sets the ReqParm BASECLASS to the next base character class. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
BehaviorData Requires ReqParm BEHAVIOR be set to a valid behavior id. Accepts MacParm HELP.
BehaviorID Requires ReqParm BEHAVIOR be set to a valid behavior id. Returns that ID.
BehaviorNext
block Defines the beginning of a block of html that may be inserted elsewhere.  This block may include its own web macros, to be evaluated when and where they are inserted.  The MacParm defines the unique name of the block. The block is ended with @/block@.
For example @block?SILLY@ Some stuff @/block@.
break Stops inserting text into a web page at the current point, skips ahead to the next @back@ macro found, and starts again. If no @back@ macro is found, the page will not continue to be evaluated. See the @loop@ macro. This macro is actually returned by many other macros as a means of creating breaks in loops.
CatalogCatNext
CatalogItemNext
CatalogMobNext
ChannelBackLogNext Requires ReqParms LOGIN and PASSWORD to be unencrypted login data, or AUTH to be encrypted login data. Also requires CHANNEL to be the name of a valid channel. Returns the next available channel message, and sets ReqParm CHANNELBACKLOGNUM. Will not break out if MacParm EMPTYOK is given.
ChannelFunction
ChannelInfo
ChannelNext Requires ReqParms LOGIN and PASSWORD to be unencrypted login data, or AUTH to be encrypted login data. Returns the next available channel in ReqParm CHANNEL. Will clear out if MacParm RESET is given.
CharClassData Requires ReqParm CLASS be set to a valid character class id. Returns data about this class depending on MacParms found. Valid MacParms include: help, playable, max stats, pracs, trains, hitpoints, mana, movement, attack, weapons, armor, limits, bonuses, prime, quals, startingeq.
CharClassID Requires ReqParm CLASS be set to a valid character class id. Returns that ID.
CharClassName Requires ReqParm CLASS be set to a valid character class id. Returns the name of that class.
CharClassNext Sets the ReqParm CLASS to the next character class. List may be limited by ReqParm BASECLASS if found. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
CheckAuthCode
CheckFactionLoaded
CheckReqParm Evaluates to the string "true" if the specified Request parameters is equal to the values for them given. For example, @CheckReqParm?PARM=VALUE@ would return "true" if the PARM request parameter is "VALUE", and "false" otherwise. See the @if?@ macro for more information on how this may be useful.
ChkReqParmBreak Evaulates to the string " @break@" (see the break macro) if the specified Request parameters are equal to the values given. It returns "" otherwise. For example, @ChkReqParmBreak?PARM=VALUE@ would return " @break@" if PARM is equal to VALUE, and "" otherwise. See the @loop@ macro for more information on how this might be useful.
ClanData Requires ReqParm CLAN be set to a valid clan id. Returns information about that clan depending on MacParms found. Valid MacParms include: PREMISE, RECALL, DONATION, TAX, EXP, CCLASS, AUTOPOSITION, STATUS, ACCEPTANCE, TYPE, POINTS, CLANIDRELATIONS (also requires ReqParm CLANID), MEMBERSTART (sets ReqParm CLANMEMBER; like ClanNext?RESET, but for clan members list), MEMBERNEXT (goes with MEMBERSTART), MEMBERNAME, MEMBERPOS (these last two require MEMBERSTART/MEMBERNEXT use)
ClanGovernmentData
ClanGovernmentID
ClanGovernmentNext
ClanID Requires ReqParm CLAN be set to a valid clan id. Returns the id.
ClanNext Sets the ReqParm CLAN to the next clan found. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
ClassRaceNext Requires ReqParm CLASS be set to a valid character class id. Sets the ReqParm RACE to the next race qualified for the given class. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
CoffeeTableRows
CommandJournalInfo
CommandJournalNext
ComponentData
ComponentID
ComponentNext
ComponentPieceData
ComponentPieceID
ComponentPieceNext
ControlPanel
CrossBaseClassAbilities
CrossClassAbilities Returns a full HTML table of classes and abilities.
DeityData Requires ReqParm DEITY be set to a valid deity name. Returns information about that deity depending on MacParms found. Valid MacParms include: DESCRIPTION, WORSHIPREQ, CLERICREQ, WORSHIPTRIG,CLERICTRIP,WORSHIPSINTRIG,CLERICSINTRIG,POWERTRIG
DeityID Requires ReqParm DEITY be set to a valid race name. Returns the id.
DeityNext Sets the ReqParm DEITY to the next deity found. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
DelRequestParameter Removes the given Request (URL) parameters, unless one of them is ALLBUT, in which case it removes all Request (URL) parameters except those listed.
else Creates an exception to an @if?@ macro.
endif Denotes the end of an @if?@ block. See the @if?@ macro.
ExitData MUDGrinder support macro for showing exit data on maps. Too complicated to describe.
ExpertiseData Requires ReqParm EXPERTISE be set to a valid expertise id. Returns information about that expertise depending on MacParms found. Valid MacParms include: NAME, HELP, COST, REQUIRES.
ExpertiseID Requires ReqParm EXPERTISE be set to a valid expertise id. Returns the id.
ExpertiseNext Sets the ReqParm EXPERTISE to the next expertise found. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
FactionData
FactionID
FactionName
FactionNext
FileData
FileInfo
FileMgr
FileNext
ForumInfo
ForumJournalNext
for The parameters for this macro are a variable name followed by an equal sign (=) followed by another macro name which evaluates to a comma-delimited string. That macro does not follow the embedding rules above. This macro requires an @next@ macro, and will assign a request parameter of the same name as the variable name equal to an entry in the string returned by the macro in each iteration. For example: @for?EXITFLAG=ExitData?ISGENERIC&NAME@ would iterate twice, with reqparm EXITFLAG = true (or false) the first time, and a NAME the second time. @for?COUNTER=1,2,3,4@ would iterate 4 times, with reqparm COUNTER = 1 on the first iteration, then 2, 3 and finally 4.
HelpTopics Handles the showing of help topics. MacParm RESET will clear ReqParm HELPTOPIC and HELPFIRSTLETTER. MacParm NEXT will set HELPTOPIC to the next help topic depending on other MacParms found (SHORT to not include abilities, ARCHON to show only Archon Help, BOTH to show Archon and Player Help, FIRSTLETTER=val to show only those with starting letter (ReqParm HELPFIRSTLETTER does the same). MacParm NEXT returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" also found. MacParm NEXTLETTER sets ReqParm HELPFIRSTLETTER to next letter in the alphabet, returning @break@ when done. MacParm DATA returns the help text denoted by ReqParm HELPTOPIC.
HolidayData
HolidayID


HTTPclientIP Returns the client's IP address.
HTTPstatus Returns the http return code; this is normally of no use ("200 OK") unless customising the error page.
HTTPstatusInfo Returns additional http status information; this is normally of no use unless customising the error page.
if The Single, Required parameter for this macro is another macro name which evaluates to the words "true" or something else (which is defined as false). That macro does not follow the embedding rules above. This macro requires an @endif@ macro, and may optionally have an @else@ macro. The "!" character may follow either "?" characters to negate the value of the expression, or the comparison respectively.  Multiple expressions must all be true for the overall expression to be true, unless an expression macro name begins with ||, which will evaluate as "or".  Starting the macro name with "<" will evaluate as less than or starts with, ">" as greater than or ends with, and "*" as substring match.
For example: 
@if?!CheckReqParm?PARM=VALUE@ would return true and false (or vis-versa) depending whether the request parameter PARM was equal to VALUE.
ImageVerificationImage
INIEntry
INIModify
INIValue
insert Inserts the html of a previously defined @block?@ of the name given in the reqparm.  See @block@ above.  For example @insert?SILLY@.
IsAccountSystem If account system is enabled, returns "true", else "false"
IsDisabled If the system DISABLE flag in the MacParm is found, "true" is returned.
IsExpirationSystem If the account expiration system is enabled, returns "true", else "false".
ItemData MUDGrinder macro for support of mob and room items. Too complicated to describe.
JournalFunction Requires ReqParm JOURNAL be set to a valid journal name, and an authenticatable user found (see Authenticate). If MacParm NEWPOST found, along with ReqParms TO, SUBJECT, and NEWTEXT, a new post is added. If ReqParm JOURNALMESSAGE is set to a valid message number for this journal, then MacParm DELETE will delete the message. If MacParm REPLY and ReqParm NEWTEXT found, a reply added to the designated message.
JournalInfo Requires ReqParm JOURNAL be set to a valid journal name. Returns information about the journal depending on MacParms found. Valid MacParms include: COUNT, to return messages found. If ReqParm JOURNALMESSAGE is set to a valid message number for this journal, and an authenticatable user is found (see Authenticate) additional MacParms may be used to get information about that message. These MacParms include: KEY, FROM, DATE, TO, SUBJECT, MESSAGE
JournalMessageNext Requires ReqParm JOURNAL be set to a valid journal name, and an authenticatable user found (see Authenticate). Sets the ReqParm JOURNALMESSAGE to the next message found in the given journal. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
JournalName Requires ReqParm JOURNAL be set to a valid journal name. Returns that name.
JournalNext Sets the ReqParm JOURNAL to the next journal found. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
LevelNext Sets the ReqParm LEVEL to the next number between 1 and 30. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
LevelNumber Requires ReaParm LEVEL be set to a number between 1 and 30. Returns that number.
LogViewer Returns the CoffeeMud log file. PAGEBREAK parameter sets max lines. REVERSE starts on last page. Url Parameter PAGE determines page#. PAGEBREAK will set PREVPAGE and NEXTPAGE
loop Repeatedly inserts into the page the contents between this macro and the corresponding @back@ until a @break@ macro located inside the block is processed. This @break@ string is most often returned by a macro processed within the block, but may also be embedded in an @if?@ macro block as well.
MobData MUDGrinder macro for viewing room mob data. Too complicated to describe.
MUDGrinder The main processing macro for the MUDGrinder area-editing tool. This macro runs as an admin macro. See the MUDGrinder guide for more information. There are too many parameters and options here to mention.
MudInfo Returns various mud information corresponding to the MacParm give. Valid MacParms include NAME, EMAILOK, MAILBOX, DOMAIN and PORT.
MUDServerPort Returns the public accessible port number the mud server is running on on.
MUDServerStatus Returns a string showing the status of the mud server (note that there's no WEB equivalent - if it wasn't running, you wouldn't be able to see it!)
MUDServerVersion Returns the name and version of the mud server.
next Denotes the end of a @for?@ block. See the @for?@ macro.
NumPlayers Returns the number of players online which can be seen (no Cloaked). The ReqParm ALL can be given to return the number of cloaked and unclocked players online. ReqParm TOTALCACHED will return the number of players who have logged in since boot. ReqParm TOTAL will return the number of players in the database. ReqParm ACCOUNTS will return the number of accounts in the database.
PlanarData
PlanarID
PlaneNext
PlayerData Requires ReqParm PLAYER be set to a valid player name. Returns information about that player depending on MacParms found. Valid MacParms include: NAME, DESCRIPTION, LASTDATETIME, EMAIL, RACE, CHARCLASS, LEVEL, LEVELSTR, CLASSLEVEL, CLASSES, MAXCARRY, ATTACK, ARMOR, DAMAGE, HOURS, PRACTICES, EXPERIENCE, EXPERIENCELEVEL, TRAINS, MONEY, DEITY, LIEGE, CLAN, CLANROLE, ALIGNMENT, ALIGNMENTSTRING, WIMP, STARTROOM, LOCATION, STARTROOMID, LOCATIONID, INVENTORY, WEIGHT, ENCUMBRANCE, GENDER, LASTDATETIMEMILLIS, HITPOINTS, MANA, MOVEMENT, RIDING, HEIGHT, LASTIP, QUESTPOINTS, ONLINE, BASEHITPOINTS, BASEMANA, BASEMOVEMENT.
PlayerDelete Requires ReqParm PLAYER be set to a valid player name, and an authenticated user (see Authenticate). Deletes the player.
PlayerID Requires ReqParm PLAYER be set to a valid player name. Returns that name.
PlayerList Returns a series of HTML <LI> elements; the enclosing list elements (<UL>..</UL> or <OL>..</OL>) are not part of this string and so must be defined in the surrounding page. Additionally, each element will have their style-sheet class set to either cmPlayerListEntry or, if applicable, cmPlayerListEntryArchon.
PlayerNext Sets the ReqParm PLAYER to the next player found. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing. Accepts MacParm SORTBY=COLNAME to sort the list.
PlayerOnline Requires ReqParm PLAYER be set to a valid player name. Returns true if online, false otherwise. If MacParm BOOT found, will kick the player off. If MacParm BANBYIP found, will ban the ip address for the player. If MacParm BANBYNAME or BANBYEMAIL os found, it will also ban the player.
PlayerPortrait
PollData
PollID
PollNext
PostalBoxInfo
PostOfficeBoxNext
PostOfficeBranchNext
PostOfficeName
PostOfficeNext
PrideStat
QuestData Requires ReqParm QUEST be set to a valid quest name. Returns data about the Quest depending on MacParms found. Valid MacParms include: NAME, DURATION, WAIT, INTERVAL, RUNNING, WAITING, REMAINING, WAITLEFT, WINNERS, SCRIPT.
QuestMaker
QuestMgr If MacParm CREATE is given, along with ReqParm SCRIPT, will create a new Quest. Other functions require ReqParm QUEST be set to a valid quest name. Performs functions on the Quest depending on MacParms found. Valid MacParms include: MODIFY (with ReqParm SCRIPT), DELETE, START, STOP.
QuestNext Sets the ReqParm QUEST to the next quest found. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
RaceCatNext
RaceClassNext Requires ReqParm RACE be set to a valid race id. Sets the ReqParm CLASS to the next class qualified for by the given race. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
RaceData Requires ReqParm RACE be set to a valid race id. Returns information about that race depending on MacParms found. Valid MacParms include: HELP, STATS, SENSES, TRAINS, PRACS, ABILITIES, HEALTHTEXTS, NATURALWEAPON, PLAYABLE, DISPOSITIONS, EXPECTANCY, STARTINGEQ, CLASSES, LANGS
RaceID Requires ReqParm RACE be set to a valid race id. Returns the id.
RaceName Requires ReqParm RACE be set to a valid race id. Returns the name.
RaceNext Sets the ReqParm RACE to the next race found. Returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" found. Accepts MacParm of RESET to restart listing.
RandomAreaTemplates
RebuildReferenceDocs
RequestParameter Inserts the value of the Request Parameter(s) specified in the macro parameters.
RequestParameterEncoded Inserts the value of the Request Parameter(s) specified in the macro parameters, formatted for a valid GET request.
RequestParametersEncoded Inserts the names and values of all Request Parameters, formatted for a valid GET request.
ResourceMgr Handles the resource cache. MacParm RESET will clear ReqParm RESOURCE. MacParm NEXT will set RESOURCE to the next resource. MacParm NEXT returns @break@ when the list has been completed, or "" if MacParm "EMPTYOK" also found. MacParm DELETE will delete resource that ReqParm RESOURCE is set to.
RoomData MUDGrinder macro for manipulating room data. Too complicated to describe.
RoomID Returns the ReqParm ROOM.
RoomName Returns the display text for the room designated by ReqParm ROOM.
RoomNext
SipletInterface
SocialData
SocialID
SocialNext
SocialTbl Returns a formatted set of table rows and columns listing all the socials.
StatRejuvCharts
StdWebMacro Base template for all other macros. Serves no useful purpose.
SystemConfig
SystemFunction Performs a shutdown if the MacParm SHUTDOWN is found. Performs a system-wide Announce command is the MacParm ANNOUNCE is found, as well as the ReqParm TEXT.
SystemInfo Returns information about the CoffeeMud system. Too many valid MacParms to mention. See the sample MUDGrinder pages which use this macro.
TellFunctionRequires ReqParms LOGIN and PASSWORD to be unencrypted login data, or AUTH to be encrypted login data.  MacParm DELETE: requires TELLMESSAGE.  MacParm POST: requires TELLWHOM, TELLMESSAGE.  Optional: TELLMESSAGEPAGE, TELLMESSAGEPAGESIZE
TellMessageNextRequires ReqParms LOGIN and PASSWORD to be unencrypted login data, or AUTH to be encrypted login data. Optional: TELLWHOM, TELLMESSAGEPAGE, TELLMESSAGEPAGESIZE. Sets ReqParm TELLMESSAGE, TELLMESSAGEFROM, TELLMESSAGETO, and TELLMESSAGENEXTPAGE. Will not break out if MacParm EMPTYOK is given.
ThinPlayerData
TimsItemTable
TriggerData
TriggerNext
Unsubscribe
WebServerName Returns just the name of the web server.
WebServerPort Returns the port number the web server is running on.
WebServerVersion Returns the name and version of the web server.
WebSock
WhiteListMgr

Customizing the error page

Simply create a file errorpage.mwhtml in the template directory of the server; at some point on the page you should use the @HTTPSTATUS@ and @HTTPSTATUSINFO@ macros. Note that the template directory is served as though it were in the specified path - images and stylesheets should therefore go in the server's base directory.

Adding new macros to CMVP

Create the new .java file in the com/planet_ink/coffee_mud/WebMacros directory; all classes in this directory are loaded as macros by default. The new class should inherit from StdWebMacro in the com.planet_ink.coffee_mud.WebMacros package.

The package of the new class should implement the interface com.planet_ink.coffee_mud.WebMacros.interfaces.WebMacro.

The name() member should return the name of your new macro (it will be capitalized and the @ symbols added by StdWebMacro) - the name doesn't have to match the class name but it is recommended to avoid confusion.

Finally, the runMacro() function returns the String data you wish to insert into the processed output; it takes as parameters a reference to the HTPRequest that is calling the macro, and a String representing the data after the first question mark? in the macro reference.

If runMacro() returns null, the string [Error] is used to replace the macro.  If runMacro() returns @break@, this will cause a @loop@-@back@ segment to terminate.

Example: this is the complete code for the @HTTPCLIENTIP@ macro (HTTPclientIP.java):

package com.planet_ink.coffee_mud.WebMacros;

import com.planet_ink.coffee_web.interfaces.*;
import com.planet_ink.coffee_mud.core.interfaces.*;
import com.planet_ink.coffee_mud.core.*;
import com.planet_ink.coffee_mud.core.collections.*;
import com.planet_ink.coffee_mud.Abilities.interfaces.*;
import com.planet_ink.coffee_mud.Areas.interfaces.*;
import com.planet_ink.coffee_mud.Behaviors.interfaces.*;
import com.planet_ink.coffee_mud.CharClasses.interfaces.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.*;
import com.planet_ink.coffee_mud.Common.interfaces.*;
import com.planet_ink.coffee_mud.Exits.interfaces.*;
import com.planet_ink.coffee_mud.Items.interfaces.*;
import com.planet_ink.coffee_mud.Locales.interfaces.*;
import com.planet_ink.coffee_mud.MOBS.interfaces.*;
import com.planet_ink.coffee_mud.Races.interfaces.*;
import java.util.*;

/*
Copyright 2000-2026 Bo Zimmerman

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
public class HTTPclientIP extends StdWebMacro
{
public String name() {return "HTTPclientIP";}

public String runMacro(HTTPRequest httpReq, String parm)
{
if(httpReq.getClientAddress()!=null)
return httpReq.getClientAddress().getHostAddress();
return "Unknown";
}
}

If your macro is intended to be for the admin server only, you can override the .isAdminMacro() member to return true.

Using Javascript in your pages

The CoffeeMud web server allows you to use the Javascript language to generate the tags and data which make up your cmvp web pages. The Javascript to do this is inserted directly into your web page at the point where you want the script-generated content to appear using the embedded macros@jscript@ and @/jscript@. The script included between those two tags will follow the rules for JavaScripting found in the Programmers Guide. The web server makes the HTTPRequest request() object available to the script, as well as the method void write(String s) for writing text into the page.

Here is our first example:

<HTML>
<BODY>
@jscript@
var x=request().getClientAddress().getHostAddress();
write('<P>Your IP Address is <B>'+x+'</B>.</P>');
@/jscript@
</BODY>
</HTML>

Notice how we used the write() method to insert our HTML into the page. We also used the request() object to fetch the client ip address. Now here is a more involved example:

<HTML>
<HEAD>
<TITLE>My JavaScript Enabled Web Page</TITLE>
</HEAD>
<BODY>
<H1>An Example of using JavaScript in a CMVP Web Page to fetch MUD Server data.</H1>

@jscript@
var lib=Packages.com.planet_ink.coffee_mud.core.CMLib;
// define a shortcut to the CoffeeMud libraries.

var randomRoom=lib.map().getRandomRoom();
var randomArea=lib.map().getRandomArea();
// finding random rooms and areas is easy

var randomMob=null;
var randomItem=null;
// assign our random mobs and items to null until they are found

var attempts=1000;
// finding random items and mobs is more difficult. We will
// select a random room, and attempt to pick out a random mob
// and/or item from the room. We will do this a maximum of 1000
// times before giving up, until we find one of each.
while(((--attempts)>0)&&((randomMob==null)||(randomItem==null)))
{
var room=lib.map().getRandomRoom();
if((randomMob==null)&&(room.numInhabitants()>0))
{
randomMob=room.fetchRandomInhabitant();
}
if((randomItem==null)&&(room.numItems()>0))
{
randomItem = room.getRandomItem();
}
} //now we have all our random things. We could easily insert our HTML using
// the write() method as we did in example 1. To be fancy, however, we'll use the
// the request() object to assign the names of our selections to HTTP Request
// strings.

request().addFakeUrlParameter("RANDOMROOM",randomRoom.displayText());
request().addFakeUrlParameter("RANDOMAREA",randomArea.name());
if(randomMob!=null)
request().addFakeUrlParameter("RANDOMMOB",randomMob.name());
if(randomItem!=null)
request().addFakeUrlParameter("RANDOMITEM",randomItem.name());
// now we exit back and continue with our HTML, using standard CMVP web macros
// to fetch the random names we saved.
@/jscript@

<FONT FACE="Courier New">
<B>A random area: <B>@RequestParameter?RANDOMAREA@<BR>
<B>A random room: <B>@RequestParameter?RANDOMROOM@<BR>
<B>A random mob : <B>@RequestParameter?RANDOMMOB@<BR>
<B>A random item: <B>@RequestParameter?RANDOMITEM@<BR>

</FONT>
<P>
</BODY>
</HTML>

Servlet interfaces

The CoffeeMud web server supports Java Servlets, which are special Java classes that can handle HTTP requests and generate their own responses for the requesters browser to process.  They must implement the SimpleServlet interface, which is part of the com.planet_ink.coffee_web.interfaces package.  The web server does not yet support the official JavaX Servlet interface.

Web Browsers gain access to servlets by configuring a particular URL path to a particular servlet class that is already defined and available in the web servers java path.  This configuration is done in the INI file for your web server, as mentioned above under configuration.  The configuration entry for servlets is as follows:

SERVLET*
=javaclass

To assign a servlet to a SimpleServlet-based class, you can map it to a top-level url context by using the word "SERVLET" followed by a slash, followed by the root url context, and then setting that equal to the java class name where your SimpleServlet can be found.  Here are some default examples:

SERVLET/stats=com.planet_ink.coffee_web.servlets.ServletStatsServlet

This example servlet provides some request counters for the various other servlets.  As mentioned above, you would access it by the url http://localhost:27744/stats , though the 'localhost' and port 27744 might be different based on how your configured your web server.

SERVLET/info=com.planet_ink.coffee_web.servlets.ServerInfoServlet

This example servlet provides some configuration information about the web server, such as found in the web server INI files.

WebMacroCreamer servlet:

This servlet is special in that its only job is to execute special web server "Web Macros" as if they were servlets instead of web macros.  (See the CoffeeMud Virtual Pages section above for more information on their normal use.)   These special web macros proclaim that they are of the 'web path' type by returning true from the method public boolean isAWebPath(), which signals to the WebMacroCreamer servlet that it can execute it.

In order for this to work, the final part of the servlet URL path must be the same as the name of the special WebMacro so declared.

Most of the remaining servlet examples, therefore, are actually WebMacros being redirected to through WebMacroCreamer servlet.

Here are examples of those webmacro-servlets:

SERVLET/images/mxp/PlayerPortrait=com.planet_ink.coffee_mud.Libraries.WebMacroCreamer

Executes the PlayerPortrait Web Macro, which returns binary image data associated with a game character, for display in various pages.  The players name is passed as a url parameter; for example:  http://localhost:27744/images/mxp/PlayerPortrait?PLAYER=Bob

SERVLET/AreaXML=com.planet_ink.coffee_mud.Libraries.WebMacroCreamer

Exports the XML representing a game Area, named by URL parameter AREA.  This also requires the AUTH url parameter, which ensures that areas can only be exported by authenticated administrators.

SERVLET/FileData=com.planet_ink.coffee_mud.Libraries.WebMacroCreamer

Exports the contents of a VFS File denoted by the url parameter PATH or FILE.  This also requires the AUTH url parameter, which ensures that files can only be read by authenticated administrators.

SERVLET/ImageVerificationImage=com.planet_ink.coffee_mud.Libraries.WebMacroCreamer

Generates a CAPTCHA-like image for human verification.  

SERVLET/pub/Unsubscribe=com.planet_ink.coffee_mud.Libraries.WebMacroCreamer
SERVLET/Unsubscribe=com.planet_ink.coffee_mud.Libraries.WebMacroCreamer

These url paths execute the Unsubscribe Web Macro, which is typically followed by an automatically generated email from the mud.  It unsubscribes the user who clicks on the link from a journal denoted by an UNSUBKEY passed into it, along with a USER parameter to confirm the appropriate account or user.

The remaining WebMacro servlets are covered below under WebSockets

SERVLET/pub/SipletInterface=com.planet_ink.coffee_mud.Libraries.WebMacroCreamer
SERVLET/SipletInterface=com.planet_ink.coffee_mud.Libraries.WebMacroCreamer
SERVLET/WebSockASCII=com.planet_ink.coffee_mud.Libraries.WebMacroCreamer
SERVLET/WebSockJSON=com.planet_ink.coffee_mud.Libraries.WebMacroCreamer
SERVLET/WebSock=com.planet_ink.coffee_mud.Libraries.WebMacroCreamer

WebSockets in CoffeeMud

WebSocket interface is a protocol that is initiated by HTTP, but which maintains persistent two-way communication between the web server and client over a single connection.  

The CoffeeMud web server supports Web Sockets via a series of special Web Macros and the specific servlet called WebMacroCreamer.   This means that each of the various flavors of WebSockets provided by CoffeeMud are actually configured in your web server INI file under the section on servlets.  Please read the previous section on Servlets, and especially WebMacroCreamer, for a bit more information on how this is configured, and how it works.

Each of the WebSock WebMacros is responsible for managing the connection between the MUD, itself, and the browser client, once the macro is executed to initiate a connection.  In effect, this means that disconnecting from the mud will also end the websock session, and vis-a-versa.  They also implement a short timer tied to the websock PING operation, which will cause the websock session to end of the browser client does not regularly and promptly respond to every ping from the server.

There are four special WebSock web macros provided for web developers to play around with, with the difference mostly being in the high-level protocol packaging, and the level of filtering or other services provided to the browser client.

WebSock

WebSock is the base, and most 'raw' of the websock interfaces to the mud.  Connecting to the /WebSock path will initiate a new telnet session with the underlying MUD.  All text and binary input sent to it by the browser is forwarded directly to the telnet port, and all new data received from the telnet port is returned to the browser client as a Binary packet.

WebSockASCII

WebSockASCII is the ascii-text version of the above WebSock, but instead of sending Binary packets back to the browser, it will send a Text packet, with all ANSI color, TELNET codes, and any other non-text data filtered out.

WebSockJSON

WebSockJSON is a more managed version of a raw interface to the MUD telnet sessions.  All input and output is a Text packet that contains a JSON document.  Every JSON packet consists of a "type" property, denoting the kind of data being sent or received, along with other properties specific to that type.  For example, the "login" packet might look like this:

{
  "type": "login",
  "name": "elrond",
  "password": "destroytheonering"
}

The types are as folllows:

"login"
This type of packet is sent from the client to the server to log a specific character into the game.  It requires two other properties: "name" for the name of the character, and "password" for the character/account password.  This packet is rejected if the websock is already logged in, or if the character given is already in the game, the character doesn't exist, or if the login information is invalid.  Normal game spam protections are also enforced.  If successful, a "connect" packet is returned by the server, otherwise an "error" is sent.

"connect"
This type of packet is sent from the server to the client to let it know that the websock session has been successfully initialized, or that the "login" packet was processed successfully.  When sent in response to a "login", the packet will contain a "username" property with the name of the character logged in.

"logout"
This packet will log the current character out of the game, without disconnecting the websock.  It will fail only if no character is currently logged in.  After executing this command, the "login" command may be sent to change to a new character.

"error"
This packet is only sent by the server in response to another packet, and delivers a failure message regarding it.  It will contain a "text" property describing the failure.

"input"
This packet is sent by the client to the server to forward to the mud as user input.  It must contain the property "data", sent as either a string, or an array of strings.

"text"
This packet is sent by the server to the client to forward output from the mud to the user.  It contains a "data" property containing the exact output from the mud, encoded as a JSON string, but often containing telnet, ansi, or other control codes.

"config"
This packet is used to read WebSockJSON configuration and filtering information, or to change it.  To read a configuration value, the client will send the packet with a "key" property of the appropriate configuration value to read.  To write a new value, the client will also include a "value" property with the new value to set the configuration entry to.  In either case, the server will respond with its own "config" packet returning the current or new "key" and "value" for the requested data.    

Valid configuration keys and values include:  
  • "asciionly" (true/false) to filter out all binary data from "text" packets
  • "gmcp" (true/false) to turn GMCP support on or off
  • "linefeeds" (true/false) to allow or filter out linefeeds in "text" packets
  • "msdp" (true/false) to turn MSDP support on or off
  • "msp" (true/false) to turn MSP support on or off
  • "mxp" (true/false) to turn MXP support on or off
  • "telnet" (true/false) to allow or filter out telnet codes from "text" packets

SipletInterface


A full web page game client web socket interface that converts all MUD output into HTML on the server side before sending it to the browser.  This client can be found on your public pages with the Play Now link, which is directed at /web/siplet/index.html.  The client supports ANSI color, Telnet codes, MSP, and MXP protocols.  Input is entered through the large text box at the bottom, and the numbered tabs along the top can be used to open or navigate through multiple sessions.  GMCP command can be sent to the mud through Siplet by entering the command into the input box prefixed with \GMCP and a space.  MSDP commands can also be sent to the mud with the \MSDP prefix.

Siplet communicates with the mud through WebSockets by using a special  URL-triggered WebMacro called SipletInterface, which is then used to send commands.  The Url to connect to SipletInterface is ws://localhost:27744/SipletInterface   where 'localhost' is your coffeemud web server domain name, and '27744' is the port of your public pages.  

SipletInterface supports the following commands from the browser:

Connect Command:
CONNECT&URL=<mud telnet host>&PORT=<mud port>
    This command establishes a connection through the SipletInterface to the target mud, which is hopefully yours.  The host and port should be the same ones used in any normal web client, and should be url-encoded if there are any special characters that might interfere with the format of the command.  

After sending this command, the next data received on the web socket will be the formatted response to this command. The response is in the following format:
<success true/false>;<token>;<siplet info string><token>;
The success argument is the string 'true' or 'false', depending on whether the connection was successful.
The token argument is a delimiter token string that must be preserved throughout the web socket session.
The siplet info string is some information about the SipletInterface, such as 'Siplet V2.3.0 (C)2005-20XX Bo Zimmerman'
The final token and semicolon are the same as above, and denote the end of the siplet info string, and the end of this response.
An example response for a successful connection might be:
true;318cae09;Siplet V2.2.0 (C)2005-2026 Bo Zimmerman318cae09;

Disconnect Command:
DISCONNECT&TOKEN=<connection token>
    This command tells the socket that the connection to the mud should be closed.  The connection can then be re-used for a new connection.   The token argument is the same delimiter token string that was received from the Connect command above.  After sending this command, the next data received on the web socket will be the formatted response to this command. The response is in the following format:
<success true/false>;
The success argument is the string 'true' or 'false', depending on whether the disconnection was successful.

Poll Command:
POLL&TOKEN=<connection token>
    This command acts like a ping command to the siplet interface, and is used to let the interface know that the web client is still there, and to check whether the connection to the underlying mud is still active.   The token argument is the same delimiter token string that was received from the Connect command above.  This command should be sent every 20 seconds or so to prevent the SipletInterface from timing out your connection.

After sending this command, the next data received on the web socket will be the formatted response to this command. The response is in the following format:
<success true/false>;<html><token>;<javascript><token>;
The success argument is the string 'true' or 'false', depending on whether the connection to the underlying mud is still active.  If false is returned, your connection is lost..
The html string is a block of html that should be added to the browser window.  
The token argument is the same delimiter token string that was received from the Connect command above..
The javascript string is a block of javascript that can be executed with the eval() command, or ignored.
An example response for a successful connection might be:
true;You have connected to the mud!318cae09;window.alert('hi')318cae09;

Send Data Command:
SENDATA&TOKEN=<connection token>&DATA=<string to send>
    This command is used to send user input and commands to the mud through the web socket. The token argument is the same delimiter token string that was received from the Connect command above, and the <string to send> is the user input.

After sending this command, the next data received on the web socket will be the formatted response to this command, which is identical to the Poll Command output above.

* Note:
After connection to a mud through the web socket, you will periodically receive spontaneous packets that are not in response to any particular command.  These are incoming data from the mud, and will be formatted exactly the same as if you had sent a Poll Command above.