From 6820c635353b25f12401f8610c140c8608051ded Mon Sep 17 00:00:00 2001 From: Mario Kilies Date: Mon, 24 Jan 2011 11:15:56 +0100 Subject: Source code refactoring. Moved net/client/server stuff to 'net' subfolder. --- src/game.c | 8 ++- src/main.c | 1 - src/net.c | 104 ---------------------------- src/net.h | 74 -------------------- src/net/client.c | 156 ++++++++++++++++++++++++++++++++++++++++++ src/net/client.h | 15 ++++ src/net/comm.c | 106 +++++++++++++++++++++++++++++ src/net/comm.h | 43 ++++++++++++ src/net/server.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/net/server.h | 25 +++++++ src/net_client.c | 156 ------------------------------------------ src/net_server.c | 203 ------------------------------------------------------- 12 files changed, 552 insertions(+), 541 deletions(-) delete mode 100644 src/net.c delete mode 100644 src/net.h create mode 100644 src/net/client.c create mode 100644 src/net/client.h create mode 100644 src/net/comm.c create mode 100644 src/net/comm.h create mode 100644 src/net/server.c create mode 100644 src/net/server.h delete mode 100644 src/net_client.c delete mode 100644 src/net_server.c (limited to 'src') diff --git a/src/game.c b/src/game.c index f4bb226..e6291a0 100644 --- a/src/game.c +++ b/src/game.c @@ -11,7 +11,9 @@ #include #include "ui.h" #include "global.h" -#include "net.h" +#include "net/comm.h" +#include "net/client.h" +#include "net/server.h" static void init_mainstack(card *stack, const uint32_t size) { @@ -35,7 +37,7 @@ static void init_mainstack(card *stack, const uint32_t size) static void main_loop_client(int sock) { bool running = true; - gamestate state = STATE_CLIENT_WAIT_CARDS; + //gamestate state = STATE_CLIENT_WAIT_CARDS; while(running) { @@ -117,7 +119,7 @@ static void main_loop_client(int sock) static void main_loop_server(socket_list_t* sock) { bool running = true; - gamestate state = STATE_SERVER_DEAL_CARDS; + //gamestate state = STATE_SERVER_DEAL_CARDS; while(running) { diff --git a/src/main.c b/src/main.c index f06cdfc..77b62ff 100644 --- a/src/main.c +++ b/src/main.c @@ -4,7 +4,6 @@ #include #include "ui.h" #include "game.h" -#include "net.h" #include "player.h" #include "hand.h" diff --git a/src/net.c b/src/net.c deleted file mode 100644 index 94dfe80..0000000 --- a/src/net.c +++ /dev/null @@ -1,104 +0,0 @@ -#include -#include -#include -#include -#include -#include "net.h" - -bool net_recv(int sock, const msg_type_t type) -{ - msg_t m; - bool result; - ssize_t len = recv(sock, &m.hdr, sizeof(msg_header_t), MSG_PEEK); // just peek into packet to determine message header - - assert(len != -1); - - if(m.hdr.type != type) - { - printf("net_recv: received message type %d instead of %d", m.hdr.type, type); - return false; - } - - m.payload = malloc(m.hdr.payload_length); // Allocate space for message payload - recv(sock, &m.hdr, sizeof(msg_header_t), 0); // Remove message header from socket - recv(sock, m.payload, m.hdr.payload_length, 0);// And then receive the payload - - switch(type) - { - case msg_type_hello: - result = server_recv_hello(m.payload, m.hdr.payload_length); - break; - case msg_type_start_game: - result = client_recv_player_list(m.payload, m.hdr.payload_length); - break; - case msg_type_deal_cards: - result = client_recv_deal_cards(m.payload, m.hdr.payload_length); - break; - case msg_type_init_stacks: - printf("not yet implemented: msg_type_init_stacks\n"); - exit(EXIT_FAILURE); - break; - case msg_type_selected_card: - result = server_recv_selected_card(m.payload, m.hdr.payload_length); - break; - case msg_type_selected_stack_c: - result = server_recv_selected_stack(m.payload, m.hdr.payload_length); - break; - case msg_type_selected_stack_s: - result = client_recv_selected_stack(m.payload, m.hdr.payload_length); - break; - default: - printf("net_recv: Unknown message type %d received!\n", type); - exit(EXIT_FAILURE); - break; - } - - free(m.payload); - - return result; -} - -bool net_send(int sock, const msg_type_t type, void* param) -{ - bool result = true; - uint8_t payload_len = 255; - uint8_t buf[payload_len+2]; // should be enough for all packet types - - buf[0] = type; - - switch(type) - { - case msg_type_hello: - payload_len = client_send_hello(&buf[2], payload_len); - break; - case msg_type_selected_card: - payload_len = client_send_selected_card(&buf[2], payload_len); - break; - case msg_type_selected_stack_c: - payload_len = client_send_selected_stack(&buf[2], payload_len); - break; - case msg_type_start_game: - payload_len = server_send_start_game(&buf[2], payload_len); - break; - case msg_type_selected_stack_s: - payload_len = server_send_selected_stack(&buf[2], payload_len); - break; - case msg_type_deal_cards: - payload_len = server_send_deal_cards(&buf[2], payload_len, param); - break; - case msg_type_initial_stack: - payload_len = server_send_initial_stacks(&buf[2], payload_len); - break; - default: - printf("net_send: Unknown message type %d received\n", type); - exit(EXIT_FAILURE); - break; - } - - buf[1] = payload_len; - - send(sock, buf, payload_len+2, 0); - - return result; -} - diff --git a/src/net.h b/src/net.h deleted file mode 100644 index 4f140dc..0000000 --- a/src/net.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef OXEN_NET_H -#define OXEN_NET_H - -#include -#include -#include "player.h" -#include "hand.h" -#include "table_stacks.h" - -// Offsets within the receive buffer to easily access the data fields of the received message -#define NET_MSG_OFFSET_TYPE 0 -#define NET_MSG_OFFSET_PAYLOAD_LENGTH 1 -#define NET_MSG_OFFSET_PAYLOAD 2 - -typedef enum -{ - // Specify message type identifiers here - msg_type_hello = 0x0, - msg_type_start_game = 0x1, - msg_type_deal_cards = 0x2, - msg_type_init_stacks = 0x3, - msg_type_selected_card = 0x4, - msg_type_selected_stack_c = 0x5, - msg_type_selected_stack_s = 0x6, - msg_type_initial_stack = 0x7 -} msg_type_t; - -// Header format -typedef struct -{ - uint8_t type; - uint8_t payload_length; -} msg_header_t; - -// Message format -typedef struct -{ - msg_header_t hdr; - uint8_t *payload; -} msg_t; - -// Socket list -typedef struct -{ - uint8_t count; - int sockets[MAX_PLAYERS]; -} socket_list_t; - - -// generic receive function -bool net_recv(int sock, msg_type_t wanted); -bool net_send(int sock, const msg_type_t type, void* param); - -// Server side functions -int server_start(const char* port); -void server_get_players(int serversock, socket_list_t* client_socks, const uint8_t count); -bool server_recv_hello(const uint8_t* payload, const uint8_t payload_len); -card* server_recv_selected_card(const uint8_t* payload, const uint8_t payload_len); -uint8_t* server_recv_selected_stack(const uint8_t* payload, const uint8_t payload_len); -uint8_t server_send_start_game(uint8_t* payload, const uint8_t payload_len); -uint8_t server_send_deal_cards(uint8_t* payload, const uint8_t payload_len, const void* param); -uint8_t server_send_selected_stack(uint8_t* payload, const uint8_t payload_len); -uint8_t server_send_initial_stacks(uint8_t* payload, const uint8_t payload_len); - -// Client side functions -int client_connect_server(const char* host, const char* port); -uint8_t client_send_hello(uint8_t* payload, const uint8_t payload_len); -uint8_t client_send_selected_card(uint8_t* payload, const uint8_t payload_len); -uint8_t client_send_selected_stack(uint8_t* payload, const uint8_t payload_len); -bool client_recv_player_list(const uint8_t* payload, const uint8_t data_len); -bool client_recv_deal_cards(const uint8_t* payload, const uint8_t payload_len); -bool client_recv_selected_stack(const uint8_t* payload, const uint8_t payload_len); - -#endif // OXEN_NET_H diff --git a/src/net/client.c b/src/net/client.c new file mode 100644 index 0000000..2606bd4 --- /dev/null +++ b/src/net/client.c @@ -0,0 +1,156 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "client.h" +#include "../global.h" +#include "../player.h" +#include "../game.h" + +/** + * Client side function; connects to specified host:port + * @param[in] host Hostname of server + * @param[in] port Port of server + * @return Socket with open connection to server + */ +int client_connect_server(const char* host, const char* port) +{ + assert(host != NULL); + assert(port != NULL); + + int status; + int sock; + struct addrinfo hints, *result, *tmp; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // IPv4 or IPv6 + hints.ai_socktype = SOCK_STREAM; // TCP socket + + status = getaddrinfo(host, port, &hints, &result); + if(status != 0) + { + printf("getaddrinfo: %s\n", gai_strerror(status)); + exit(EXIT_FAILURE); + } + + // connect to first result in linked addrinfo list + for(tmp = result; tmp != NULL; tmp = tmp->ai_next) + { + // create socket + sock = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol); + if(sock == -1) + continue; + + // connect! + if(connect(sock, tmp->ai_addr, tmp->ai_addrlen) != -1) + break; // Success! + + close(sock); + } + + if(tmp == NULL) + { + printf("failed to connect\n"); + exit(EXIT_FAILURE); + } + freeaddrinfo(result); + + return sock; +} + +bool client_recv_player_list(const uint8_t* payload, const uint8_t data_len) +{ + assert(payload != NULL); + + data_store* ds = datamodel(); + uint32_t pos = 0; + + ds->players.count = payload[pos++]; + + // read usernames from buffer + for(int i=0; iplayers.count; i++) + { + uint8_t namelen; + ds->players.players[i].player_id = payload[pos++]; + namelen = payload[pos++]; + assert(namelen <= MAX_PLAYER_NAME_LENGTH); + strncpy(ds->players.players[i].player_name, (const char*) payload+pos, namelen); + ds->players.players[i].player_name[namelen] = '\0'; + pos += namelen; + } + + return true; +} + +bool client_recv_deal_cards(const uint8_t* payload, const uint8_t payload_len) +{ + assert(payload != NULL); + assert(payload_len == MAX_HAND_CARDS); // deal_cards packet have fixed size + + data_store* ds = datamodel(); + + for(int i=0; ihand.cards[i] = payload[i]; + + return true; +} + +bool client_recv_selected_stack(const uint8_t* payload, const uint8_t payload_len) +{ + assert(payload != NULL && payload_len == 1); + + data_store* ds = datamodel(); + ds->stack_index = payload[0]; + + assert(ds->stack_index <= NUM_TABLE_STACKS); + + return true; +} + +bool client_recv_initial_stacks(const uint8_t* payload, const uint8_t payload_len) +{ + assert(payload != NULL && payload_len == NUM_TABLE_STACKS); + + data_store* ds = datamodel(); + for(int i=0; itable_stacks.stacks[i].cards[0] = payload[i]; + + return true; +} + +uint8_t client_send_hello(uint8_t* payload, const uint8_t payload_len) +{ + data_store* ds = datamodel(); + uint8_t namelen = strlen(ds->nickname); + + memcpy(payload, ds->nickname, namelen); + + return namelen; +} + +uint8_t client_send_selected_card(uint8_t* payload, const uint8_t payload_len) +{ + data_store* ds = datamodel(); + card c = ds->selected_card; + + assert(c >= MIN_CARD && c <= MAX_CARD); + + payload[0] = c; + + return 1; +} + +uint8_t client_send_selected_stack(uint8_t* payload, const uint8_t payload_len) +{ + data_store* ds = datamodel(); + + payload[0] = ds->stack_index; + assert(ds->stack_index <= NUM_TABLE_STACKS); + + return 1; +} + diff --git a/src/net/client.h b/src/net/client.h new file mode 100644 index 0000000..31b3d30 --- /dev/null +++ b/src/net/client.h @@ -0,0 +1,15 @@ +#ifndef OXEN_CLIENT_H +#define OXEN_CLIENT_H + +#include +#include + +int client_connect_server(const char* host, const char* port); +uint8_t client_send_hello(uint8_t* payload, const uint8_t payload_len); +uint8_t client_send_selected_card(uint8_t* payload, const uint8_t payload_len); +uint8_t client_send_selected_stack(uint8_t* payload, const uint8_t payload_len); +bool client_recv_player_list(const uint8_t* payload, const uint8_t data_len); +bool client_recv_deal_cards(const uint8_t* payload, const uint8_t payload_len); +bool client_recv_selected_stack(const uint8_t* payload, const uint8_t payload_len); + +#endif // OXEN_CLIENT_H diff --git a/src/net/comm.c b/src/net/comm.c new file mode 100644 index 0000000..5a283db --- /dev/null +++ b/src/net/comm.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include +#include +#include "comm.h" +#include "client.h" +#include "server.h" + +bool net_recv(int sock, const msg_type_t type) +{ + msg_t m; + bool result; + ssize_t len = recv(sock, &m.hdr, sizeof(msg_header_t), MSG_PEEK); // just peek into packet to determine message header + + assert(len != -1); + + if(m.hdr.type != type) + { + printf("net_recv: received message type %d instead of %d", m.hdr.type, type); + return false; + } + + m.payload = malloc(m.hdr.payload_length); // Allocate space for message payload + recv(sock, &m.hdr, sizeof(msg_header_t), 0); // Remove message header from socket + recv(sock, m.payload, m.hdr.payload_length, 0);// And then receive the payload + + switch(type) + { + case msg_type_hello: + result = server_recv_hello(m.payload, m.hdr.payload_length); + break; + case msg_type_start_game: + result = client_recv_player_list(m.payload, m.hdr.payload_length); + break; + case msg_type_deal_cards: + result = client_recv_deal_cards(m.payload, m.hdr.payload_length); + break; + case msg_type_init_stacks: + printf("not yet implemented: msg_type_init_stacks\n"); + exit(EXIT_FAILURE); + break; + case msg_type_selected_card: + result = server_recv_selected_card(m.payload, m.hdr.payload_length); + break; + case msg_type_selected_stack_c: + result = server_recv_selected_stack(m.payload, m.hdr.payload_length); + break; + case msg_type_selected_stack_s: + result = client_recv_selected_stack(m.payload, m.hdr.payload_length); + break; + default: + printf("net_recv: Unknown message type %d received!\n", type); + exit(EXIT_FAILURE); + break; + } + + free(m.payload); + + return result; +} + +bool net_send(int sock, const msg_type_t type, void* param) +{ + bool result = true; + uint8_t payload_len = 255; + uint8_t buf[payload_len+2]; // should be enough for all packet types + + buf[0] = type; + + switch(type) + { + case msg_type_hello: + payload_len = client_send_hello(&buf[2], payload_len); + break; + case msg_type_selected_card: + payload_len = client_send_selected_card(&buf[2], payload_len); + break; + case msg_type_selected_stack_c: + payload_len = client_send_selected_stack(&buf[2], payload_len); + break; + case msg_type_start_game: + payload_len = server_send_start_game(&buf[2], payload_len); + break; + case msg_type_selected_stack_s: + payload_len = server_send_selected_stack(&buf[2], payload_len); + break; + case msg_type_deal_cards: + payload_len = server_send_deal_cards(&buf[2], payload_len, param); + break; + case msg_type_initial_stack: + payload_len = server_send_initial_stacks(&buf[2], payload_len); + break; + default: + printf("net_send: Unknown message type %d received\n", type); + exit(EXIT_FAILURE); + break; + } + + buf[1] = payload_len; + + send(sock, buf, payload_len+2, 0); + + return result; +} + diff --git a/src/net/comm.h b/src/net/comm.h new file mode 100644 index 0000000..03816c8 --- /dev/null +++ b/src/net/comm.h @@ -0,0 +1,43 @@ +#ifndef OXEN_NET_H +#define OXEN_NET_H + +#include +#include + +// Offsets within the receive buffer to easily access the data fields of the received message +#define NET_MSG_OFFSET_TYPE 0 +#define NET_MSG_OFFSET_PAYLOAD_LENGTH 1 +#define NET_MSG_OFFSET_PAYLOAD 2 + +typedef enum +{ + // Specify message type identifiers here + msg_type_hello = 0x0, + msg_type_start_game = 0x1, + msg_type_deal_cards = 0x2, + msg_type_init_stacks = 0x3, + msg_type_selected_card = 0x4, + msg_type_selected_stack_c = 0x5, + msg_type_selected_stack_s = 0x6, + msg_type_initial_stack = 0x7 +} msg_type_t; + +// Header format +typedef struct +{ + uint8_t type; + uint8_t payload_length; +} msg_header_t; + +// Message format +typedef struct +{ + msg_header_t hdr; + uint8_t *payload; +} msg_t; + +// generic network functions +bool net_recv(int sock, msg_type_t wanted); +bool net_send(int sock, const msg_type_t type, void* param); + +#endif // OXEN_NET_H diff --git a/src/net/server.c b/src/net/server.c new file mode 100644 index 0000000..10d5d11 --- /dev/null +++ b/src/net/server.c @@ -0,0 +1,202 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "server.h" +#include "../global.h" + +/** + * Server side function; start server on specified port + * @param[in] port Port on which server should listen + * @return Listening socket + */ +int server_start(const char* port) +{ + assert(port != NULL); + + int status; + int serversock; + struct addrinfo hints, *result, *tmp; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; // IPv4 or IPv6 + hints.ai_socktype = SOCK_STREAM; // TCP socket + hints.ai_flags = AI_PASSIVE; // wildcard IP + hints.ai_protocol = 0; // any protocol + + status = getaddrinfo(NULL, port, &hints, &result); + if(status != 0) + { + printf("getaddrinfo: %s\n", gai_strerror(status)); + exit(EXIT_FAILURE); + } + + // iterate over linked addrinfo list and use first useable entry + for(tmp = result; tmp != NULL; tmp = tmp->ai_next) + { + int yes=1; + + // create socket + serversock = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol); + if(serversock == -1) + continue; + + // try to reuse still open sockets in TIME_WAIT state + setsockopt(serversock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); + + // try to bind to address/port + if(bind(serversock, tmp->ai_addr, tmp->ai_addrlen) == 0) + break; // Success! + + close(serversock); + } + + if(tmp == NULL) + { + printf("failed to bind\n"); + exit(EXIT_FAILURE); + } + freeaddrinfo(result); + + // start listening + status = listen(serversock, 1); + if(status == -1) + { + printf("listen: %s\n", strerror(status)); + exit(EXIT_FAILURE); + } + + return serversock; +} + +/** + * Server side function; accepts connections from clients + * @param[in] serversock Socket on which server is listening + * @param[out] client_socks Socket list in which to store open client connections + * @param[in] count Number of clients that should connect + */ +void server_get_players(int serversock, socket_list_t* client_socks, const uint8_t count) +{ + int i; + + assert(count < MAX_PLAYERS && count > 0); + + // accept connections + for(i=0; isockets[i] = accept(serversock, (struct sockaddr*) &addr, &addrlen); + if(client_socks->sockets[i] == -1) + { + printf("accept: %s\n", strerror(client_socks->sockets[i])); + exit(EXIT_FAILURE); + } + //printf("new client connected: %s\n", inet_ntop(sock.ss_family, get_in_addr((struct sockaddr*)&sock), INET6_ADDRSTRLEN)); + printf("new client connected (%d/%d)\n", i+1, count); + } + client_socks->count = count; +} + +/** + * Server side function; receive hello message from client and read username + * @param[in] sock Socket to use + * @return Username of client + */ +bool server_recv_hello(const uint8_t* payload, const uint8_t payload_len) +{ + assert(payload != NULL && payload_len < MAX_PLAYER_NAME_LENGTH && payload_len > 0); + + data_store* ds = datamodel(); + + for(int i=0; iplayers.count; i++) + { + if(strlen(ds->players.players[i].player_name) > 0) // search for first empty (not yet assigned) slot + continue; + memcpy(ds->players.players[i].player_name, payload, payload_len); + ds->players.players[i].player_name[payload_len] = '\0'; + } + + return true; +} + +card* server_recv_selected_card(const uint8_t* payload, const uint8_t payload_len) +{ + assert(payload != NULL && payload_len == 1); + + card* c = malloc(sizeof(card)); + assert(c != NULL); + *c = payload[0]; + + return c; +} + +uint8_t* server_recv_selected_stack(const uint8_t* payload, const uint8_t payload_len) +{ + assert(payload != NULL && payload_len == 1); + + uint8_t* index = malloc(sizeof(uint8_t)); + assert(index != NULL); + *index = payload[0]; + + return index; +} + +uint8_t server_send_start_game(uint8_t* payload, const uint8_t payload_len) +{ + uint16_t pos = 0; + data_store* ds = datamodel(); + player_list* players = &ds->players; + + payload[pos++] = players->count; + + // copy player_ids, length and nicknames to buffer + for(int i=0; icount; i++) + { + pnoc_t* pl = &players->players[i]; + payload[pos++] = pl->player_id; + uint8_t len = strlen(pl->player_name); + payload[pos++] = len; + memcpy(payload+pos, pl->player_name, len); + payload += len; + } + + assert(pos <= payload_len); + + return pos; +} + +uint8_t server_send_selected_stack(uint8_t* payload, const uint8_t payload_len) +{ + data_store* ds = datamodel(); + + payload[0] = ds->stack_index; + + return 1; +} + +uint8_t server_send_deal_cards(uint8_t* payload, const uint8_t payload_len, const void* param) +{ + const hand_t* hand = (hand_t*) param; + + for(int i=0; icards[i]; + + return MAX_HAND_CARDS; +} + + +uint8_t server_send_initial_stacks(uint8_t* payload, const uint8_t payload_len) +{ + data_store* ds = datamodel(); + + for(int i=0; itable_stacks.stacks[i].cards[0]; + + return NUM_TABLE_STACKS; +} + diff --git a/src/net/server.h b/src/net/server.h new file mode 100644 index 0000000..66bce9b --- /dev/null +++ b/src/net/server.h @@ -0,0 +1,25 @@ +#ifndef OXEN_SERVER_H +#define OXEN_SERVER_H + +#include +#include +#include "../player.h" + +// Socket list +typedef struct +{ + uint8_t count; + int sockets[MAX_PLAYERS]; +} socket_list_t; + +int server_start(const char* port); +void server_get_players(int serversock, socket_list_t* client_socks, const uint8_t count); +bool server_recv_hello(const uint8_t* payload, const uint8_t payload_len); +card* server_recv_selected_card(const uint8_t* payload, const uint8_t payload_len); +uint8_t* server_recv_selected_stack(const uint8_t* payload, const uint8_t payload_len); +uint8_t server_send_start_game(uint8_t* payload, const uint8_t payload_len); +uint8_t server_send_deal_cards(uint8_t* payload, const uint8_t payload_len, const void* param); +uint8_t server_send_selected_stack(uint8_t* payload, const uint8_t payload_len); +uint8_t server_send_initial_stacks(uint8_t* payload, const uint8_t payload_len); + +#endif // OXEN_SERVER_H diff --git a/src/net_client.c b/src/net_client.c deleted file mode 100644 index e742e7a..0000000 --- a/src/net_client.c +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include "net.h" -#include "global.h" -#include "player.h" -#include "game.h" - -/** - * Client side function; connects to specified host:port - * @param[in] host Hostname of server - * @param[in] port Port of server - * @return Socket with open connection to server - */ -int client_connect_server(const char* host, const char* port) -{ - assert(host != NULL); - assert(port != NULL); - - int status; - int sock; - struct addrinfo hints, *result, *tmp; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; // IPv4 or IPv6 - hints.ai_socktype = SOCK_STREAM; // TCP socket - - status = getaddrinfo(host, port, &hints, &result); - if(status != 0) - { - printf("getaddrinfo: %s\n", gai_strerror(status)); - exit(EXIT_FAILURE); - } - - // connect to first result in linked addrinfo list - for(tmp = result; tmp != NULL; tmp = tmp->ai_next) - { - // create socket - sock = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol); - if(sock == -1) - continue; - - // connect! - if(connect(sock, tmp->ai_addr, tmp->ai_addrlen) != -1) - break; // Success! - - close(sock); - } - - if(tmp == NULL) - { - printf("failed to connect\n"); - exit(EXIT_FAILURE); - } - freeaddrinfo(result); - - return sock; -} - -bool client_recv_player_list(const uint8_t* payload, const uint8_t data_len) -{ - assert(payload != NULL); - - data_store* ds = datamodel(); - uint32_t pos = 0; - - ds->players.count = payload[pos++]; - - // read usernames from buffer - for(int i=0; iplayers.count; i++) - { - uint8_t namelen; - ds->players.players[i].player_id = payload[pos++]; - namelen = payload[pos++]; - assert(namelen <= MAX_PLAYER_NAME_LENGTH); - strncpy(ds->players.players[i].player_name, (const char*) payload+pos, namelen); - ds->players.players[i].player_name[namelen] = '\0'; - pos += namelen; - } - - return true; -} - -bool client_recv_deal_cards(const uint8_t* payload, const uint8_t payload_len) -{ - assert(payload != NULL); - assert(payload_len == MAX_HAND_CARDS); // deal_cards packet have fixed size - - data_store* ds = datamodel(); - - for(int i=0; ihand.cards[i] = payload[i]; - - return true; -} - -bool client_recv_selected_stack(const uint8_t* payload, const uint8_t payload_len) -{ - assert(payload != NULL && payload_len == 1); - - data_store* ds = datamodel(); - ds->stack_index = payload[0]; - - assert(ds->stack_index <= NUM_TABLE_STACKS); - - return true; -} - -bool client_recv_initial_stacks(const uint8_t* payload, const uint8_t payload_len) -{ - assert(payload != NULL && payload_len == NUM_TABLE_STACKS); - - data_store* ds = datamodel(); - for(int i=0; itable_stacks.stacks[i].cards[0] = payload[i]; - - return true; -} - -uint8_t client_send_hello(uint8_t* payload, const uint8_t payload_len) -{ - data_store* ds = datamodel(); - uint8_t namelen = strlen(ds->nickname); - - memcpy(payload, ds->nickname, namelen); - - return namelen; -} - -uint8_t client_send_selected_card(uint8_t* payload, const uint8_t payload_len) -{ - data_store* ds = datamodel(); - card c = ds->selected_card; - - assert(c >= MIN_CARD && c <= MAX_CARD); - - payload[0] = c; - - return 1; -} - -uint8_t client_send_selected_stack(uint8_t* payload, const uint8_t payload_len) -{ - data_store* ds = datamodel(); - - payload[0] = ds->stack_index; - assert(ds->stack_index <= NUM_TABLE_STACKS); - - return 1; -} - diff --git a/src/net_server.c b/src/net_server.c deleted file mode 100644 index 327a695..0000000 --- a/src/net_server.c +++ /dev/null @@ -1,203 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include "net.h" -#include "player.h" -#include "global.h" - -/** - * Server side function; start server on specified port - * @param[in] port Port on which server should listen - * @return Listening socket - */ -int server_start(const char* port) -{ - assert(port != NULL); - - int status; - int serversock; - struct addrinfo hints, *result, *tmp; - - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; // IPv4 or IPv6 - hints.ai_socktype = SOCK_STREAM; // TCP socket - hints.ai_flags = AI_PASSIVE; // wildcard IP - hints.ai_protocol = 0; // any protocol - - status = getaddrinfo(NULL, port, &hints, &result); - if(status != 0) - { - printf("getaddrinfo: %s\n", gai_strerror(status)); - exit(EXIT_FAILURE); - } - - // iterate over linked addrinfo list and use first useable entry - for(tmp = result; tmp != NULL; tmp = tmp->ai_next) - { - int yes=1; - - // create socket - serversock = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol); - if(serversock == -1) - continue; - - // try to reuse still open sockets in TIME_WAIT state - setsockopt(serversock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); - - // try to bind to address/port - if(bind(serversock, tmp->ai_addr, tmp->ai_addrlen) == 0) - break; // Success! - - close(serversock); - } - - if(tmp == NULL) - { - printf("failed to bind\n"); - exit(EXIT_FAILURE); - } - freeaddrinfo(result); - - // start listening - status = listen(serversock, 1); - if(status == -1) - { - printf("listen: %s\n", strerror(status)); - exit(EXIT_FAILURE); - } - - return serversock; -} - -/** - * Server side function; accepts connections from clients - * @param[in] serversock Socket on which server is listening - * @param[out] client_socks Socket list in which to store open client connections - * @param[in] count Number of clients that should connect - */ -void server_get_players(int serversock, socket_list_t* client_socks, const uint8_t count) -{ - int i; - - assert(count < MAX_PLAYERS && count > 0); - - // accept connections - for(i=0; isockets[i] = accept(serversock, (struct sockaddr*) &addr, &addrlen); - if(client_socks->sockets[i] == -1) - { - printf("accept: %s\n", strerror(client_socks->sockets[i])); - exit(EXIT_FAILURE); - } - //printf("new client connected: %s\n", inet_ntop(sock.ss_family, get_in_addr((struct sockaddr*)&sock), INET6_ADDRSTRLEN)); - printf("new client connected (%d/%d)\n", i+1, count); - } - client_socks->count = count; -} - -/** - * Server side function; receive hello message from client and read username - * @param[in] sock Socket to use - * @return Username of client - */ -bool server_recv_hello(const uint8_t* payload, const uint8_t payload_len) -{ - assert(payload != NULL && payload_len < MAX_PLAYER_NAME_LENGTH && payload_len > 0); - - data_store* ds = datamodel(); - - for(int i=0; iplayers.count; i++) - { - if(strlen(ds->players.players[i].player_name) > 0) // search for first empty (not yet assigned) slot - continue; - memcpy(ds->players.players[i].player_name, payload, payload_len); - ds->players.players[i].player_name[payload_len] = '\0'; - } - - return true; -} - -card* server_recv_selected_card(const uint8_t* payload, const uint8_t payload_len) -{ - assert(payload != NULL && payload_len == 1); - - card* c = malloc(sizeof(card)); - assert(c != NULL); - *c = payload[0]; - - return c; -} - -uint8_t* server_recv_selected_stack(const uint8_t* payload, const uint8_t payload_len) -{ - assert(payload != NULL && payload_len == 1); - - uint8_t* index = malloc(sizeof(uint8_t)); - assert(index != NULL); - *index = payload[0]; - - return index; -} - -uint8_t server_send_start_game(uint8_t* payload, const uint8_t payload_len) -{ - uint16_t pos = 0; - data_store* ds = datamodel(); - player_list* players = &ds->players; - - payload[pos++] = players->count; - - // copy player_ids, length and nicknames to buffer - for(int i=0; icount; i++) - { - pnoc_t* pl = &players->players[i]; - payload[pos++] = pl->player_id; - uint8_t len = strlen(pl->player_name); - payload[pos++] = len; - memcpy(payload+pos, pl->player_name, len); - payload += len; - } - - assert(pos <= payload_len); - - return pos; -} - -uint8_t server_send_selected_stack(uint8_t* payload, const uint8_t payload_len) -{ - data_store* ds = datamodel(); - - payload[0] = ds->stack_index; - - return 1; -} - -uint8_t server_send_deal_cards(uint8_t* payload, const uint8_t payload_len, const void* param) -{ - const hand_t* hand = (hand_t*) param; - - for(int i=0; icards[i]; - - return MAX_HAND_CARDS; -} - - -uint8_t server_send_initial_stacks(uint8_t* payload, const uint8_t payload_len) -{ - data_store* ds = datamodel(); - - for(int i=0; itable_stacks.stacks[i].cards[0]; - - return NUM_TABLE_STACKS; -} - -- cgit v1.2.3