@ -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_ I NF O) ;
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 = " " ;