IMC Packet Documentation
Author: Xorith
Thanks goes to Samson for helping to clarify parts.
Date Created: 2-27-04
Date last modified: 3-1-04

Documentation for the IMC2 Protocol, Version 2.
Document Version: 1.0 Final (Client-handled packets ONLY)

Note: When asked, Rogel said that there should be no significiant 
differences between the MUD-Net packets and his own clients and hubs. 
Should any differences be found, please send them to hub00@kenetix.biz so 
that I may keep this document updated.

MUD-Net clients and hubs were used to generate the packet logs.

This documentation was formulated after sorting through the packet logs of both the MUD-Net client and hub.
ONLY the logs were examined in the creation of this paper. No source code was used to define any part.

----------------------------
[General Packet Information]
----------------------------

Basic packet format (for all packets except connection packets)
-------------------

<sender>@<origin> <sequence> <route> <packet-type> <target>@<destination> <data...>

Fields:
<sender>	The player/entity that sent the packet. * is a wildcard or 'global' entity.
<origin>	The MUD/Hub/Place the packet originated from.
<sequence>	A long integer sent with the packets to help validate the packet.
		The sequence is initialized by the client with current_time, and then one is added
		to it with every packet sent.
<route>		The list of MUDs and Hubs the packet has passed through. This should always
		start with the originating MUD's name, and should not have any other MUD names in it.
		All hubs that routed the packet are tacked on to the end, seperated by a !.
		Example: OrigMud!Hub1!Hub2
<packet-type>	This is a string that contains the type of packet. Example: "is-alive".
<target>	The player or entity the packet is intended for.
<destination>	The MUD the packet is intended to reach.
<data...>	A range of data based on the <packet-type>


Common origins/destinations
---------------------------
*		This is the wildcard or 'broadcast' character.
$		This is the hub-only or 'multicast' character.
IMC@$		Commonly used for ice-refresh packets. Sends to entity IMC on all hubs.
ICE@<hub>	Mostly seen in channel replies from Hubs.
*@*		This will broadcast to all MUDs and Hubs
*@$		This will multicast to all hubs.
*@<mud>		Sends to a MUD without a specific target player.
*@<hub>		Sends to a specific hub without a target entity.

Packet Types
------------

keepalive-request
is-alive
ice-refresh
ice-update
ice-msg-r
ice-msg-b
ice-msg-p
user-cache
user-cache-request
user-cache-reply
tell
emote
remote-admin
ice-cmd
who
who-reply
ping
ping-reply
whois
whois-reply
beep
ice-chan-who
ice-chan-whoreply
ice-destroy
close-notify


Notes about packet formats!
---------------------------

[Special Characters]

In most cases, data only needs to be enclosed in double quotes ' " ' when there is a space.
However, all double quotes must be escaped with the escape character ' \ '. This also means
that the ' \ ' character must also be escaped. Other characters that have to be escaped include
'\n' and '\r'.
Examples: "  would become \"
          \  would become \\
          \n would become \\n
          \r would become \\r


[Socials and Emotes]

Emotes are designated by an "emote=1" in the channel packet and refer to the message that should
be displayed right after the Player@MUD's name.
Example: 	ichat ,grins.
Would be:	Xorith@SOR-Live grins.

Socials are designated by an "emote=2" in the channel packet. The social text is to be compiled
by the MUD before the packet is sent.
Example: 	ichat @grin Someone@MUD
Would be:	Xorith@SOR-Live grins at Someone@MUD

[Ucache and Socials]

The Ucache is kept locally by the MUD and used when compiling socials. If a target of a social
isn't in the MUD's local ucache, then the MUD sends a user-cache-request packet before compiling the
social. The target MUD will then send a user-cache-reply packet containing the information.
The Ucache is intended to simply store the Name@MUD and Gender of a remote player. A MUD automatically
broadcasts a user-cache packet when a new player can access IMC, or when that player's gender changes.

[Color Codes and Translation]
The network uses standardized color codes for sending color in packets across the network. It is up
to the client to make any translation from local MUD color codes to the network color, and back again.

The current IMC2 Standard Color Codes are as follows:

Foreground:
~Z Random	~x Black	~r Dark Red
~g Dark Green	~y Orange	~b Dark Blue
~p Purple	~c Cyan		~w Grey
~D Dark Grey	~z (Same as ~D)	~R Red
~G Green	~Y Yellow	~B Blue	
~P Pink		~C Light Blue	~W White

Background:
^Z Random	^x Black	^r Dark Red
^g Dark Green	^O Orange	^B Dark Blue
^p Purple	^c Cyan		^w Grey
^z Dark Grey	^R Red		^G Green
^Y Yellow	^b Blue		^P Pink
^C Light Blue	^W White

Blinking Foreground:
`Z Random	`x Black	`r Dark Red
`g Dark Green	`O Orange	`b Dark Blue
`p Purple	`c Cyan		`w Grey
`z Dark Grey	`R Red		`G Green
`Y Yellow	`B Blue		`P Purple
`C Light Blue	`W White

Misc:
~! Reset	~L Bold		~u Underline
~$ Blink	~i Italic	~v Reverse
~s Strike-thru

For Backwards Compatability:
~m = ~p
~d = ~w
~M = ~P


[WHO Packet Information]
------------------------

(Note: This information is as observed on MUD-Net clients and Hubs)

For the 'who' type packet, the general reply is the MUD's wholist. Given that IMC uses
permission levels, the MUD might choose to use these levels to seperate the MUD list and
to denote what type of player is playing (Mort, Imm, Admin, Imp).

The 'info' type packet usually replies with the site information. This includes the SiteName,
SiteHost, Admin Email, Website, IMC Version, and IMC Details. Of course, some of this info
will vary depending on the implementation.

The 'finger' type packet replies with the information for the specified player. Information
replied in a MUD-Net client includes the channels the player is listening to and the player's
permissions.

The 'istats' type packet is generally only applicable to Hubs, though nothing in the protocol
stops a client from accepting and responding. The general data given back is  the network stats
for the Hub, and the last IMC boot.

-------------------------------------
[Connection / Authentication Packets]
-------------------------------------
Note: All connection packets are sent immediately in the order designated below.

-- Plain Text --
MUD Sends: PW <mudname> <clientpw> version=<version#> autosetup <serverpw> [md5]
HUB Sends: PW <hubname> <clientpw> version=<version#> <networkname>

-- MD5 Auth --
MUD Sends: MD5-AUTH-REQ <mudname>
HUB Sends: MD5-AUTH-INIT <hubname> <key>
MUD Sends: MD5-AUTH-RESP <mudname> <hash> version=<version#>
HUB Sends: MD5-AUTH-APPR <hubname> <networkname> version=<version#>

Fields:
<mudname>	Name of the MUD or client connecting.
<hubname>	Name of the Hub the client is connecting to.
<clientpw>	This is the client password saved in the client's configuration.
<serverpw>	This is the server password saved in the client's configuration.
<version#>	This is the protocol version number. In most cases, this will be the number 2.
<networkname>	This is the name of the network the Hub is connected to.
<key>		This is a long integer sent by the Hub. It is used in creating the <hash>
<hash>		This is the result of the <key>+<clientpw>+<serverpw>, salted by "$1$<mudname>$".

Optional Arguments:

(Plain Text)
[md5]		This is sent to notify the Hub that the MUD is MD5-Enabled. All future logins
		from this client will be expected in MD5-AUTH format if the hub supports it.

(MD5-Auth)
None.

--------------------
[Packet Definitions]
--------------------

--------------------
Packet: 	keepalive-request

Description:
   This packet is sent by a MUD to trigger is-alive packets from other MUDs.
   This packet is usually followed by the sending MUD's own is-alive packet.
   It is used in the filling of a client's MUD list, thus any MUD that doesn't respond with an is-alive
   isn't marked as online on the sending MUD's mudlist.

Data:
(none)

Older client Data:
versionid=<string>	Where <string> is the text version ID of the client. ("IMC2 4.5 MUD-Net")\
			NOTE: This is no longer sent with a keepalive-request, however older clients
			      may still send it.

Example:
*@YourMUD 1234567890 YourMUD!Hub1 keepalive-request *@*
--------------------

--------------------
Packet: 	is-alive

Description:
   This packet is the reply to a keepalive-request packet. It is responsible for filling a client's
   mudlist with the information about other MUDs on the network.

Data:
versionid=<string>	Where <string> is the text version ID of the client. ("IMC2 4.5 MUD-Net")
url=<string>		where <string> is the proper URL of the client. (http://www.domain.com)

(These data fields are not sent by the MUD, they are added by the Hub.)
networkname=<string>	Where <string> is the network name that the MUD/Hub is on. ("MyNetwork")
md5=<int>		This is an optional tag that denotes the MD5 capabilities of a MUD or Hub.

Example:
*@SomeMUD 1234567890 SomeMUD!Hub2 is-alive *@YourMUD versionid="IMC2 4.5 MUD-Net" url="http://www.domain.com"
   networkname="MyNetwork" md5=1
--------------------

--------------------
Packet: ice-refresh

Description:
   This packet is sent by the MUD to request data about the channels on the network. Hubs with channels
   reply with an ice-update packet for each channel they control. The usual target for this packet is IMC@$.

Data:
(none)

Example:
*@YourMUD 1234567890 YourMUD!Hub1 ice-refresh IMC@$
--------------------

--------------------
Packet: ice-update

Description:
   A hub returns this packet with the data of a channel when prompted with an ice-refresh request.
   According to the logs I've examined, it seems that not all data is required. For instance, I've seen
   cases where operators, invited and excluded are left out if there is no data to provide.

Data:
channel=<string>	The channel's network name in the format of HubName:ChannelName
owner=<string>		The Name@MUD of the channel's owner
operators=<string>	A space-seperated list of the Channel's operators, in the format of Person@MUD
policy=<string>		The policy is either "open" or "private" with no quotes.
invited=<string>	The space-seperated list of invited User@MUDs, only valid for a "private" channel.
excluded=<string>	The space-seperated list of banned User@MUDs, only valid for "open" channels.
level=<string>		The default level of the channel: Admin, Imp, Imm, Mort, or None
localname=<string>	The suggested local name of the channel.

Examples:

Open Policy:
ICE@Hub1 1234567890 Hub1!Hub2 ice-update *@YourMUD channel=Hub1:ichat owner=Imm@SomeMUD operators=Other@SomeMUD
   policy=open excluded="Flamer@badMUD Jerk@dirtyMUD" level=Imm localname=ichat

Private Policy:
ICE@Hub1 1234567890 Hub1!Hub2 ice-update *@YourMUD channel=Hub1:secretchat owner=Imm@SomeMUD operators=Other@SomeMUD
   policy=private invited="SpecialDude@OtherMUD CoolDude@WeirdMUD" level=Mort localname=schat


--------------------

--------------------
Packet: ice-msg-r

Description:
   The -r in this ice-msg packet means it was relayed. This, along with the ice-msg-p packet, are used with
   private policy channels. The 'r' stands for 'relay'. All incoming channel messages are from ICE@<hub>, where
   <hub> is the hub hosting the channel.

Data:
realfrom=<string>	The User@MUD the message came from.
channel=<string>	The Hub:Channel the message is intended to be displayed on.
text=<string>		The message text.
emote=<int>		An integer value designating emotes. 0 for no emote, 1 for an emote, and 2 for a social.

Examples:
ICE@Hub1 1234567890 Hub1!Hub2 ice-msg-r *@YourMUD realfrom=You@YourMUD channel=hub1:secret text="Aha! I got it!" emote=0
ICE@Hub1 1234567890 Hub1!Hub2 ice-msg-r *@YourMUD realfrom=You@YourMUD channel=hub1:secret text=Ahh emote=0 
ICE@Hub1 1234567890 Hub1!Hub2 ice-msg-r *@YourMUD realfrom=You@YourMUD channel=hub1:secret text="grins evilly." emote=1
ICE@Hub1 1234567890 Hub1!Hub2 ice-msg-r *@YourMUD realfrom=You@YourMUD channel=hub1:secret text="You@YourMUD grins evilly!" emote=2

--------------------

--------------------
Packet: ice-msg-p

Description:
   This packet is sent when a player sends a message to a private channel. This packet should never be
   seen as incoming to a client. The target of this packet should be IMC@<Hub> of the hub hosting the channel.

Data:
channel=<string>	The Hub:Channel the message is intended to be displayed on.
text=<string>		The message text.
emote=<int>		An integer value designating emotes. 0 for no emote, 1 for an emote, and 2 for a social.
echo=<int>		Tells the Hub to echo the message back to the sending MUD. This is only seen on out-going messages.

Examples:
You@YourMUD 1234567890 YourMUD ice-msg-p IMC@Hub1 channel=Hub1:secret text="Ahh! I got it!" emote=0 echo=1
You@YourMUD 1234567890 YourMUD ice-msg-p IMC@Hub1 channel=Hub1:secret text=Ahh! emote=0 echo=1
You@YourMUD 1234567890 YourMUD ice-msg-p IMC@Hub1 channel=Hub1:secret text="grins evilly." emote=1 echo=1
You@YourMUD 1234567890 YourMUD ice-msg-p IMC@Hub1 channel=Hub1:secret text="You@YourMUD grins evilly." emote=2 echo=1

--------------------

--------------------
Packet: ice-msg-b

Description:
   This is the packet used to chat on open policy channels. When sent from a MUD, it is broadcasted across the
   network. Other MUDs receive it in-tact as it was sent by the originating MUD. The Hub that hosts the channel
   sends the packet back to the originating MUD as an 'echo' by removing the "echo=1" and attaching the
   "sender=Person@MUD" data field.

Data:
channel=<string>	The Hub:Channel the message is intended to be displayed on.
text=<string>		The message text.
emote=<int>		An integer value designating emotes. 0 for no emote, 1 for an emote, and 2 for a social.
*echo=<int>		This stays on broadcasted messages. It tells the channel's hub to relay an echo back.
*sender=<string>	The hosting hub replaces "echo=1" with this when sending the echo back to the originating MUD.

Examples: (See above for emote/social examples as they are pretty much the same)

Return Echo Packet:
You-YourMUD@Hub1 1234567890 Hub1 ice-msg-b *@YourMUD text=Hi! channel=Hub1:ichat sender=You@YourMUD emote=0 

Broadcasted Packet:
You@YourMUD 1234567890 YourMUD!Hub1 ice-msg-b *@* channel=Hub1:ichat text=Hi! emote=0 echo=1

--------------------

--------------------
Packet: user-cache

Description:
   Sent by a MUD with a new IMC-able player or when a player's gender changes, this packet contains only
   the gender for data. The packet's origination should be the Player@MUD.

Data:
gender=<int>  0 is male, 1 is female, 2 is anything else such as neuter. Will be referred to as "it".

Example:
Dude@someMUD 1234567890 SomeMUD!Hub2!Hub1 user-cache *@* gender=0

--------------------

--------------------
Packet: user-cache-request

Description:
   The MUD sends this packet out when making a request for the user-cache information of the user included in
   the data part of the packet.
Data:
user=<string>		The Person@MUD whose data the MUD is seeking.

Example:
*@YourMUD 1234567890 YourMUD user-cache-request *@SomeMUD user=Dude@SomeMUD
--------------------

--------------------
Packet: user-cache-reply

Description:
   A reply to the user-cache-request packet. It contains the user and gender for the user.

Data:
user=<string>		The Person@MUD whose data the MUD requested.
gender=<int>		The gender of the Person@MUD in the 'user' field.

Example:
*@someMUD 1234567890 SomeMUD!Hub2!Hub1 user-cache-reply *@YourMUD user=Dude@SomeMUD gender=0
--------------------

--------------------
Packet: tell

Description:
   This packet is used to communicate private messages between users on MUDs across the network.

Data:
level=<int>		Permission level of the tell's sender
text=<string>		Message text
isreply=<int>		Two settings: 1 denotes a reply, 2 denotes a tell social.

Example:

Originating:
You@YourMUD 1234567890 YourMUD tell Dude@SomeMUD level=5 text="Having fun?"

Reply from Dude:
Dude@SomeMUD 1234567890 SomeMUD!Hub1 tell You@YourMUD level=3 text="Yeah, this is cool!" isreply=1
--------------------

--------------------
Packet: emote

Description:
   This packet seems to be sent by hubs when notifying the network of a new channel or the destruction
   of a channel.
   
Data:
channel=<int>		Unsure of what this means. The channel seen in both creation and destruction packets
			is 15.
level=<int>		I am assuming this is the permission level of the sender. In both creation and
			destruction messages, this is -1.
text=<string>		This is the message to be sent to the users.

Examples:
ICE@Hub1 1234567890 Hub1 emote *@* channel=15 level=-1 text="the channel called hub1:test has been destroyed by You@YourMUD."
--------------------

--------------------
Packet: remote-admin

Description:
   This packet is used in remote hub administration. Please note that MD5 Support is *required* for
   a client to use this feature. The command can vary, in fact this very packet is highly dependant
   on the Hub it's being directed to. In most cases, sending the 'list' command will have a remote-admin
   enabled Hub send you the list of commands it will accept. 

Data:
command=<string>	The command being sent to the hub for processing.
data=<string>		Data associated with the command.
hash=<string>		The MD5 hash that is verified by the Hub. It's the sequence+hubadminpass salted by the Hub name.

Example:
You@YourMUD 1234567890 YourMUD remote-admin IMC@Hub1 command=list data= hash=<hash goes here>
--------------------

--------------------
Packet: ice-cmd

Description:
   Used for remote channel administration. In most cases, one must be listed as a channel creator on the
   target hub in order to do much with this packet. Other cases include channel operators.

Data:
channel=<string>	The target hub:channel for the command.
command=<string>	The command to be processed.
data=<string>		Data associated with the command.

Example:
You@YourMUD 1234567890 YourMUD ice-cmd IMC@hub1 channel=hub1:ichat command=list data=
--------------------

--------------------
Packet: ice-destroy

Description:
   Sent by a hub to indicate the destruction of a channel it hosted. The mud should remove this channel from
   its local configuration.

Data:
channel=<string>	The hub:channel being destroyed.
--------------------

--------------------
Packet: who
Variant packet: wHo ( Sometimes encountered from older clients )

Description:
   A seemingly mutli-purpose information-requesting packet. The istats packet currently only works on Hubs,
   or at least that's the case on MUD-Net hubs. The 'finger' type takes a player name in addition to the type name.
   Example: "finger Dude". The 'who' and 'info' types take no argument. The MUD is responsible for building the
   reply text sent in the who-reply packet.

Data:
level=<int>		Requester's permission level
type=<string>		Types: who, info, "finger <name>", istats (hub only)

Example:
Dude@SomeMUD 1234567890 SomeMUD!Hub1 who *@YourMUD level=3 type=who 
--------------------

--------------------
Packet: who-reply
Variant packet: wHo-reply ( Sometimes encountered from older clients )

Description:
   The multi-purpose reply to the multi-purpose information-requesting 'who' packet. The MUD is responsible for
   building the return data, including the format of it. The mud can use the permission level sent in
   the original who packet to filter the output. The example below is the MUD-Net format.

Data:
text=<string>		The formatted reply to a 'who' packet.

Additional Notes:
   The example below is for the who list packet. The same construction would go into formatting the other
   types of who packets. Please see the section on [WHO TYPES] in the Packet Format section for more information
   on the data *usually* sent with each type.

Example:
*@YourMUD 1234567890 YourMUD who-reply Dude@SomeMUD text="\n\r                     ~R-=[ ~WPlayers on YourMUD ~R]=-\n\r             ~Y-=[ ~Wtelnet://yourmud.domain.com:1234 ~Y]=-\n\r\n\r~B--------------------------------=[ ~WPlayers ~B]=---------------------------------\n\r\n\r       ~BPlayer        ~z[---]~G Mortal the Toy\n\r\n\r~R-------------------------------=[ ~WImmortals ~R]=--------------------------------\n\r\n\r       ~YStaff         ~z[---]~G You the Immortal\n\r\n\r~Y[~W2 Players~Y] ~Y[~WHomepage: http://www.yourmud.com~Y] [~W  2 Max Since Reboot~Y]\n\r~Y[~W3 logins since last reboot on Tue Feb 24, 2004 6:55:59 PM EST~Y]" 
--------------------

--------------------
Packet: ping

Description:
   Requests the destination MUD to return its path.

Data:
(None)

Example:
*@YourMUD 1234567890 YourMUD ping *@SomeMUD
--------------------

--------------------
Packet: ping-reply

Description:
   The reply to a ping packet. The path should be the route the ping packet traveled to the destination.

Data:
path=<string>		The route of the original ping packet.

Example:
*@SomeMUD 123467890 SomeMUD!Hub1 ping-reply *@SomeMUD path=YourMUD!Hub1
--------------------

--------------------
Packet: whois

Description:
   Sends a request to the network for the location of the specified player.

Data:
level=<int>		The permission level of the person making the request.

Example:
You@YourMUD 1234567890 YourMUD whois dude@* level=5
--------------------

--------------------
Packet: whois-reply

Description:
   The reply to a whois packet. The MUD is responsible for building and formatting the text sent back to the
   requesting player, and can use the permission level sent in the original whois packet to filter or block
   the response.

Data:
text=<string>		The whois text.

Example:
*@SomeMUD 1234567890 SomeMUD!Hub1 whois-reply You@YourMUD text="~RIMC Locate: ~YDude@SomeMUD: ~cOnline.\n\r" 
--------------------

--------------------
Packet: beep

Description:
   Sends out a beep packet to the Player@MUD. The client receiving this should then send a bell-character
   to the target player to 'beep' them.

Data:
level=<int>		The permission level of the person sending the beep.

Example:
You@YourMUD 1234567890 YourMUD beep dude@somemud level=5
--------------------

--------------------
Packet: ice-chan-who

Description:
   Sends a request to the specified MUD or * to list all the users listening to the specified
   channel.

Data:
level=<int>		Sender's permission level.
channel=<string>	The hub:chan name of the channel.
lname=<string>		The localname of the channel.

Example:
You@YourMUD 1234567890 YourMUD ice-chan-who somemud level=5 channel=Hub1:ichat lname=ichat
--------------------

--------------------
Packet: ice-chan-whoreply

Description:
   This is the reply packet for an ice-chan-who. The MUD is responsible for creating and formatting
   the list sent back in the 'list' field. The permission level sent in the original ice-chan-who
   packet can be used to filter or block the response.

Data:
channel=<string>	The hub:chan of the requested channel.
list=<string>		The formatted list of local listeners for that MUD.

Example:
*@SomeMUD 1234567890 SomeMUD!Hub1 ice-chan-whoreply You@YourMUD channel=Hub1:ichat list="The following people are listening to ichat on SomeMUD:\n\r\n\rDude\n\r"
--------------------

--------------------
Packet: close-notify

Description:
   This packet alerts the network when a Hub or MUD has disconnected. The Hub hosting the Hub or MUD is responsible for
   sending this packet out across the network. Clients need only process the packet to remove the disconnected MUD from
   their MUD list (or mark it as Disconnected).

Data:
host=<string>		The MUD or Hub that has disconnected from the network.

(Older clients)
versionid=<string>	This was the IMC version tag of the Hub sending the close-notify, but it is no longer sent
                        nor was it needed.

Example:
*@Hub2 1234567890 Hub2!Hub1 close-notify *@* host=DisconnMUD
--------------------
