|
|
@ -120,109 +120,6 @@ void check_num_args(int argc, char** argv) {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* This function checks the command-line arguments passed to the program.
|
|
|
|
|
|
|
|
It then decides whether the game is in Server or Client mode (or neither), and
|
|
|
|
|
|
|
|
instantiates the appropriate object. The (uninitialized) objects are passed to the
|
|
|
|
|
|
|
|
function as pointers. It returns a GameType struct, that indicates whether the game
|
|
|
|
|
|
|
|
is in server, client or single player mode, and contains the appropriate socket object. */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GameType check_server_client(int argc, char** argv) {
|
|
|
|
|
|
|
|
std::string connect_code;
|
|
|
|
|
|
|
|
std::vector<std::string> addr_port; /* Vector to store (IPv4) address and port */
|
|
|
|
|
|
|
|
GameType type;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (argc < 2) { /* Game was not started in client or server mode */
|
|
|
|
|
|
|
|
type.mode = M_SINGLE;
|
|
|
|
|
|
|
|
type.netsock = nullptr;
|
|
|
|
|
|
|
|
return type;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* GAME STARTED IN CLIENT MODE */
|
|
|
|
|
|
|
|
if (strcmp(argv[1],"-C") == 0) {
|
|
|
|
|
|
|
|
if (argc < 3) { /* No address was provided */
|
|
|
|
|
|
|
|
throw EXCEPT_TOOFEWARGS;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
connect_code = std::string(argv[2]); /* The connect code is a special string, that contains the server address and port. It is given by the server. */
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
addr_port = connect_code::decode(connect_code);
|
|
|
|
|
|
|
|
/* Check IP address version */
|
|
|
|
|
|
|
|
if (check_ip_ver(addr_port[0].data()) < 0) {
|
|
|
|
|
|
|
|
throw std::invalid_argument("Invalid code entered.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Client* client = new Client(ES_UDP, addr_port[0].data(), std::stoi(addr_port[1]));
|
|
|
|
|
|
|
|
client->create_socket();
|
|
|
|
|
|
|
|
/* Send a specific message to the server, and wait for the appropriate response, to know that the server is ready */
|
|
|
|
|
|
|
|
client->sendAll("GG");
|
|
|
|
|
|
|
|
std::string msg_from_server = client->recvAll();
|
|
|
|
|
|
|
|
if (msg_from_server == "U2") {
|
|
|
|
|
|
|
|
std::cout << "Connection made. Waiting for server to begin game..." << std::endl;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
throw EXCEPT_WRONGRESPONSE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
type.mode = M_CLIENT;
|
|
|
|
|
|
|
|
type.netsock = client;
|
|
|
|
|
|
|
|
return type;
|
|
|
|
|
|
|
|
} catch (int e) {
|
|
|
|
|
|
|
|
throw;
|
|
|
|
|
|
|
|
} catch (std::exception& e) {
|
|
|
|
|
|
|
|
throw;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* GAME STARTED IN SERVER MODE */
|
|
|
|
|
|
|
|
else if (strcmp(argv[1],"-S") == 0) {
|
|
|
|
|
|
|
|
std::string addr;
|
|
|
|
|
|
|
|
uint16_t port;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* No IP address or port specified */
|
|
|
|
|
|
|
|
if (argc < 3) {
|
|
|
|
|
|
|
|
throw EXCEPT_TOOFEWARGS;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* IP address but no port */
|
|
|
|
|
|
|
|
else if (argc < 4) {
|
|
|
|
|
|
|
|
std::cout << "No port specified, using 6500..." << std::endl;
|
|
|
|
|
|
|
|
addr = std::string(argv[2]);
|
|
|
|
|
|
|
|
port = 6500;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
addr = std::string(argv[2]);
|
|
|
|
|
|
|
|
port = std::stoi(std::string(argv[3]));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Check if IP is valid */
|
|
|
|
|
|
|
|
if (check_ip_ver(addr.data()) < 0) {
|
|
|
|
|
|
|
|
throw EXCEPT_INVALIDIP;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string code = connect_code::encode(addr, std::to_string(port));
|
|
|
|
|
|
|
|
std::cout << "Your code is " << code << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Create server socket and wait for client to connect */
|
|
|
|
|
|
|
|
Server* server = new Server(ES_UDP, addr.data(), port);
|
|
|
|
|
|
|
|
server->create_socket();
|
|
|
|
|
|
|
|
std::cout << "Waiting for connection..." << std::endl;
|
|
|
|
|
|
|
|
std::string response = "";
|
|
|
|
|
|
|
|
char* temp_response = NULL;
|
|
|
|
|
|
|
|
/* Wait for the right client to connect. Since recvAll returns a char*, we need to create a temporary variable to check for NULL.
|
|
|
|
|
|
|
|
TODO - Check that the client actually sends 'GG'. */
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
|
|
|
temp_response = server->recvAll();
|
|
|
|
|
|
|
|
} while (temp_response == NULL);
|
|
|
|
|
|
|
|
response = std::string(temp_response);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::cout << "Connection received from " << server->get_peer_addr() << std::endl;
|
|
|
|
|
|
|
|
server->sendAll("U2");
|
|
|
|
|
|
|
|
type.mode = M_SERVER;
|
|
|
|
|
|
|
|
type.netsock = server;
|
|
|
|
|
|
|
|
return type;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
throw EXCEPT_INVALIDARGS;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char** argv) {
|
|
|
|
int main(int argc, char** argv) {
|
|
|
|
/* Check the number and validity of command-line arguments. Invalid arguments
|
|
|
|
/* Check the number and validity of command-line arguments. Invalid arguments
|
|
|
|
will throw an exception. */
|
|
|
|
will throw an exception. */
|
|
|
@ -244,31 +141,22 @@ int main(int argc, char** argv) {
|
|
|
|
|
|
|
|
|
|
|
|
/* Check if game was started in server or client mode, and call the appropriate function to process the arguments.
|
|
|
|
/* Check if game was started in server or client mode, and call the appropriate function to process the arguments.
|
|
|
|
If game was started in single-player mode (i.e. with no arguments), then the user is prompted in the GUI. */
|
|
|
|
If game was started in single-player mode (i.e. with no arguments), then the user is prompted in the GUI. */
|
|
|
|
try { // I put this try-catch block outside the if-statement because the exception handling is the same for both client and server.
|
|
|
|
try { // I put this try-catch block outside the if-statement because the exception handling is the same for both client and server.
|
|
|
|
if (argc > 1) { // Server or client mode
|
|
|
|
if (argc > 1) { // Server or client mode
|
|
|
|
if (std::string(argv[1]) == "-S") { // Server mode
|
|
|
|
if (std::string(argv[1]) == "-S") { // Server mode
|
|
|
|
type = check_server(argv[2], argv[3], IF_CLI);
|
|
|
|
type = check_server(argv[2], argv[3], IF_CLI);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (std::string(argv[1]) == "-C") { // Client mode
|
|
|
|
if (std::string(argv[1]) == "-C") { // Client mode
|
|
|
|
type = check_client(argv[2], IF_CLI);
|
|
|
|
type = check_client(argv[2], IF_CLI);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (std::invalid_argument& inv) {
|
|
|
|
|
|
|
|
std::cout << inv.what() << std::endl;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
} catch (int err) {
|
|
|
|
|
|
|
|
std::cout << strerror(err) << std::endl;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (std::invalid_argument& inv) {
|
|
|
|
//try {
|
|
|
|
std::cout << inv.what() << std::endl;
|
|
|
|
//type = check_server_client(argc, argv);
|
|
|
|
return -1;
|
|
|
|
//} catch(int e) {
|
|
|
|
} catch (int err) {
|
|
|
|
|
|
|
|
std::cout << strerror(err) << std::endl;
|
|
|
|
//else {
|
|
|
|
return -1;
|
|
|
|
//std::cout << strerror(e) << std::endl;
|
|
|
|
}
|
|
|
|
//return -7;
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialize window and other variables */
|
|
|
|
/* Initialize window and other variables */
|
|
|
|
SetTraceLogLevel(LOG_NONE);
|
|
|
|
SetTraceLogLevel(LOG_NONE);
|
|
|
|