diff --git a/src/network/client/client.c b/src/network/client/client.c index b2384ba..184a07a 100644 --- a/src/network/client/client.c +++ b/src/network/client/client.c @@ -38,20 +38,23 @@ void cmdLeave(const consolecmdexec_t *exec) { void clientInit() { memoryZero(&CLIENT, sizeof(client_t)); - consoleRegCmd("join", cmdJoin); consoleRegCmd("leave", cmdLeave); } errorret_t clientConnect(const clientconnect_t connect) { errorret_t ret; + + // Don't connect if already connected. if(CLIENT.state != CLIENT_STATE_DISCONNECTED) { return error("Client is already connected"); } + // Init the client. CLIENT.type = connect.type; packetQueueInit(&CLIENT.packetQueue); + // Change how we connect based on the type. switch(connect.type) { case CLIENT_TYPE_NETWORKED: ret = networkedClientConnect(&CLIENT, connect.networked); @@ -61,6 +64,7 @@ errorret_t clientConnect(const clientconnect_t connect) { assertUnreachable("Invalid client type"); } + // Should be connected now. if(ret != ERROR_OK) CLIENT.state = CLIENT_STATE_DISCONNECTED; return ret; } @@ -70,24 +74,28 @@ void clientUpdate() { int32_t ret; errorret_t err; + // Don't do anything if not connected if(CLIENT.state == CLIENT_STATE_DISCONNECTED) return; - + do { + // Pop the packet off the queue. ret = packetQueuePopIn( &CLIENT.packetQueue, &packet ); + // No more packets to process, just break out. if(ret == 0) break; + // An error occured? if(ret < 0) { clientDisconnect(); consolePrint("Failed to pop packet"); return; } + // Process the packet err = packetClientProcess(&packet, &CLIENT); - if(err != ERROR_OK) { clientDisconnect(); consolePrint("Failed to process packet %s", errorString()); @@ -98,8 +106,10 @@ void clientUpdate() { } void clientDisconnect() { + // Don't disconnect if already disconnected. if(CLIENT.state == CLIENT_STATE_DISCONNECTED) return; + // Disconnect the client. switch(CLIENT.type) { case CLIENT_TYPE_NETWORKED: networkedClientDisconnect(&CLIENT); @@ -112,10 +122,6 @@ void clientDisconnect() { consolePrint("Client disconnected"); } -void clientProcess() { - if(CLIENT.state == CLIENT_STATE_DISCONNECTED) return; -} - void clientDispose() { clientDisconnect(); } \ No newline at end of file diff --git a/src/network/client/client.h b/src/network/client/client.h index fb6a269..1b78845 100644 --- a/src/network/client/client.h +++ b/src/network/client/client.h @@ -15,7 +15,7 @@ typedef enum { } clienttype_t; typedef enum { - CLIENT_STATE_DISCONNECTED, + CLIENT_STATE_DISCONNECTED = 0, CLIENT_STATE_CONNECTING, CLIENT_STATE_CONNECTED, CLIENT_STATE_DISCONNECTING, @@ -32,7 +32,6 @@ typedef struct client_s { clientstate_t state; clienttype_t type; packetqueue_t packetQueue; - union { networkedclient_t networked; }; diff --git a/src/network/client/networked/networkedclient.c b/src/network/client/networked/networkedclient.c index cf47bf3..8971555 100644 --- a/src/network/client/networked/networkedclient.c +++ b/src/network/client/networked/networkedclient.c @@ -18,10 +18,12 @@ errorret_t networkedClientConnect( errorret_t err; char_t *ip = "127.0.0.1"; + // Validate the params assertNotNull(client, "Client is NULL"); assertTrue(client->type == CLIENT_TYPE_NETWORKED, "Client is not networked"); assertIsMainThread("Client connect must be on main thread"); + // Set the state to connecting. client->state = CLIENT_STATE_CONNECTING; consolePrint("Connecting to server %s:%d", ip, connInfo.port); @@ -38,7 +40,6 @@ errorret_t networkedClientConnect( client->networked.address.sin_family = AF_INET; client->networked.address.sin_port = htons(connInfo.port); client->networked.address.sin_addr.s_addr = inet_addr(ip); - ret = inet_pton(AF_INET, ip, &client->networked.address.sin_addr); if(ret <= 0) { close(client->networked.socket); @@ -69,11 +70,9 @@ errorret_t networkedClientConnect( } } - // Initialize mutex and condition variable + // Initialize mutexes and locks and condition variable pthread_mutex_init(&client->networked.lock, NULL); pthread_cond_init(&client->networked.cond, NULL); - - // Initialize read and write locks pthread_mutex_init(&client->networked.readLock, NULL); pthread_mutex_init(&client->networked.writeLock, NULL); @@ -88,20 +87,20 @@ errorret_t networkedClientConnect( ); } - // We should now receive a welcome packet + // We should now receive a welcome packet or a disconnect packet. err = networkedClientReadPacket(client, &packet); if(err) return err; switch(packet.type) { + case PACKET_TYPE_WELCOME: + err = packetWelcomeClientProcess(&packet, client); + if(err) return err; + break; + case PACKET_TYPE_DISCONNECT: err = packetDisconnectClientProcess(&packet, client); if(err) return err; return error("Server disconnected"); - case PACKET_TYPE_WELCOME: - err = packetWelcomeClient(&packet); - if(err) return err; - break; - default: return error("Server did not send welcome message."); } @@ -113,7 +112,6 @@ errorret_t networkedClientConnect( networkedClientReadThread, client ); - if(ret != 0) { close(client->networked.socket); pthread_mutex_destroy(&client->networked.readLock); @@ -138,7 +136,6 @@ errorret_t networkedClientConnect( networkedClientWriteThread, // Renamed from networkedClientRightThread client ); - if(ret != 0) { close(client->networked.socket); pthread_mutex_destroy(&client->networked.readLock); diff --git a/src/network/packet/packet.c b/src/network/packet/packet.c index 181dd82..c9c7be3 100644 --- a/src/network/packet/packet.c +++ b/src/network/packet/packet.c @@ -13,7 +13,7 @@ packethandler_t PACKET_HANDLERS[] = { { NULL, NULL }, - { NULL, NULL }, + { packetWelcomeClientProcess, NULL }, { packetDisconnectClientProcess, NULL }, { packetPingClientProcess, packetPingServerProcess }, }; diff --git a/src/network/packet/packetdisconnect.c b/src/network/packet/packetdisconnect.c index f015634..d34ec72 100644 --- a/src/network/packet/packetdisconnect.c +++ b/src/network/packet/packetdisconnect.c @@ -31,21 +31,22 @@ errorret_t packetDisconnectClientProcess( return error("Disconnect packet length is not correct"); } + // TODO: Handle disconnect reasons better. packetdisconnect_t *data = (packetdisconnect_t *)&packet->data; - switch(data->reason) { - case PACKET_DISCONNECT_REASON_UNKNOWN: - return error("Server disconnected: Unknown reason"); - case PACKET_DISCONNECT_REASON_INVALID_VERSION: - return error("Server disconnected: Invalid version"); - case PACKET_DISCONNECT_REASON_MALFORMED_PACKET: - return error("Server disconnected: Malformed packet"); - case PACKET_DISCONNECT_REASON_SERVER_FULL: - return error("Server disconnected: Server full"); - case PACKET_DISCONNECT_REASON_SERVER_SHUTDOWN: - return error("Server disconnected: Server shutdown"); - default: - return error("Server disconnected: Unknown reason"); - } + // switch(data->reason) { + // case PACKET_DISCONNECT_REASON_UNKNOWN: + // return error("Server disconnected: Unknown reason"); + // case PACKET_DISCONNECT_REASON_INVALID_VERSION: + // return error("Server disconnected: Invalid version"); + // case PACKET_DISCONNECT_REASON_MALFORMED_PACKET: + // return error("Server disconnected: Malformed packet"); + // case PACKET_DISCONNECT_REASON_SERVER_FULL: + // return error("Server disconnected: Server full"); + // case PACKET_DISCONNECT_REASON_SERVER_SHUTDOWN: + // return error("Server disconnected: Server shutdown"); + // default: + // return error("Server disconnected: Unknown reason"); + // } return ERROR_OK; } \ No newline at end of file diff --git a/src/network/packet/packetwelcome.h b/src/network/packet/packetwelcome.h index e3b1da9..69400f8 100644 --- a/src/network/packet/packetwelcome.h +++ b/src/network/packet/packetwelcome.h @@ -26,6 +26,10 @@ void packetWelcomeCreate(packet_t *packet); * Handles a welcome packet received FROM a server INTO a client. * * @param packet Pointer to the packet structure to handle. + * @param client Pointer to the client structure. * @return ERROR_OK on success, or an error code on failure. */ -errorret_t packetWelcomeClient(packet_t *packet); \ No newline at end of file +errorret_t packetWelcomeClientProcess( + const packet_t *packet, + client_t *client +); \ No newline at end of file