Commit 1323d0cc authored by Simon Wüllhorst's avatar Simon Wüllhorst

Implemented first parts of the gameserver

parent 7a4345e9
......@@ -5,12 +5,12 @@
#ifndef GAME_H_
#define GAME_H_
#define BUFFER_SIZE (1 << 16)
#define BACKLOG 1000
/*
* Message TYPES
*/
#define BUFFER_SIZE (1 << 16)
#define MSG_REG 0
#define MSG_REG_ACK 1
#define MSG_REG_NACK 2
......@@ -106,4 +106,21 @@ struct game_peers_info_t {
};
typedef struct game_peers_info_t game_peers_info;
struct client_info_t {
struct game_server_info_t* server_info;
struct client_info_t* next;
int client_fd;
struct timer* hb_timer;
unsigned int hb_timeout_ms;
ssize_t buf_offset;
char buf[BUFFER_SIZE];
};
typedef struct client_info_t client_info;
struct game_server_info_t {
struct addrinfo* server;
int server_fd;
struct client_info_t client_queue;
};
typedef struct game_server_info_t game_server_info;
#endif
\ No newline at end of file
#include "gameserver.h"
void client_list_add(client_info* list, client_info* a_client)
{
for (; list->next != NULL; list = list->next) {
}
list->next = a_client;
}
void client_list_remove(client_info* list, client_info* a_client)
{
for (; list->next != a_client; list = list->next) {
if (list->next == NULL) {
printf("NOT FOUND IN LIST\n");
return;
}
}
list->next = list->next->next;
}
int parse_args(int argc, char** argv, game_server_info* server_info)
{
struct addrinfo hints;
if (argc != 2) {
printf("Wrong amount of parameters. Propper usage:\n ./%s LOCAL_PORT\n", argv[0]);
return -1;
}
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
Getaddrinfo(NULL, argv[1], &hints, &server_info->server);
return 0;
}
void finalize_client(client_info* a_client)
{
printf("Finalize client, fd #%d\n", a_client->client_fd);
stop_timer(a_client->hb_timer);
delete_timer(a_client->hb_timer);
deregister_fd_callback(a_client->client_fd);
Shutdown(a_client->client_fd, SHUT_WR);
while (Recv(a_client->client_fd, (void*)a_client->buf, (size_t)BUFFER_SIZE, 0) != 0) {
}
Close(a_client->client_fd);
client_list_remove(&a_client->server_info->client_queue, a_client);
free(a_client);
return;
}
void finalize(game_server_info* server_info, int exit_code, char* last_message)
{
client_info *a_client, *tmp_client;
if (last_message != NULL)
printf("%s", last_message);
for (a_client = server_info->client_queue.next; a_client != NULL;) {
tmp_client = a_client;
a_client = a_client->next;
finalize_client(tmp_client);
}
Close(server_info->server_fd);
freeaddrinfo(server_info->server);
exit(exit_code);
}
void handle_client_hb_timer(client_info* a_client)
{
printf("handle_client_hb_timer\n");
msg_heartbeat a_hb;
a_hb.length = htons(0);
a_hb.type = htons(MSG_HEARTBEAT);
Send(a_client->client_fd, &a_hb, sizeof(a_hb), 0);
a_client->hb_timeout_ms += a_client->hb_timeout_ms;
if (a_client->hb_timeout_ms > TIMEOUT_HB_MAX_MS) {
finalize_client(a_client);
return;
}
start_timer(a_client->hb_timer, a_client->hb_timeout_ms);
return;
}
void handle_client_message(client_info* a_client, struct msg_meta_t* a_msg)
{
printf("handle_client_message\n");
}
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);
}
void handle_client_rec(client_info* a_client)
{
printf("handle_client_rec\n");
ssize_t n;
if ((n = Recv(a_client->client_fd, (void*)(a_client->buf + a_client->buf_offset), BUFFER_SIZE, 0)) == 0)
finalize_client(a_client);
printf("Received %zd bytes.\n", n);
a_client->buf_offset = packet_sequenzer(a_client, n);
}
client_info* initialize_client(game_server_info* server_info, int a_client_fd)
{
printf("initialize_client\n");
client_info* a_client = NULL;
a_client = calloc(1, sizeof(client_info));
a_client->server_info = server_info;
a_client->client_fd = a_client_fd;
a_client->hb_timeout_ms = TIMEOUT_HB_MIN_MS;
register_fd_callback(a_client->client_fd, (void (*)(void*)) & handle_client_rec, a_client);
a_client->hb_timer = create_timer((void (*)(void*)) & handle_client_hb_timer, a_client, "A_REQUIRED_STRING");
start_timer(a_client->hb_timer, a_client->hb_timeout_ms);
return a_client;
}
void handle_accept(game_server_info* server_info)
{
int a_client_fd;
a_client_fd = Accept(server_info->server_fd, NULL, 0);
printf("Accepted client, fd #%d\n", a_client_fd);
client_list_add(&server_info->client_queue, initialize_client(server_info, a_client_fd));
}
int init_gs(game_server_info* server_info)
{
int option;
server_info->server_fd = Socket(server_info->server->ai_family, server_info->server->ai_socktype, 0);
option = 1;
Setsockopt(server_info->server_fd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
Bind(server_info->server_fd, server_info->server->ai_addr, server_info->server->ai_addrlen);
Listen(server_info->server_fd, BACKLOG);
init_cblib();
memset(&server_info->client_queue, 0, sizeof(server_info->client_queue));
register_fd_callback(server_info->server_fd, (void (*)(void*)) & handle_accept, server_info);
handle_events();
return 0;
}
int main(int argc, char** argv)
{
int val;
game_server_info server_info;
if (parse_args(argc, argv, &server_info) != 0)
return -1;
val = init_gs(&server_info);
finalize(&server_info, val, NULL);
return 0;
}
\ No newline at end of file
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