Btw, I intend the protocol for this to be open. At the moment what I am using has the following specs:
PEER-TO_PEER PROTOCOL SPECS
The peer-to-peer protocol is designed for connecting two Chess GUIs over
the internet directly, i.e. without using a third-party server as
intermediate. It uses a TCP/IP connection. At the lowest level one of the
GUIs would act as a server, listening on a certain port of the machine it
is started on for incoming connection request. The other side ('client')
would then send such a request to that machine and port, upon which the
connection is established, and client and server can start to exchange
(text) messages.
GUIs could use the protocol directly, but also through an adapter that to
them looks like a normal (WB) engine. For this reason the protocol is
designed to not need direct control over the GUI at the other end (as
engines would not have that). Of course when implemented directly in a GUI
some of the things that the protocol implements as requests can be obeyed
automatically.
The basic idea of the peer-to-peer protocol is that both sides maintain an
up-to-date copy of the state of the GUI at the remote end, which is
allowed to be different from the state of the local GUI. So any state
change (move, takeback, start of a new game, setting up of a position,
time control setting) is immediately relayed to the peer. Whether the peer
does anything with that information other than updating the state copy
depends on whether it is in 'playing' or 'setup' mode.
Initially (after connecting, or finishing a previous game) both sides
are in setup mode, so the users can set up a game without disturbing each
other. (E.g. select TC, variant, load an adjourned game from PGN, etc.)
When the user wants to start playing (e.g. by pressing Machine White or
Machine Black), a 'go' message is sent to the peer. Only when a 'go' has
been sent to as well as received from the peer there can be a transition
to 'playing' mode, and only when the local and remote GUI have matching
state. This can only be checked on the second 'go', and the design choice
has been made to let the GUI receiving that do the checking. So that if
the states do not match, it can immediately interpret it as a counter
proposal, present that to its user (e.g. in a popup), so that the burden
to match the remote state or reject it is now on him again. This way the
users take turns in sending 'go' commands that reject the GUI state of
their peer. Until one finally sets up the requested state before sending
the next 'go'. This 'go' will then be answered with an 'accepted', and
both the sender and receiver of that 'accepted' then know they are in
playing mode.
After that, it is just a matter of relaying moves, playing moves entered
by the remote during his turn also on our side, and vice versa. A 'result'
command makes both sides drop out of playing mode.
Detailed specification of p2p commands:
new
Sent when the user starts a new game (e.g. when a 'new' command is
received from the GUI). Unlike the corresponding command of WB protocol,
however, the receiver must assume the sender is now in force mode.
variant VARIANTNAME
Sent after 'new' when the started game is not normal Chess. Used to update
the state copy of the remote GUI.
setboard FEN
Sent after 'new' or 'variant' to update the state-copy of the remote GUI.
move MOVE
Sent whenever the GUI on the side of the sender advances one move. This
can be because the adapter received a 'usermove MOVE' command from that
GUI, or because you sent a 'move MOVE' command to that GUI. In the latter
case you would be echoing a move command received earlier from your peer.
Upon reception, you forward the command to the GUI only if it was a move
of the side the adapter is now playing (and in that case echo it back to
the peer). Otherwise (i.e. when in force mode or for a move of the wrong
side) you just use it to update your state copy of the remote GUI.
go
Sent whenever you start playing. Which is when you receive a 'go' command
from your GUI, or when you receive the first move of a game from the GUI
when you were set to play black by a 'new' command. In the latter case you
send the 'go' after relaying the move.
Upon reception, you know the remote GUI has started a game, and is now
expecting a move from you. If you were already playing (having sent a 'go'
command before) a compatible game (i.e. opposite color, same variant,
equal forced moves, if any) you should have the move ready, and the remote
adapter should already have a copy of it, and you reply with 'accepted' to
inform him the game has started, and he can play that move.
If you were not yet playing, (i.e. had not sent a 'go' yet), or the
games are not compatible (your GUI's state does not match the copy you
maintain of the remote GUI's state), you request the user to start a
compatible game (e.g. by sending a 'telluser' command to your GUI). An
already started game should be aborted (e.g. by sending a 'result' command
to the GUI), so the user can set up a compatible game.
accepted
Sent when you receive a 'go' from your peer, after already having sent one
yourself, when the games matches.
Upon reception you can release the move you had already in the state
copy of the remote GUI, if it is not in your own game yet, by sending it
to your GUI (and to your peer!). Note that you should not start playing
merely because the user on your side orders it (i.e. when you receive a
'go' from the GUI), but that you forward this 'go' to your peer (for
compatibility checking) and receive it back as 'accepted', upon which you
act.
name OPPONENTNAME
Sent to inform the peer of the name of his opponent. Upon reception it
could be used to alter the name the adapter presents to its GUI (through a
'feature myname="OPPONENTNAME"').
text MESSAGE
Sent when you want the MESSAGE displayed to the user (e.g. through a
'telluser' command to the GUI at the receiving end).
hallo MESSAGE
Sent after answering an incoming call, to confirm your presence. Upon
reception the MESSAGE would typically be displayed to the user, so he
knows he is now connected, and to whom.
level MPS TC INC
Sent whenever the user specifies a time control, so that the receiving
side can update its state copy of the remote GUI, and later use it for
checking compatibility of started games. The parameters have their usual
WB-protocol meaning, (but TC is in seconds!), with one kludge: if MPS = -
1, it specifies fixed time per move, given by TC.
time T
otim T
Commands to relay the times left on the clock (in centi-sec) on the side
of the sender to the peer. The latter could use them to synchronize (on
of) his clocks, or request a user to do so when the difference gets out of
hand.
remove
Sent when the user has performed a (2-ply) takeback, from a position where
he had the move. Upon reception we should request the user on our side to
do the same (or perhaps force it on him).
undo
Sent (twice) as confirmation of the 'remove' command from peer. Upon
reception the latter can update his state copy of the remote GUI by taking
back one ply. In addition he should now assume the remote GUI has dropped
out of playing mode, and will try to renegociate a game start by sending a
new 'go'.
quit
Sent as last command before closing a connection, so that the peer knows
the connection was terminated intentionally.