1. Current OpenVerse protocol. ~
 
 A protocol is a standardized language spoken by nodes on a network in order to
 communicate with each other.
 
 The OpenVerse protocol is currently divided into several parts: the control
 connection, ORT registration and login, and DCC file transfer.

 1.1. The control connection. ~

  The control connection protocol consists of newline-delimited packets, each of
  which is a command word followed by any number of space-prefixed arguments.
  An empty field is indicated by sending two contiguous spaces.  Two empty
  fields would be represented by three contiguous spaces, and so on.  See below
  for examples.
 
  To join an OpenVerse server (room), a client opens the control connection to a
  specified port on a server.  The server's name and port are previously
  arranged, through configuration, a history list, room exits, or other means.
 
  The client authenticates itself to the server, and the server then sends the
  client information about the current state of the room: room name, room image,
  list of users, list of objects.
 
  After this the server continues to give the client updates about events in the
  room, such as movement, users entering and leaving, and chat.  The client
  sends the server information about its own moves and chatting and so on, and
  the server relays this information to the other clients.

  1.1.1. Creating the control connection. ~

   The client opens the connection and immediately sends an initial command.
   The valid commands at this point are AUTH, USERS, and TRANS.

   If the server sees there are too many simultaneous connections from a single
   source address, it sends "TOOMANYCONNECTIONS" and kills the connection.

   If the server determines that there are too many users already in the room,
   it sends "ROOMFULL" to the client, and both disconnect.

   Both of the above tests are common to the AUTH, USERS, and TRANS initial
   commands, so if a user already has several chat connections, he or she may
   not be able to issue a USERS command, or an ORT server on his or her machine
   may fail to connect.  Also if the room has exactly the maximum number
   allowed users, a user count query (USERS) will fail with ROOMFULL.

   If the client sends a command other than AUTH, USERS, or TRANS, "AUTH REQD"
   is sent by the server and the connection is killed.  This can be confusing
   because shortly after the client opens the connection the server sends
   "PING", and if the client responds with "PONG" before issuing any other
   command it gets disconnected.  This may confuse AUTH, USERS, and TRANS
   response parsers.

   After all this testing, the command is processed.

  1.1.2. Joining the server. ~

   1.1.2.1. Client login. ~

    The client opens the connection and sends:
>
     AUTH nick pos-x pos-y av-name name-x name-y av-size balloon-x balloon-y
<
    {nick}       Desired nickname of the user.  Cannot contain spaces.
    {pos-x}      Desired initial X coordinate.  Rooms are 640 pixels wide.
    {pos-y}      Desired initial Y coordinate.  Rooms are 480 pixels tall.
    {av-name}    Name of the user's avatar image file.  Includes any filename
                 extension (currently just .gif).  Cannot contain spaces.
    {name-x}     X position of the center of the nametag relative to the center
                 of the avatar image.
    {name-y}     Y position of the center of the nametag relative to the center
                 of the avatar image.
    {av-size}    Size of the avatar image file in bytes.
    {balloon-x}  X position of the base of the point of the balloon relative to
                 the center of the avatar image.  See below for diagram.
    {balloon-y}  Y position of the base of the point of the balloon relative to
                 the center of the avatar image.  See below for diagram.
 
             .--------------------.       The N indicates the point by which
           .'                      `.     the speech balloon is placed.
         __|                        |
       -<  N                        |     The same point on the opposite side
         ""|                        |     is used for balloons facing the
           `.                      .'     other direction.
             `--------------------'

   1.1.2.2. Validation. ~

    The fields are tested for validity using the following rules:

     Field        Numeric-Only  Max-Length  Min-Value  Invalid  Unique ~
     {nick}                                            checked  checked
     {pos-x}        checked         3           0
     {pos-y}        checked         3           0
     {av-name}
     {name-x}       checked         4
     {name-y}       checked         4
     {av-size}      checked         6           0
     {balloon-x}    checked         4
     {balloon-y}    checked         4

    Num-Only is (erroneously) defined as containing only characters in the set
    "-0123456789".  As a consequence, the server will allow values such as
    "0-0" with unpredictable results.  The Num_Only test is the first
    performed.  If the test fails for any field, "AUTH FAILED (Non Numeric)" is
    sent to the client and the connection is closed.  The client does not
    appear to have any code to process this message; instead it assumes it will
    never happen, which is a mistake because the client will be left in an
    unpredictable state when connecting to a broken server or in case of a
    version mismatch.

    Max-Length is the maximum number of characters in the field.  The minimum
    length for all fields is zero characters, not one character as may be
    expected.  If the Max-Length test fails, "AUTH FAILED (String Lengths)" is
    sent and the connection is closed.  The client does not have code to handle
    this error message.

    Min-Value is the minimum numeric value for the field.  If the field
    numerically compares as less, "AUTH FAILED (String Lengths)" is sent and
    the connection is terminated.  The client ignores this error message.

    The Invalid test is then performed on the {nick} field [1].  If {nick} is
    an empty string, a one-character string consisting of only "*" or ".", or a
    string whose first character is "-", the server rejects it, sending
    "BADNAME" to the client and killing the connection.

    {nick} is then checked for uniqueness.  if the name {nick} already belongs
    to another user in the room, the server sends "NAMEINUSE" to the client
    over the control connection, and the connection is closed.  To the server,
    nicknames are case-sensitive, so "Joe" and "joe" can both be in the room at
    the same time.  This contrasts with some parts of the client, and is one
    difference than standard IRC policy.

    Lastly, each server object gets a chance to disconnect the client.  If a
    server object decides to disconnect, it is its responsibility to first send
    a reason code to the client.

   1.1.2.2. Room name and image. ~
   
    If the client is still connected after all these checks, the user is
    finally admitted to the room.  The server sends:
>
     ROOMNAME room-name
     ROOM img-name img-size
<
    {room-name}  Name of the room.  Can contain embedded spaces.
    {img-name}   Name of the room background image file.  Cannot contain spaces.
    {img-size}   Size of the room background image file in bytes.

    Note that the client can handle these commands at any time, therefore the
    room server can change the room name or background image without forcing
    reconnects.  The client also always recognizes the above error messages,
    with the exception of the AUTH errors, which it never recognizes.

    Upon reception of ROOM, the client checks to see if it already has a room
    image file of the given name and file size.  If not, it requests the room
    image file from the server, with {img-name} as above:
>
     DCCSENDROOM img-name
<
    File transfers are discussed in greater detail below.
    
    Notice the potential for collision between room image filenames.  This is
    especially troublesome with personal servers using the default name
    "room.gif" but with customized graphics.  Also if a server changes its room
    image yet keeps the same name, if the file size remains unchanged (which is
    quite possible since room images are nearly always 640x480, except with
    ELC's client and server) the client will never know.

   1.1.2.3. OpenVerse Rapid Transit (ORT). ~

    After describing the room name and image to the client, the server checks
    to see if it is currently hosting an ORT.  The server does not support more
    than one simultaneous ORT.  If it has an ORT stopped, it sends the client a
    user and an exit object to represent the ORT:
>
     NEW nick pos-x pos-y av-name name-x name-y av-size balloon-x balloon-y
<
    {nick}       Nickname of the ORT; shown in nametag.  Can't include spaces.
    {pos-x}      X coordinate of center of the ORT image.
    {pos-y}      Y coordinate of the center of the ORT image.
    {av-name}    Name of the avatar image file used to display the ORT.
    {name-x}     X coordinate of the nametag.  Constant "0".
    {name-y}     Y coordinate of the nametag.  Constant "60".
    {av-size}    Size of the avatar image file in bytes.
    {balloon-x}  X coordinate of the speech balloon.  Constant "66".
    {balloon-y}  Y coordinate of the speech balloon.  Constant "-44".
>
     EXIT_OBJ obj-name left top right bottom duration host port
<
    {obj-name}   Name of the exit object.  Constant "ov_tram_exit".
    {left}       Left edge of the ORT.  Calculated {pos-x} - 60.
    {top}        Top edge of the ORT.  Calculated {pos-y} - 60.
    {right}      Right edge of the ORT.  Calculated {pos-x} + 60.
    {bottom}     Bottom edge of the ORT.  Calculated {pos-y} + 60.
    {duration}   Duration value of exit.  Constant "0" (infinite).
    {host}       Name or network address of the destination server.
    {port}       Port number of the room on the destination server.

    To the client, the visible portion of the ORT is an ordinary user, capable
    of chatting, receiving files, and being queried, ignored, or whois'ed.  The
    nametag and balloon are positioned as with the AUTH command, as above.

    The functional portion of the ORT is an ordinary exit object, which the
    client has the option of honoring or ignoring.  Its duration is set to
    infinite, with the expectation that it will be explicitly deleted later.
   
    The nametag and balloon locations, unfortunately, are not configurable, and
    will look strange with ORT images not the same size as the standard train.
    Also the exit object is always a 120x120 square centered on the ORT image.
    This can be very confusing for larger or smaller ORT images.  Plus, the
    exit object name is always "ov_tram_exit", so no more than one ORT can be
    in a room at a single time.  ELC fixes this.

    In most places it's known as the ORT/OpenVerse Rapid Transit, but it's also
    known as the Ort, the OV Tram, a Transport, and in one place, "The Bus".
   
   1.1.2.4. Server objects. ~

    Every time a user joins the room, all the server object files are sourced.
    The server object files are expected to send commands to the client
    indicating their presense.

    Unfortunately, server object files are also expected to initialize
    themselves at this time, so they need to track whether or not they have
    been previously initialized.
    
    They also register hooks during this initialization, and unless the server
    object is very careful, all hooks are re-registered every time a user
    enters the room, which is a terrible memory leak and may lead to duplicated
    processing and other potential problems.  This bug exists in version 0.8-7
    but has since been fixed in ELC's code.

    Furthermore, prior to the first user entering the room, no server objects
    have been sourced and therefore cannot be initialized, so no server object
    can disconnect the first user to enter the room (see above).

   1.1.2.5. Informing other users. ~

    After the server announces the ORT and other server objects are sent to the
    new user, it then sees to sending the other users in the room informationa
    bout the newly-joined client.

    In each case below, the server sends all clients, including the one that
    just joined, notification about the user, with the following command:
>
     NEW nick pos-x pos-y av-name name-x name-y av-size balloon-x balloon-y
<
    These fields are analogous to those of AUTH (see above).

    First the server checks to see whether or not it already has the avatar
    image file the client wants to use.  If not, it pretends for a moment that
    the new user wants default.gif, and sends this to the other users in the
    room.  More specifically, it hard-codes certain fields as follows:

    {av-name}    "default.gif".
    {name-x}     "0".
    {name-y}     "20".
    {av-size}    The size, in bytes, of the default.gif file on the server.
    {balloon-x}  "24".
    {balloon-y}  "6".

    These values are repeated again below for other cases, as specified.
    
    It also begins a file transfer to get the real avatar from the client, and
    when the upload is done the server tells the other users that there was an
    avatar change.

    If the server does in fact already have an avatar image file with the asme
    name as the one requested, it next checks to see if the server's avatar
    image file size is equal to {av-size} bytes.  If they do not match, the
    procedure for not having the avatar image file is followed.
    
    If they do match, the avatar image file is checked for validity and
    acceptable dimensions.  If the file is not in GIF format or has width or
    height greater than the server-configured maximums, the above procedure is
    again followed, except that no file transfer is performed.  Instead the
    server sends to the new client:
>
     TOOBIG widthxheight
<
    Where {width} and {height} are the maximum width and height values the
    server is willing to accept.  {width} and {height} are separated by the
    letter "x".
    
    If the server already has the image file and determines that it is a GIF of
    suitable size, all the fields are broadcast just as they appeared in the
    client's initial AUTH line.

    Note that the first NEW command that a client sees upon connecting to the
    server is the one describing him or herself, unless there is an ORT in the
    room, or possibly another server object that creates a fake user (currently
    none known).  This confuses an old version of ovcon, which was developed
    prior to the ORT:  It assumed that its own user would be the first echoed
    back, but with a nickname truncated and otherwise massaged to suit the
    server, and therefore assumed that its own name was equal to that of the
    first NEW.  IF there was an ORT in the room, it took on names such as
    "ORT_Number_1", much to the user's consternation.

    This also means that the user sees his or her avatar below all other avatars
    in the room excepting the ORT, yet above any server objects except those
    created dynamically, unless the server also sends an ABOVE, which some
    versions do.  All very confusing...

   1.1.2.6. Populating the room. ~

    The final step of connecting to a room server is the server sending the new
    client a list of users in the room.

    For each authenticated user in the room besides the new user, the server
    sends a NEW to the new user:
>
     NEW nick pos-x pos-y av-name name-x name-y av-size balloon-x balloon-y
<
    The fields are as before.  If the server currently has the {av-name} avatar
    image file, it and the rest of the fields are sent as they arrived in AUTH
    or as they were changed over the course of the chat.  If the server does not
    have the {av-name} avatar image file, it instead sends the "default.gif"
    values, similarly to the above case of telling the existing users about the
    new, but duplicated here for convenience:

    {av-name}    "default.gif".
    {name-x}     "0".
    {name-y}     "20".
    {av-size}    The size, in bytes, of the default.gif file on the server.
    {balloon-x}  "24".
    {balloon-y}  "6".

  1.1.3. Getting a user count. ~

   The passageways and history facilities in the client and the room display in
   the ORT server employ the USERS command to check which room servers are
   online and how many users they each have.  After opening a connection, the
   client immediately sends "USERS", and the server responds:
>
    USERS count
<
   {count} is nominally the number of users connected to the server at that
   time.  After sending USERS, the server drops the connection.

   Unfortunately, {count} is not actually the number of users connected but
   really is the number of open sockets on the server, less one.  Therefore many
   non-users are also counted: the ORT, not-yet-authenticated users, hanging
   connections, others querying for a USERS count, etc.  As a result, the ORT
   always displays at least one user in each room, but as Cruise said this
   encourages users to explore new rooms, thinking people are already there, but
   of course this is silly---ORT users quickly learn that "1" means "0".

  1.1.4. ORT authentication. ~

   
==================

 Currently the OpenVerse control protocol is as follows:

* The client opens a TCP/IP connection to the server.

* They chat using messages formatted thusly:
    COMMAND arg1 arg2 arg3 ... argN
  Arguments are space-delimited.  Packets are newline-delimited.

File transfer ("DCC"):

* To send files from client to server, the server opens a TCP socket and tells
  the client over the control connection which port number it is via a
  DCCSENDAV message.  The client then connects to that port and immediately
  sends a hunk of data from the file.  When the server is finished getting the
  data, it takes the total number of bytes written so far, encodes it as a
  32-bit big-endian integer, and sends it to the client.  When the client gets
  the expected number, it repeats the process until there is no more data.

* To send files from server to client, the server opens a TCP socket and tells
  the client over the control connection which port number to connect to via
  DCCGET{AV,OB,ROOM}.  When the client connects, the server immediately starts
  sending file data, and things continue as above except with the direction
  reversed.

* To send files from client to client, the sender opens a TCP socket and sends
  a SUB message to the receiver (relayed through the control connection to the
  server) including the hostname and port to connect to.  When the receiver
  connects, the sender immediately starts sending data, as in the above two
  scenarios.

Advantages:

Disadvantages:

Alternate proposal:

Advantages:

Disadvantages:

	Chatting
		> CHAT
		< CHAT
		> SCHAT
		< SCHAT
		> PRIVMSG
		< PRIVMSG
		> URL
		< URL
	Movement and effects
		> MOVE
		< MOVE
		> PUSH
		< PUSH
		> EFFECT
		< EFFECT
	File transfer
		> SEND
		> DCCSENDAV
		> DCCSENDOB
		> DCCSENDROOM
		> RSEND
		< DCCGETAV
		< DCCGETOB
		< DCCGETROOM
		< DCCSENDAV
	The subchannel
	Ignore
	Server objects
	Miscellaneous
		> QUERY
		> PONG
		< PING

Protocol basics
Chat protocol
	Joining the room
		Connecting
		Login
			> AUTH
		Validation
			< AUTH FAILED (Non Numeric)
			< AUTH FAILED (String Lengths)
			< BADNAME
			< NAMEINUSE
		Room description
			< ROOMNAME
			< ROOM
			> DCCSENDROOM
		Sending ORT object
			< NEW
			< EXIT_OBJ
			> DCCSENDAV
		Sending server objects
		Informing other users
			< NEW
		Announcing other users
			< NEW
			< ABOVE
	Main chat
		Chatting
			> CHAT
			< CHAT
			> SCHAT
			< SCHAT
			> PRIVMSG
			< PRIVMSG
			> URL
			< URL
		Movement and effects
			> MOVE
			< MOVE
			> PUSH
			< PUSH
			> EFFECT
			< EFFECT
		File transfer
			> SEND
			> DCCSENDAV
			> DCCSENDOB
			> DCCSENDROOM
			> RSEND
			< DCCGETAV
			< DCCGETOB
			< DCCGETROOM
			< DCCSENDAV
		The subchannel
		Ignore
		Server objects
		Miscellaneous
			> QUERY
			> PONG
			< PING
	Leaving the room
		< NOMORE
	Reference
		Sending
			AUTH ...
		Receiving
			AUTH REQD ...
File transfer protocol
User total
ORT login
ORT registration

 vim:ft=help:et:tw=80:ts=8