Tic Tac Toe over TCP and UDP
MPL-2.0 License
#ttt
Tic Tac Toe over TCP (+TLS) and UDP.
Make sure that you have OpenSSL installed. This is necessary for the TLS support (in Ubuntu-a-like sytems: # apt-get install openssl libssl-dev
).
If you're willing to run a server, generate a certificate and a private key:
$ ./generate-cert.sh
This command will run OpenSSL
and output the certificate and private key into /certs
.
(TODO: we should add a symmetric encryption step here so that the private key would be encrypted, increasing security)
Now, build the project (out of tree):
$ mkdir build $$ cd $_
$ cmake -Dtest=ON .. # config for building w/ tests
#will build gtest as well
$ make -j4 # build w/ 4 cores
Then run the binaries:
$ ./ttt-server & # run the server in the background
$ ./ttt-client # initialize a client
.
├── bin/ final executables
├── certs/ certificate and private key generated
├── include/ header includes (ttt_INCLUDE_DIRS)
├── lib/ dependencies (gtest)
├── src/ obj sources
└── tests/ tests
The server is responsible for centralizing all information regarding login, state of matches and players, as well as punctuation. If, for some reason, a player connection fails while the match was in its middle, and then the player who disconnected gets back and the other player stays online (not in playing
state) then the match can be resumed (for such case we must implement some kind of 'cookie-a-like' system).
It must:
(ps: a client MUST NOT be capable of being logged at two clients at the same time).
Connects to the server, registers if it hadn't done before, selects a user to play against (from the list of available users), invites the user for a match, starts the match.
It must be capable of:
Server
{
ConnectionPtr udp; // connection handler
ConnectionPtr tls; // connection handler
std::map<int, ConnectionPtr> m_connections;
std::vector<Room> rooms_list;
std::vector<User> registered_users;
}
Room
{
unsigned id;
Board board;
User userA; // X
User userB; // O
}
Board
{
char game_data[9];
}
User
{
unsigned id; // assigned on registration
char* login;
char* senha; // ps: shouldn't use plain text here
// optimally we'd use bcrypt or something
// like that
unsigned score; // (victory ==> 2 points, draw ==> 1 point)
unsigned time_connected;
Connection* current_connection; // also gives info about conn_type
BOARD_MARK current_mark; // O or X
UserStatus status; // (online|playing|offline)
}
Database
{
std::string fname;
FILE* file;
}
X
or O
was placed in the boardThe grammar is made to be extremely simple to parse. All of the content is expected to be encoded in ASCII. The following grammar is written conforming to ABNF syntax rules (see rfc 5234).
message
s are expected to be at max 512bytes long, ending with CRLF.
CRLF can be understood as a message separator.
message = cmd args crlf
cmd = (command / reply) ":"
args = *(arg ":")
command = "CMD_" 2*(ALPHA)
reply = "RPL_" 2*(ALPHA)
arg = 1*(%x01-39 / %x3B-FF) ; any octet except NULL and ":"
crlf = "%x0D %x0A" ; '\r\n'
Commands are intended to be "named requests". Some of them are not intended to generate a reply. Replies are specified in replies section.
Performs a Login if the
usr
andpwd
matches. Ifusr
doesn't exist, creates a new user, associates it with the givenpwd
and logs in. Otherwise (wrong pwd), error.
client:
CMD_IN:my_user_id:my_password:
server: (OK)
RPL_WELCOME:id:score:
server: (ERROR)
RPL_INPWD:Invalid Password:
RPL_ALOGGED:Already Logged:
The client connection wants to log into the server with a given user.
Logout
client:
CMD_OUT:
server:
RPL_BYE:You've been logged out. Closing connection:
Heartbeat
// TODO perform clock sync here?
server:
CMD_HB:
client:
RPL_HB:
Transmits the state.
// TODO synchronize clocks?
// TODO gather those replies specified above.
RPL_OK
Mozilla Public License Version 2.0