Worked on further implementation of the network side of things.

Specifically, I added code to send a message from the client, after the client is launched. This message is used to try to connect to the server. Once the server receives this message, it responds back. After the client receives this response, the connection has been established, and the game can begin.

I also added code to wait (on the client side) for the server to press the spacebar.
master
Aadhavan Srinivasan 8 months ago
parent b47b0eab28
commit 89e1e8d45e

@ -1,14 +1,17 @@
#include <iostream>
#include <cmath>
#include <cstring>
#include <ctime>
#include "includes/raylib-cpp/raylib-cpp.hpp"
#include "includes/paddle.hpp"
#include "includes/ball.hpp"
#include "includes/easysock.hpp"
#include "includes/sign.hpp"
#include "includes/connect-helpers.hpp"
#include "includes/connect_code.hpp"
#include "includes/client.hpp"
#include "includes/server.hpp"
#include "includes/exception_consts.hpp"
/* Global variables used to instantiate structs */
const int WIDTH = 1500;
const int HEIGHT = 600;
@ -56,7 +59,7 @@ raylib::Vector2 changeVelocityAfterCollision(Paddle paddle, Ball ball) {
/* 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
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) {
@ -78,7 +81,16 @@ GameType check_server_client(int argc, char** argv) {
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);
Client* client = new Client(4, 'T', addr_port[0].data(), std::stoi(addr_port[1]));
Client* client = new Client(4, 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;
@ -116,17 +128,22 @@ GameType check_server_client(int argc, char** argv) {
std::string code = connect_code::encode(addr, std::to_string(port));
std::cout << "Your code is " << code << std::endl;
try {
Server* server = new Server(4, 'T', addr.data(), port);
type.mode = M_SERVER;
type.netsock = server;
return type;
} catch (int e) {
throw;
}
catch (std::exception& e) {
throw;
}
/* Create server socket and wait for client to connect */
Server* server = new Server(4, ES_UDP, addr.data(), port);
server->create_socket();
std::cout << "Waiting for connection..." << std::endl;
std::string response;
/* Wait for the right client to connect */
do {
response = server->recvAll();
} while (response != "GG");
std::cout << "Connection received from " << server->get_peer_addr() << std::endl;
server->sendAll("U2");
type.mode = M_SERVER;
type.netsock = server;
return type;
}
else {
@ -153,29 +170,25 @@ int main(int argc, char** argv) {
std::cout << "Invalid argument." << std::endl;
return -2;
}
if (e == EXCEPT_CONNREFUSED) {
std::cout << "Connection refused. Wrong IP address or port specified." << std::endl;
return -3;
}
if (e == EXCEPT_ADDRNOTAVAIL) {
std:: cout << "Unable to use requested address for server." << std::endl;
return -4;
}
if (e == EXCEPT_INVALIDIP) {
std::cout << "Invalid IP address provided." << std::endl;
return -5;
}
if (e == EXCEPT_WRONGRESPONSE) {
std::cout << "The server didn't respond with the correct message. Are you sure you have used the right server?" << std::endl;
return -6;
}
else {
std::cout << strerror(e) << std::endl;
return -7;
}
} catch(std::invalid_argument& inv) {
std::cout << inv.what() << std::endl;
return -6;
return -8;
}
#ifdef DEBUG
type.mode = M_CLIENT;
#endif
/* Initialize window and other variables */
SetTraceLogLevel(LOG_INFO);
SetTraceLogLevel(LOG_NONE);
raylib::Window window = raylib::Window(WIDTH, HEIGHT, "Pong");
window.ClearBackground(BLACK);
SetTargetFPS(60);
@ -184,6 +197,9 @@ int main(int argc, char** argv) {
bool game_started = false;
srand(std::time(NULL));
/* Variable to store the response given by the other player */
std::string response;
/* Instantiate Paddle and Ball objects */
Paddle pad1 = Paddle(10, (HEIGHT / 2) - (RECT_H / 2), RECT_W, RECT_H);
Paddle pad2 = Paddle(window.GetWidth() - RECT_W - 10, (HEIGHT / 2) - (RECT_H / 2), RECT_W, RECT_H);
@ -199,14 +215,26 @@ int main(int argc, char** argv) {
while (!window.ShouldClose()) {
if (!game_started) {
if (IsKeyDown(KEY_SPACE)) {
/* For the server, or if game is being played in single-player mode */
if ((type.mode == M_SERVER || type.mode == M_SINGLE) && IsKeyDown(KEY_SPACE)) {
game_started = true;
/* Send a start message to the client */
type.netsock->sendAll("S");
}
/* For client (wait for start message from server) */
if (type.mode == M_CLIENT) {
do {
response = type.netsock->recvAll();
} while (response[0] != 'S');
game_started = true;
std::cout << "Game has been started by server." << std::endl;
}
}
if (game_started) {
/* Receive response from the other machine, if the game is in multiplayer mode */
std::string response = "";
response = "";
if (type.mode != M_SINGLE) {
#ifdef DEBUG
response = "";

Loading…
Cancel
Save