This file is indexed.

/usr/share/doc/fceu/Documentation/protocol.txt is in fceu 0.98.12-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
FCE Ultra 0.91+ network play protocol.
Description v 0.0.1
--------------------------------------

In FCE Ultra, all data is sent to the server, and then the server
distributes, every emulated frame(60hz on NTSC), the collated data to the 
clients.

The server should not block when it is receiving UDP data from the clients.
If no UDP data is available, then just go on.

The clients MUST block until the input data packet comes on every emulated
frame.

Packets from the server to the client are sent out over both TCP and UDP.
Duplicate packets should be discarded.  Out-of-order packets can either
be cached, or discarded(what I recommend, as caching code gets a little
complex and wouldn't yield any benefit from what I've observed).
In the case of client->server UDP communications, the server should just use
the data from the UDP packet that has the highest packet number count, and
the server should then set its internal incoming packet counter to that
number(to prevent out-of-order packets from totally screwing up user input).

The "magic number"(used with UDP packets) is meant to reduce the chance of a hostile remote host
from disrupting the network play, without resorting to using extreme amounts
of network bandwidth.  The server generates the magic number, and it is best 
if the magic number is as random as possible.
UDP packets received with an incorrect magic number should be discarded, of
course.

Initialization, server->client:

uint32		Local UDP port(what the server is listening on).
uint32		Player number(0-3) for client.
uint32		Magic number(for UDP).


Initialization, client->server

uint32		Local UDP port(that the client is listening on).


Structure of UDP packet data:

uint32		CRC32		- Includes magic number, packet counter, and 
				  data.  For reference, CRC32 is calculated 
				  with the zlib function crc32().
uint32		Magic number
uint32		Packet counter(linear, starts at 0).
uint8[variable]	Data.

Structure of tcp packet data:

uint32		Packet counter("	").
uint8[variable]	Data.



Data format of server->client communications:

	uint8[4]	Controller data
	uint8		Command byte.  0 if no command. Otherwise(in decimal):

			1	Select FDS disk side.
			2	Insert/eject FDS disk.
			10	Toggle VS Unisystem dip switch editing.
			11 ... 18 Toggle VS Unisystem dip switches.
			19	Insert VS Unisystem coin.
			30	Reset NES.
			31	Power toggle NES.
			40	Save state(not implemented correctly).
			41	Load state(not implemented correctly).
			42 ... 50	Select save state slot(minus 42).

	Special message communications occurs if the "Packet counter" is 
	0xFFFFFFFF(only with TCP):
	
	uint32	Length of text data, minus the null character(the null
		character is sent, though).
	uint8[variable]	Text data.  Convert all characters <32 to space, and
			then display the text message(it's one line) as is.

Structure of client->server communication:

	uint8		Controller data(for this client).

	Over tcp channel, a text message can be sent.  It is one line,
	null terminated(remember the data and parse it and display it and 
	distribute it to the clients once the null byte is received).  
	Maximum size of message(including the null byte) should be 256 bytes.