Commit b36c92f7 authored by Simon Wüllhorst's avatar Simon Wüllhorst

Refactored rec functions in gamepeer:

- Gamepeer can work with both, now: TCP and UDP.
- HB / HB_ACK works now in both directions between
  gamepeer and gameserver.
- TODO: Unifiy datastructures to reduce amount of
  similiar functions.
parent 811ee766
......@@ -24,10 +24,10 @@
* SUCH DAMAGE.
*/
#include <stdio.h>
#include <sys/time.h>
#define MAX_DESCRIPTION_LENGTH 100
//#define DEBUG
struct timer {
struct timer* prev;
struct timer* next;
......
......@@ -9,6 +9,8 @@
#define BUFFER_SIZE (1 << 16)
#define BACKLOG 1000
#define MODE_SERVER 1
#define MODE_DIRECT 2
/*
* Message TYPES
*/
......@@ -29,7 +31,7 @@
#define LOCAL_PLAYER -1
#define REMOTE_PLAYER 1
//#define STATE_INIT 0
#define STATE_INIT 0
#define STATE_WAIT_FOREIGN_MOVE 1
#define STATE_WAIT_ACK 2
//#define STATE_GOT_FORGEIN_MOVE 2
......
......@@ -16,47 +16,17 @@ int parse_remote_client(int argc, char** argv, game_peers_info* peers_info)
hints.ai_socktype = SOCK_DGRAM;
//hints.ai_flags = AI_V4MAPPED;
Getaddrinfo(argv[3], argv[4], &hints, &peers_info->remote);
return 0;
return MODE_DIRECT;
}
// ssize_t packet_sequenzer(client_info* a_client, ssize_t n)
// {
// ssize_t len;
// uint16_t msg_len;
// struct msg_meta_t* a_msg;
// len = n + a_client->buf_offset;
// if (len < sizeof(struct msg_meta_t))
// return len;
// a_msg = (struct msg_meta_t*)a_client->buf;
// a_msg->length = ntohs(a_msg->length);
// a_msg->type = ntohs(a_msg->type);
// msg_len = sizeof(struct msg_meta_t) + a_msg->length + (4 - a_msg->length % 4) % 4;
// if (len < msg_len)
// return len;
// handle_client_message(a_client, a_msg);
// memmove(a_client->buf, a_client->buf + msg_len, len - msg_len);
// return packet_sequenzer(a_client, n - msg_len);
// }
int parse_remote_server(int argc, char** argv, game_peers_info* peers_info)
{
struct addrinfo hints;
msg_heartbeat hb;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
Getaddrinfo(argv[3], argv[4], &hints, &peers_info->remote);
peers_info->net_fd = Socket(peers_info->remote->ai_family, peers_info->remote->ai_socktype, peers_info->remote->ai_protocol);
Connect(peers_info->net_fd, peers_info->remote->ai_addr, peers_info->remote->ai_addrlen);
hb.length = htons(0);
hb.type = htons(MSG_HEARTBEAT);
Send(peers_info->net_fd, (const void*)&hb, sizeof(hb), 0);
Close(peers_info->net_fd);
printf("ERR: Server-Modus not implemented, yet.\n");
return -1;
return MODE_SERVER;
}
int parse_args(int argc, char** argv, game_peers_info* peers_info)
{
......@@ -212,7 +182,36 @@ int handle_msg_ack(game_peers_info* peers_info, msg_move_ack* a_move_ack)
return 0;
}
void handle_rec(game_peers_info* peers_info)
void handle_rec_msg(game_peers_info* peers_info, struct msg_meta_t* meta_data)
{
//printf("GOT PACKET: LENGHT: %d, TYPE: %d\n", meta_data->length, meta_data->type);
switch (meta_data->type) {
case MSG_HEARTBEAT:
send_hb_ack(peers_info);
break;
case MSG_HEARTBEAT_ACK:
peers_info->timer.hb_timeout_ms = TIMEOUT_HB_MIN_MS;
break;
case MSG_MOVE:
handle_foreign_move(peers_info, (msg_move*)peers_info->message.buf);
break;
case MSG_MOVE_ACK:
handle_msg_ack(peers_info, (msg_move_ack*)peers_info->message.buf);
break;
case MSG_UNKNOWN_MSG_TYPE:
finalize(peers_info, -1, "Sended unknown message.\n");
break;
default:
printf("Received unknown message, msg_type-ID: %d\n", meta_data->type);
send_unknown_packet(peers_info);
break;
};
}
/* for udp */
void handle_rec_udp(game_peers_info* peers_info)
{
ssize_t n;
struct msg_meta_t* meta_data;
......@@ -235,28 +234,43 @@ void handle_rec(game_peers_info* peers_info)
send_unknown_packet(peers_info);
return;
}
handle_rec_msg(peers_info, meta_data);
}
//printf("GOT PACKET: LENGHT: %d, TYPE: %d\n", meta_data->length, meta_data->type);
/* for tcp */
ssize_t packet_sequenzer(game_peers_info* peers_info, ssize_t n)
{
ssize_t len;
uint16_t msg_len;
struct msg_meta_t* a_msg;
len = n + peers_info->message.buf_offset;
if (len < sizeof(struct msg_meta_t))
return len;
switch (meta_data->type) {
case MSG_HEARTBEAT:
send_hb_ack(peers_info);
break;
case MSG_HEARTBEAT_ACK:
peers_info->timer.hb_timeout_ms = TIMEOUT_HB_MIN_MS;
break;
case MSG_MOVE:
handle_foreign_move(peers_info, (msg_move*)peers_info->message.buf);
break;
case MSG_MOVE_ACK:
handle_msg_ack(peers_info, (msg_move_ack*)peers_info->message.buf);
break;
default:
send_unknown_packet(peers_info);
break;
};
}
a_msg = (struct msg_meta_t*)peers_info->message.buf;
a_msg->length = ntohs(a_msg->length);
a_msg->type = ntohs(a_msg->type);
msg_len = sizeof(struct msg_meta_t) + a_msg->length + (4 - a_msg->length % 4) % 4;
if (len < msg_len)
return len;
handle_rec_msg(peers_info, a_msg);
memmove(peers_info->message.buf, peers_info->message.buf + msg_len, len - msg_len);
return packet_sequenzer(peers_info, n - msg_len);
}
void handle_rec_tcp(game_peers_info* peers_info)
{
ssize_t n;
printf("handle_client_rec\n");
if ((n = Recv(peers_info->net_fd, (void*)(peers_info->message.buf + peers_info->message.buf_offset), BUFFER_SIZE - peers_info->message.buf_offset, 0)) == 0) {
finalize(peers_info, -1, NULL);
return;
}
printf("Received %zd bytes, buf offset: %zd \n", n, peers_info->message.buf_offset);
peers_info->message.buf_offset = packet_sequenzer(peers_info, n);
}
int make_own_move(game_peers_info* peers_info, int column)
{
int a_winner;
......@@ -319,6 +333,25 @@ void handle_stdin(game_peers_info* peers_info)
//printf("STATE->STATE_WAIT_ACK\n");
return;
}
int init_gs_4gw(game_peers_info* peers_info)
{
msg_heartbeat hb;
peers_info->net_fd = Socket(peers_info->remote->ai_family, peers_info->remote->ai_socktype, peers_info->remote->ai_protocol);
Connect(peers_info->net_fd, peers_info->remote->ai_addr, peers_info->remote->ai_addrlen);
register_fd_callback(peers_info->net_fd, (void (*)(void*)) & handle_rec_tcp, peers_info);
peers_info->timer.hb_timer = create_timer((void (*)(void*)) & handle_hb_timer, peers_info, "HB_TIMER");
start_timer(peers_info->timer.hb_timer, 200);
peers_info->timer.hb_timeout_ms = TIMEOUT_HB_MIN_MS;
hb.length = htons(0);
hb.type = htons(MSG_HEARTBEAT);
Send(peers_info->net_fd, (const void*)&hb, sizeof(hb), 0);
//Close(peers_info->net_fd);
peers_info->state.current_state = STATE_INIT;
return 0;
}
int init_4gw(game_peers_info* peers_info)
{
//int option;
......@@ -328,13 +361,11 @@ int init_4gw(game_peers_info* peers_info)
Bind(peers_info->net_fd, peers_info->local->ai_addr, peers_info->local->ai_addrlen);
Connect(peers_info->net_fd, (const struct sockaddr*)peers_info->remote->ai_addr, peers_info->remote->ai_addrlen);
init_4clib();
init_cblib();
memset(&peers_info->state, 0, sizeof(peers_info->state));
memset(&peers_info->timer, 0, sizeof(peers_info->timer));
register_stdin_callback((void (*)(void*)) & handle_stdin, peers_info);
register_fd_callback(peers_info->net_fd, (void (*)(void*)) & handle_rec, peers_info);
register_fd_callback(peers_info->net_fd, (void (*)(void*)) & handle_rec_udp, peers_info);
peers_info->timer.hb_timer = create_timer((void (*)(void*)) & handle_hb_timer, peers_info, "HB_TIMER");
peers_info->timer.ack_timer = create_timer((void (*)(void*)) & handle_ack_timer, peers_info, "ACK_TIMER");
start_timer(peers_info->timer.hb_timer, 10000);
......@@ -356,15 +387,23 @@ int init_4gw(game_peers_info* peers_info)
//printf("STATE->STATE_WAIT_FOREIGN_MOVE\n");
}
handle_events();
return 0;
}
int main(int argc, char** argv)
{
game_peers_info peers_info;
if (parse_args(argc, argv, &peers_info) != 0)
init_4clib();
init_cblib();
switch (parse_args(argc, argv, &peers_info)) {
case MODE_DIRECT:
init_4gw(&peers_info);
break;
case MODE_SERVER:
init_gs_4gw(&peers_info);
break;
default:
return -1;
init_4gw(&peers_info);
finalize(&peers_info, 0, NULL);
}
handle_events();
}
......@@ -60,7 +60,22 @@ void finalize(game_server_info* server_info, int exit_code, char* last_message)
freeaddrinfo(server_info->server);
exit(exit_code);
}
int send_hb_ack(client_info* a_client)
{
msg_heartbeat_ack a_hb_ack;
a_hb_ack.length = htons(0);
a_hb_ack.type = htons(MSG_HEARTBEAT_ACK);
Send(a_client->client_fd, &a_hb_ack, sizeof(a_hb_ack), 0);
return 0;
}
int send_unknown_packet(client_info* a_client)
{
msg_unknown_msg_type a_unknown;
a_unknown.length = htons(0);
a_unknown.type = htons(MSG_UNKNOWN_MSG_TYPE);
Send(a_client->client_fd, &a_unknown, sizeof(a_unknown), 0);
return 0;
}
void handle_client_hb_timer(client_info* a_client)
{
printf("handle_client_hb_timer\n");
......@@ -78,7 +93,22 @@ void handle_client_hb_timer(client_info* a_client)
}
void handle_client_message(client_info* a_client, struct msg_meta_t* a_msg)
{
printf("handle_client_message\n");
switch (a_msg->type) {
case MSG_HEARTBEAT_ACK:
a_client->hb_timeout_ms = TIMEOUT_HB_MIN_MS;
break;
case MSG_HEARTBEAT:
send_hb_ack(a_client);
break;
case MSG_UNKNOWN_MSG_TYPE:
printf("Sended unknown message.\n");
finalize_client(a_client);
break;
default:
printf("Received unknown message, msg_type-ID: %d\n", a_msg->type);
send_unknown_packet(a_client);
break;
}
}
ssize_t packet_sequenzer(client_info* a_client, ssize_t n)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment