The CoffeeMud Web Server:
The CoffeeMud Web Server is a simple, extensible web server that runs as part of CoffeeMud; it uses HTTP 1.0 to communicate with a web browser. In addition to being able to serve standard HTML web pages, it allows mime-types to be specified for any file extension; it also supports a simple 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. It is NOT intended to be a full-blown web server! This document assumes you have some familiarty with HTTP, mime types, and stuff like that.

How to Connect:
By default, the public web site listens on port 27744 and the administrative 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/

What it does and doesn't do:
It only supports GET, urlencoded POST and HEAD requests (I think HEAD is HTTP 1.1, but it's supported anyway).  It does not cache.

Security:
In the default CoffeeMud installation, the server named admin may be bound to 127.0.0.1 (localhost) - this means it will not accept external connections (see below).
The servers will not permit access to a directory or file outside their base directory tree (which includes mounted virtual directories, see below); attempts will generate a log message and return a HTTP 401.

Configuration:
The default installation of CoffeeMud has two inbuilt web servers, named 'pub' and 'admin'. The web servers are enabled with the line 'RUNWEBSERVERS=true' in 'coffeemud.ini'; any other value or the abscence 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. The options are:

Virtual Directories:
This is a quick-and-dirty directory mounting method; using an operating-system specific method would be preferable. Nevertheless, you can specify MOUNT/virtualdir=physicaldir in a server cfg file; for example, MOUNT/guides=guides creates a virtual directory with access to the player guides.
Now the limitation - URLs that do things like this: /guides/.. won't work; this means you can't link BACK from a virtual directory with a RELATIVE link, unless you rely on the user's browser to preprocess the URL and remove redundancies; instead, specify a path from the root ('/') - e.g., instead of ../index.cmvp specify /index.cmvp.

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.

MacroDescription
AbilityAffectNextSets 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.
AbilityDataRequires ReqParm ABILITY be set an an Ability ID.  Returns information about the ability from the Macro parms.  Valid MacParms include help, ranges, quality, target, alignment, domain, qualifyQ (if ReqParm CLASS is set to a valid character class), auto. 
AbilityDomainNextSets 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.
AbilityIDRequires ReqParm ABILITY be set an an Ability ID.  Returns that ID.
AbilityNameRequires ReqParm ABILITY be set an an Ability ID.  Returns the name of the Ability designated.
AbilityPlayerNextThis 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.
AbilityBlessingNextThis 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.
AbilityCursesNextThis 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.
AbilityRaceNextThis 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.
AbilityPowersNextThis 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.
AbilityTypeNextSets 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.
AddFileThe parameters for this macro are a list of file names.  Inserts the contents of the files  into the current document.
AddRandomFileThe 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.
AddRandomFileFromDirThe 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 ReqParmnamesandvalues. Forexample@AddRequestParameter?PARM1=VALUE&PARM2=VALUE@.  This is usually used to provide literal data for other macros which may require certain Request parameter data.
AreaDataRequires ReqParm AREA be set to a valid area name.  Returns information about that area depending on the MacParms.  Valid MacParms include: HELP, CLIMATES, TECHLEVEL, BEHAVIORS, AFFECTS, NAME, ARCHP, AUTHOR, CLASSES, SUBOPS, DESCRIPTION, SEASON, TODCODE, WEATHER, MOON, STATS
AreaNameRequires ReqParm AREA be set to a valid area name.  Returns that name.
AreaNameEncodedRequires ReqParm AREA be set to a valid area name.  Returns that name encoded for an HTTP GET request.
AreaNextSets 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.
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.
AuthenticateRequires 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.
backDenotes the looping point for a @loop@ block.  See the @loop@ macro.
BanListMgrHandles 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.
BaseCharClassNameRequires ReqParm BASECLASS be set to a valid base character class id.  Returns the name of that class.
BaseCharClassNextSets 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.
BehaviorDataRequires ReqParm BEHAVIOR be set to a valid behavior id.  Accepts MacParm HELP.
BehaviorIDRequires ReqParm BEHAVIOR be set to a valid behavior id.  Returns that ID.
breakStops 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.
ChannelBackLogNextRequires 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.
ChannelNextRequires 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.
CharClassDataRequires 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.
CharClassIDRequires ReqParm CLASS be set to a valid character class id. Returns that ID.
CharClassNameRequires ReqParm CLASS be set to a valid character class id. Returns the name of that class.
CharClassNextSets 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.
CheckReqParmEvaluates 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.
ChkReqParmBreakEvaulates 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.
ClanDataRequires ReqParm CLAN be set to a valid clan id.  Returns information about that race depending on MacParms found.  Valid MacParms include: PREMISE, RECALL, DONATION, TAX, EXP, 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)
ClanIDRequires ReqParm CLAN be set to a valid clan id.  Returns the id.
ClanNextSets 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. 
ClassRaceNextRequires 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.
CrossClassAbilitiesReturns a full HTML table of classes and abilities.
elseCreates an exception to an @if?@ macro.
endifDenotes the end of an @if?@ block.  See the @if?@ macro.
ExitDataMUDGrinder support macro for showing exit data on maps.  Too complicated to describe.
HelpTopicsHandles 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.
HTTPclientIPReturns the client's IP address.
HTTPstatusReturns the http return code; this is normally of no use ("200 OK") unless customising the error page.
HTTPstatusInfoReturns additional http status information; this is normally of no use unless customising the error page.
ifThe 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 the "?" to negate the value of the expression.  For example: @if?CheckReqParm?PARM=VALUE@  @if?!CheckReqParm?PARM=VALUE@ would return true and false (or vis-versa) depending whether the request parameter PARM was equal to VALUE.
ItemDataMUDGrinder macro for support of mob and room items.  Too complicated to describe.
JournalFunctionRequires 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.
JournalInfoRequires 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
JournalMessageNextRequires 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.
JournalNameRequires ReqParm JOURNAL be set to a valid journal name.  Returns that name.
JournalNextSets 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.
LevelNextSets 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.
LevelNumberRequires ReaParm LEVEL be set to a number between 1 and 30.  Returns that number.
LogViewerReturns the CoffeeMud log file.
loopRepeatedly 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.
MobDataMUDGrinder macro for viewing room mob data.  Too complicated to describe.
MUDGrinderThe 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.
MUDServerPortReturns the port number the mud server is running on.
MUDServerStatusReturns 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!)
MUDServerVersionReturns the name and version of the mud server.
NumPlayersReturns the number of players online which can be seen (no Cloaked)
PlayerDataRequires 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.
PlayerDeleteRequires ReqParm PLAYER be set to a valid player name, and an authenticated user (see Authenticate).  Deletes the player.
PlayerIDRequires ReqParm PLAYER be set to a valid player name.  Returns that name.
PlayerListReturns 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 surronding page. Additionally, each element will have their style-sheet class set to either cmPlayerListEntry or, if applicable, cmPlayerListEntryArchon.
PlayerNextSets 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.
PlayerOnlineRequires 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 found, will be the name of the player.
QuestDataRequires 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.
QuestMgrIf 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.
QuestNextSets 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. 
RaceClassNextRequires 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.
DeityDataRequires 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
DeityIDRequires ReqParm DEITY be set to a valid race name.  Returns the id.
DeityNextSets 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. 
RaceDataRequires 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
RaceIDRequires ReqParm RACE be set to a valid race id.  Returns the id.
RaceNameRequires ReqParm RACE be set to a valid race id.  Returns the name.
RaceNextSets 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. 
RequestParameterInserts the value of the Request Parameter(s) specified in the macro parameters.
RequestParameterEncodedInserts the value of the Request Parameter(s) specified in the macro parameters, formatted for a valid GET request.
RequestParametersEncodedInserts the names and values of all Request Parameters, formatted for a valid GET request.
ResourceMgrHandles 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.
RoomDataMUDGrinder macro for manipulating room data.  Too complicated to describe.
RoomIDReturns the ReqParm ROOM.
RoomNameReturns the display text for the room designated by ReqParm ROOM.
StdWebMacroBase template for all other macros.  Serves no useful purpose.
SocialTblReturns a formatted set of table rows and columns listing all the socials.
SystemInfoReturns information about the CoffeeMud system.  Too many valid MacParms to mention.  See the sample MUDGrinder pages which use this macro.
SystemFunctionPerforms 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.
WebServerNameReturns just the name of the web server.
WebServerPortReturns the port number the web server is running on.
WebServerVersionReturns the name and version of the web server.

Customising the error page:
Simply create a file error.cmvp (or whatever the v.p. extension is) 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/web/macros 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.web package.
The package of the new class should be com.planet_ink.coffee_mud.web.macros; the name() member should return the name of your new macro (it will be capitalised 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 a single parameter, a reference to the ProcessWebRequest that is calling the macro (you can use .getWebServer() on this parameter to get a reference to the web server, and .getWebServer().getMUD() to get a reference to the main MUD object).
If runMacro() returns null, the string [Error] is used to replace the macro; also note that macros may not return other macros in the processed text unless properly embedded as discussed above.

Example: this is the complete code for the @HTTPCLIENTIP@ macro (HTTPclientIP.java):
package com.planet_ink.coffee_mud.web.macros;
import com.planet_ink.coffee_mud.interfaces.*;
import com.planet_ink.coffee_mud.common.*;
import com.planet_ink.coffee_mud.utils.*;

public class HTTPclientIP extends StdWebMacro
{

	public String name() {return "HTTPclientIP";}

	public String runMacro(ExternalHTTPRequests httpReq, String parms)
	{
		return httpReq.getHTTPclientIP();
	}

}

The .getHTTPclientIP() member of ProcessWebRequest essentially just does this:

	return sock.getInetAddress().getHostAddress();

(don't be confused by the name .getHostAddress() - this just returns the dotted quad notation form of the address, whereas .toString() would attempt to do a reverse DNS(?) and return a meaningful name as well)

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