summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReiner Herrmann <reiner@reiner-h.de>2011-01-23 22:46:29 +0100
committerReiner Herrmann <reiner@reiner-h.de>2011-01-23 22:46:29 +0100
commit2bd0e560986c66406bae90ff44f2dd6d3fec17be (patch)
tree29aa4b7cb1831d7781a1a75f1db8ee2850a2a7ac
parentfff390715fff73f05639d3e5f96612a5a4fa82e8 (diff)
added generic net_send function and adapted functions it is using
-rw-r--r--src/game.c32
-rw-r--r--src/global.h3
-rw-r--r--src/main.c5
-rw-r--r--src/net.c51
-rw-r--r--src/net.h36
-rw-r--r--src/net_client.c141
-rw-r--r--src/net_server.c146
7 files changed, 209 insertions, 205 deletions
diff --git a/src/game.c b/src/game.c
index 0da39e4..f868cac 100644
--- a/src/game.c
+++ b/src/game.c
@@ -3,6 +3,7 @@
#include "hand.h"
#include <stdlib.h>
#include <stdbool.h>
+#include <string.h>
#include <time.h>
#include <unistd.h>
#include <assert.h>
@@ -31,7 +32,7 @@ static void init_mainstack(card *stack, const uint32_t size)
}
}
-static void main_loop_client()
+static void main_loop_client(int sock)
{
bool running = true;
gamestate state = STATE_CLIENT_WAIT_CARDS;
@@ -113,7 +114,7 @@ static void main_loop_client()
}
-static void main_loop_server()
+static void main_loop_server(socket_list_t* sock)
{
bool running = true;
gamestate state = STATE_SERVER_DEAL_CARDS;
@@ -242,13 +243,25 @@ void start_game(const bool servermode, const char* addr, const char* port)
if(server_process) // Start server and connect to localhost
{
- int ssock;
+ int server_sock;
+ socket_list_t client_socks;
uint8_t num_opponents = 1;
- ssock = server_start(port);
- server_get_players(ssock, num_opponents);
+ server_sock = server_start(port);
+ server_get_players(server_sock, &client_socks, num_opponents);
- main_loop_server();
+ for(int i=0; i<num_opponents; i++)
+ {
+ net_recv(client_socks.sockets[i], msg_type_hello);
+ printf("Player connected: %s\n", data->players.players[i].player_name);
+ }
+
+ for(int i=0; i<num_opponents; i++)
+ {
+ net_send(client_socks.sockets[i], msg_type_start_game, NULL);
+ }
+
+ main_loop_server(&client_socks);
}
else // Connect to server
{
@@ -256,7 +269,10 @@ void start_game(const bool servermode, const char* addr, const char* port)
sleep(1); // TODO make sure server process is listening
sock = client_connect_server(addr, port);
- client_hello(sock, "nickname1");
+
+ strncpy(data->nickname, "nickname", 10);
+ //client_hello(sock, "nickname1");
+ //net_send()
net_recv(sock, msg_type_start_game);
net_recv(sock, msg_type_deal_cards);
net_recv(sock, msg_type_init_stacks);
@@ -269,7 +285,7 @@ void start_game(const bool servermode, const char* addr, const char* port)
ui_display_wnd_current_state(pnoc, num_players, 2, score);
ui_display_wnd_hand_cards(&data->hand, false, 0);
- main_loop_client();
+ main_loop_client(sock);
ui_fini();
}
diff --git a/src/global.h b/src/global.h
index c8ad6d3..7385a0a 100644
--- a/src/global.h
+++ b/src/global.h
@@ -7,9 +7,12 @@
typedef struct
{
+ char nickname[MAX_PLAYER_NAME_LENGTH+1];
player_list players;
table_stacks_t table_stacks;
hand_t hand;
+ uint8_t stack_index;
+ card selected_card;
} data_store;
typedef enum
diff --git a/src/main.c b/src/main.c
index bde5bf1..f06cdfc 100644
--- a/src/main.c
+++ b/src/main.c
@@ -14,8 +14,6 @@ int main(int argc, char **argv)
char* addr = NULL;
bool servermode = false;
- int opponents = 1;
-
if (argc < 2)
{
printf("usage: '%s address port' for client mode, or '%s port' for server mode\n", argv[0], argv[0]);
@@ -25,12 +23,13 @@ int main(int argc, char **argv)
{
addr = "localhost";
port = argv[1];
+ servermode = true;
}
else if(argc == 3)
{
addr = argv[1];
port = argv[2];
-
+ servermode = false;
}
start_game(servermode, addr, port);
diff --git a/src/net.c b/src/net.c
index f3945a0..f1b7e43 100644
--- a/src/net.c
+++ b/src/net.c
@@ -5,10 +5,10 @@
#include <assert.h>
#include "net.h"
-void *net_recv(int sock, msg_type_t type)
+bool net_recv(int sock, const msg_type_t type)
{
msg_t m;
- void *result;
+ 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);
@@ -16,7 +16,7 @@ void *net_recv(int sock, msg_type_t type)
if(m.hdr.type != type)
{
printf("net_recv: received message type %d instead of %d", m.hdr.type, type);
- return NULL;
+ return false;
}
m.payload = malloc(m.hdr.payload_length); // Allocate space for message payload
@@ -57,3 +57,48 @@ void *net_recv(int sock, msg_type_t type)
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_stack(&buf[2], payload_len, param);
+ 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
index 52bb855..0caaa21 100644
--- a/src/net.h
+++ b/src/net.h
@@ -2,6 +2,7 @@
#define OXEN_NET_H
#include <stdint.h>
+#include <stdbool.h>
#include "player.h"
#include "hand.h"
#include "table_stacks.h"
@@ -20,7 +21,8 @@ typedef enum
msg_type_init_stacks = 0x3,
msg_type_selected_card = 0x4,
msg_type_selected_stack_c = 0x5,
- msg_type_selected_stack_s = 0x6
+ msg_type_selected_stack_s = 0x6,
+ msg_type_initial_stack = 0x7
} msg_type_t;
// Header format
@@ -37,26 +39,36 @@ typedef struct
uint8_t *payload;
} msg_t;
+// Socket list
+typedef struct
+{
+ uint8_t count;
+ int sockets[MAX_PLAYERS];
+} socket_list_t;
+
+
// generic receive function
-void* net_recv(int sock, msg_type_t wanted);
+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);
-int* server_get_players(int serversock, const uint8_t count);
-void server_start_game(int* clients, const uint8_t clientcount, const player_list* players);
-void server_deal_cards(int sock, const hand_t *h);
+void server_get_players(int serversock, socket_list_t* client_socks, const uint8_t count);
char* 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);
-void server_send_selected_stack(int* clients, const uint8_t clientcount, const uint8_t stackindex);
+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);
-void client_hello(int sock, const char* username);
-void client_selected_card(int sock, const card c);
-void client_send_selected_stack(int sock, const uint8_t stackindex);
-void* client_recv_player_list(const uint8_t* payload, const uint8_t data_len);
-hand_t *client_recv_deal_cards(const uint8_t* payload, const uint8_t payload_len);
-uint8_t* client_recv_selected_stack(const uint8_t* payload, const uint8_t payload_len);
+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
index 6b5fa60..e742e7a 100644
--- a/src/net_client.c
+++ b/src/net_client.c
@@ -7,73 +7,9 @@
#include <unistd.h>
#include <assert.h>
#include "net.h"
+#include "global.h"
#include "player.h"
#include "game.h"
-#include "global.h"
-
-/**
- * Client side function; Send hello to server
- * @param[in] sock Socket to use
- * @param[in] username Username of player
- */
-void client_hello(int sock, const char* username)
-{
- assert(username != NULL);
-
- uint8_t* buf;
- uint8_t namelen = strlen(username);
-
- buf = malloc(namelen+2); // type + len + username
- if(buf == NULL)
- {
- printf("client_hello: Out of memory\n");
- exit(EXIT_FAILURE);
- }
-
- buf[NET_MSG_OFFSET_TYPE] = msg_type_hello;
- buf[NET_MSG_OFFSET_PAYLOAD_LENGTH] = namelen;
- memcpy(buf+NET_MSG_OFFSET_PAYLOAD, username, namelen);
-
- send(sock, buf, namelen+2, 0);
-
- free(buf);
-}
-
-/**
- * Client side function; Send selected card to server
- * @param[in] sock Socket to use
- * @param[in] c Selected card
- */
-void client_selected_card(int sock, const card c)
-{
- assert(c >= MIN_CARD && c <= MAX_CARD);
-
- uint8_t buf[3];
-
- buf[NET_MSG_OFFSET_TYPE] = msg_type_selected_card;
- buf[NET_MSG_OFFSET_PAYLOAD_LENGTH] = 1;
- buf[NET_MSG_OFFSET_PAYLOAD] = c;
-
- send(sock, buf, 3, 0);
-}
-
-/**
- * Client side function; Send selected table stack to server
- * @param[in] sock Socket to use
- * @param[in] stackindex Index of selected stack
- */
-void client_send_selected_stack(int sock, const uint8_t stackindex)
-{
- assert(stackindex <= NUM_TABLE_STACKS);
-
- uint8_t buf[3];
-
- buf[NET_MSG_OFFSET_TYPE] = msg_type_selected_stack_c;
- buf[NET_MSG_OFFSET_PAYLOAD_LENGTH] = 1;
- buf[NET_MSG_OFFSET_PAYLOAD] = stackindex;
-
- send(sock, buf, 3, 0);
-}
/**
* Client side function; connects to specified host:port
@@ -126,7 +62,7 @@ int client_connect_server(const char* host, const char* port)
return sock;
}
-void* client_recv_player_list(const uint8_t* payload, const uint8_t data_len)
+bool client_recv_player_list(const uint8_t* payload, const uint8_t data_len)
{
assert(payload != NULL);
@@ -142,40 +78,79 @@ void* client_recv_player_list(const uint8_t* payload, const uint8_t data_len)
ds->players.players[i].player_id = payload[pos++];
namelen = payload[pos++];
assert(namelen <= MAX_PLAYER_NAME_LENGTH);
- strncpy(ds->players.players[i].player_name, payload+pos, namelen);
+ strncpy(ds->players.players[i].player_name, (const char*) payload+pos, namelen);
ds->players.players[i].player_name[namelen] = '\0';
pos += namelen;
}
- return NULL; // TODO return boolean (for success indication)
+ return true;
}
-hand_t *client_recv_deal_cards(const uint8_t* payload, const uint8_t payload_len)
+bool client_recv_deal_cards(const uint8_t* payload, const uint8_t payload_len)
{
assert(payload != NULL);
-
- hand_t *h = malloc(sizeof(hand_t));
-
assert(payload_len == MAX_HAND_CARDS); // deal_cards packet have fixed size
+ data_store* ds = datamodel();
+
for(int i=0; i<MAX_HAND_CARDS; i++)
- {
- h->cards[i] = payload[i];
- }
+ ds->hand.cards[i] = payload[i];
- return h;
+ return true;
}
-uint8_t* client_recv_selected_stack(const uint8_t* payload, const uint8_t payload_len)
+bool client_recv_selected_stack(const uint8_t* payload, const uint8_t payload_len)
{
- assert(payload != NULL);
- assert(payload_len == 1);
+ 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; i<NUM_TABLE_STACKS; i++)
+ ds->table_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;
- uint8_t* stackindex = malloc(sizeof(uint8_t));
- *stackindex = payload[0];
+ return 1;
+}
+
+uint8_t client_send_selected_stack(uint8_t* payload, const uint8_t payload_len)
+{
+ data_store* ds = datamodel();
- assert(*stackindex <= NUM_TABLE_STACKS);
+ payload[0] = ds->stack_index;
+ assert(ds->stack_index <= NUM_TABLE_STACKS);
- return stackindex;
+ return 1;
}
diff --git a/src/net_server.c b/src/net_server.c
index 52dca17..a7f6c48 100644
--- a/src/net_server.c
+++ b/src/net_server.c
@@ -8,6 +8,7 @@
#include <assert.h>
#include "net.h"
#include "player.h"
+#include "global.h"
/**
* Server side function; start server on specified port
@@ -76,108 +77,30 @@ int server_start(const char* port)
/**
* 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
- * @return List of $count open sockets with connections to clients
*/
-int* server_get_players(int serversock, const uint8_t count)
+void server_get_players(int serversock, socket_list_t* client_socks, const uint8_t count)
{
- int* clientsocks;
int i;
assert(count < MAX_PLAYERS && count > 0);
- clientsocks = malloc(count*sizeof(int));
- if(clientsocks == NULL)
- {
- printf("server_get_players: Out of memory\n");
- exit(EXIT_FAILURE);
- }
-
// accept connections
for(i=0; i<count; i++)
{
- int sock;
struct sockaddr_storage addr;
socklen_t addrlen = sizeof(addr);
- sock = accept(serversock, (struct sockaddr*) &addr, &addrlen);
- if(sock == -1)
+ client_socks->sockets[i] = accept(serversock, (struct sockaddr*) &addr, &addrlen);
+ if(client_socks->sockets[i] == -1)
{
- printf("accept: %s\n", strerror(sock));
+ 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);
- clientsocks[i] = sock;
}
-
- return clientsocks;
-}
-
-/**
- * Server side function; notifies players of game start and send list of all players
- * @param[in] clients List of sockets with connection to clients
- * @param[in] clientcount Number of clients
- * @param[in] players List of all players (including self) to send
- */
-void server_start_game(int* clients, const uint8_t clientcount, const player_list* players)
-{
- assert(clients != NULL);
- assert(players != NULL);
-
- uint8_t* buf;
- uint8_t usercount = players->count;
- uint32_t pos;
- uint32_t buflen = 3 + 2*usercount; // type + packetlen + usercount + (usercount * player_id) + (usercount * len)
-
- //for(int i=0; i<usercount; i++)
- // buflen += strlen(players->names[i]);
-
- buf = malloc(buflen);
- if(buf == NULL)
- {
- printf("server_start_game: Out of memory\n");
- exit(EXIT_FAILURE);
- }
- buf[NET_MSG_OFFSET_TYPE] = msg_type_start_game;
- buf[NET_MSG_OFFSET_PAYLOAD_LENGTH] = buflen - 2;
- pos = NET_MSG_OFFSET_PAYLOAD;
- buf[pos++] = players->count;
- // copy usernames with length to buffer
- for(int i=0; i<usercount; i++)
- {
- /*
- buf[pos++] = i; // player_id
- uint8_t len = strlen(players->names[i]);
- buf[pos++] = len;
- memcpy(buf+pos, players->names[i], len);
- pos += len;*/
- }
-
- // send to all users
- for(int i=0; i<clientcount; i++)
- send(clients[i], buf, buflen, 0);
-
- free(buf);
-}
-
-/**
- * Server side function; broadcast a selected table stack to all clients
- * @param[in] clients Array of sockets with connections to clients
- * @param[in] clientcount Number of sockets/clients
- * @param[in] stackindex Selected stack to broadcast
- */
-void server_send_selected_stack(int* clients, const uint8_t clientcount, const uint8_t stackindex)
-{
- assert(clients != NULL);
- assert(stackindex <= NUM_TABLE_STACKS);
-
- uint8_t buf[3];
- buf[NET_MSG_OFFSET_TYPE] = msg_type_selected_stack_s;
- buf[NET_MSG_OFFSET_PAYLOAD_LENGTH] = 1;
- buf[NET_MSG_OFFSET_PAYLOAD] = stackindex;
-
- for(int i=0; i<clientcount; i++)
- send(clients[i], buf, 3, 0);
+ client_socks->count = count;
}
/**
@@ -226,21 +149,52 @@ uint8_t* server_recv_selected_stack(const uint8_t* payload, const uint8_t payloa
return index;
}
-/**
- * Server side function; deal cards to a client (send hand)
- * @param[in] sock Socket to use
- * @param[in] h Hand to send
- */
-void server_deal_cards(int sock, const hand_t *h)
+uint8_t server_send_start_game(uint8_t* payload, const uint8_t payload_len)
{
- assert(h != NULL);
+ uint16_t pos = 0;
+ data_store* ds = datamodel();
+ player_list* players = &ds->players;
- uint8_t buf[2+MAX_HAND_CARDS];
+ payload[pos++] = players->count;
+
+ // copy player_ids, length and nicknames to buffer
+ for(int i=0; i<players->count; 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;
- buf[NET_MSG_OFFSET_TYPE] = msg_type_deal_cards;
- buf[NET_MSG_OFFSET_PAYLOAD_LENGTH] = MAX_HAND_CARDS;
for(int i=0; i<MAX_HAND_CARDS; i++)
- buf[NET_MSG_OFFSET_PAYLOAD+i] = h->cards[i];
+ payload[i] = hand->cards[i];
- send(sock, buf, 2+MAX_HAND_CARDS, 0);
+ return MAX_HAND_CARDS;
}
+
+
+uint8_t server_send_initial_stacks(uint8_t* payload, const uint8_t payload_len)
+{
+// TODO
+}
+