From a4e34c257a4f5966ce699f48d30b3528bdaa45e4 Mon Sep 17 00:00:00 2001 From: oroborus Date: Fri, 14 Mar 2008 15:25:01 +0000 Subject: - program bol prepisany tak, aby sa dal v buducnosti sietovy multiplayer prepisat pre protokol UDP ( BTW network.[ch] je uz zombia ) git-svn-id: http://opensvn.csie.org/tuxanci_ng@14 0ee4d065-81f0-4d1e-b06c-ff20ad07cc3e --- src/Makefile | 22 +- src/client.c | 142 ++++++++++++ src/item.c | 1 + src/net_multiplayer.c | 626 +++----------------------------------------------- src/network.c | 2 + src/proto.c | 252 ++++++++++++++++++++ src/screen_world.c | 6 +- src/server.c | 285 +++++++++++++++++++++++ src/tcp.c | 210 +++++++++++++++++ src/tux.c | 1 + src/udp.c | 198 ++++++++++++++++ 11 files changed, 1147 insertions(+), 598 deletions(-) create mode 100644 src/client.c create mode 100644 src/proto.c create mode 100644 src/server.c create mode 100755 src/tcp.c create mode 100644 src/udp.c (limited to 'src') diff --git a/src/Makefile b/src/Makefile index fd17130..2ecb449 100755 --- a/src/Makefile +++ b/src/Makefile @@ -1,8 +1,9 @@ +#CC = /usr/local/gcc/bin/gcc CC = gcc -#CFLAGS = -g -O0 -DDISTDIR=\"$(DISTDIR)\" `sdl-config --cflags` -I../include -Wall -CFLAGS = -O2 -DDISTDIR=\"$(DISTDIR)\" `sdl-config --cflags` -I../include -Wall +CFLAGS = -g -O0 -DDISTDIR=\"$(DISTDIR)\" `sdl-config --cflags` -I../include -Wall +#CFLAGS = -O2 -DDISTDIR=\"$(DISTDIR)\" `sdl-config --cflags` -I../include -Wall LIBS = `sdl-config --libs` -lSDL_image -lSDL_ttf -lSDL_mixer @@ -11,7 +12,8 @@ FILES = interface.o font.o list.o image.o layer.o director.o configFile.o tux.o buffer.o dynamicInt.o arena.o arenaFile.o textFile.o sound.o audio.o music.o gun.o \ item.o widget_label.o screen_mainMenu.o widget_button.o screen_analyze.o widget_textfield.o \ widget_check.o widget_image.o screen_setting.o screen_gameType.o screen_choiceArena.o \ - widget_buttonimage.o screen_credits.o teleport.o pipe.o homeDirector.o screen_table.o + widget_buttonimage.o screen_credits.o teleport.o pipe.o homeDirector.o screen_table.o \ + tcp.o udp.o proto.o server.o client.o tuxanci-ng: $(FILES) $(CC) $(CFLAGS) $(LIBS) -o tuxanci-ng $(FILES) @@ -64,6 +66,20 @@ panel.o: panel.c ../include/panel.h buffer.o: buffer.c ../include/buffer.h $(CC) $(CFLAGS) -o buffer.o -c buffer.c +tcp.o: tcp.c ../include/tcp.h + $(CC) $(CFLAGS) -o tcp.o -c tcp.c + +udp.o: udp.c ../include/udp.h + $(CC) $(CFLAGS) -o udp.o -c udp.c + +proto.o: proto.c ../include/proto.h + $(CC) $(CFLAGS) -o proto.o -c proto.c + +server.o: server.c ../include/server.h + $(CC) $(CFLAGS) -o server.o -c server.c + +client.o: client.c ../include/client.h + $(CC) $(CFLAGS) -o client.o -c client.c network.o: network.c ../include/network.h $(CC) $(CFLAGS) -o network.o -c network.c diff --git a/src/client.c b/src/client.c new file mode 100644 index 0000000..a885b65 --- /dev/null +++ b/src/client.c @@ -0,0 +1,142 @@ + +#include "list.h" +#include "tux.h" +#include "network.h" +#include "buffer.h" +#include "net_multiplayer.h" +#include "screen_world.h" +#include "tcp.h" +#include "udp.h" +#include "proto.h" +#include "client.h" + +static int protocolType; +static sock_tcp_t *sock_server_tcp; +static sock_udp_t *sock_server_udp; +static buffer_t *clientBuffer; + +int initTcpClient(char *ip, int port) +{ + sock_server_tcp = connectTcpSocket(ip, port); + + if( sock_server_tcp == NULL ) + { + return -1; + } + + printf("connect %s %d\n", ip, port); + clientBuffer = newBuffer( LIMIT_BUFFER ); + + return 0; +} + +void sendServer(char *msg) +{ + int ret; + + if( protocolType == NET_PROTOCOL_TYPE_TCP ) + { + ret = writeTcpSocket(sock_server_tcp, msg, strlen(msg)); + + if ( ret == 0 ) + { + fprintf(stderr, "server uzatvoril sietovy socket\n"); + setWorldEnd(); + } + + if ( ret < 0 ) + { + fprintf(stderr, "nastala chyba pri poslani spravy serveru\n"); + setWorldEnd(); + } + } + + if( protocolType == NET_PROTOCOL_TYPE_UDP ) + { + } +} + +static void eventServerTcpSelect() +{ + char buffer[STR_SIZE]; + int ret; + + memset(buffer,0 ,STR_SIZE); + + if( protocolType == NET_PROTOCOL_TYPE_TCP ) + { + ret = readTcpSocket(sock_server_tcp, buffer, STR_SIZE-1); + + if( ret == 0 ) + { + fprintf(stderr, "server uzatovril sietovy socket\n"); + setWorldEnd(); + return; + } + + if( ret < 0 ) + { + fprintf(stderr, "chyba, spojenie prerusene \n"); + setWorldEnd(); + return; + } + } + + if( protocolType == NET_PROTOCOL_TYPE_UDP ) + { + } + + if( addBuffer(clientBuffer, buffer, ret) != 0 ) + { + fprintf(stderr, "chyba, nemozem zapisovat do mojho buffera !\n"); + setWorldEnd(); + return; + } +} + +void eventServerBuffer() +{ + char line[STR_SIZE]; + + /* obsluha udalosti od servera */ + + while ( getBufferLine(clientBuffer, line, STR_SIZE) >= 0 ) + { + //printf("dostal som %s", line); + + if( strncmp(line, "init", 4) == 0 )proto_recv_init_client(line); + if( strncmp(line, "event", 5) == 0 )proto_recv_event_client(line); + if( strncmp(line, "newtux", 6) == 0 )proto_recv_newtux_client(line); + if( strncmp(line, "deltux", 6) == 0 )proto_recv_deltux_client(line); + if( strncmp(line, "additem", 7) == 0 )proto_recv_additem_client(line); + } +} + +void selectClientTcpSocket() +{ + fd_set readfds; + struct timeval tv; + int max_fd; + + tv.tv_sec = 0; + tv.tv_usec = 0; + + FD_ZERO(&readfds); + FD_SET(sock_server_tcp->sock, &readfds); + max_fd = sock_server_tcp->sock; + + select(max_fd+1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &tv); + + if( FD_ISSET(sock_server_tcp->sock, &readfds) ) + { + eventServerTcpSelect(sock_server_tcp); + } +} + +void quitTcpClient() +{ + closeTcpSocket(sock_server_tcp); + destroyBuffer(clientBuffer); + printf("quit conenct\n"); +} + diff --git a/src/item.c b/src/item.c index abfe2c5..3b7a147 100644 --- a/src/item.c +++ b/src/item.c @@ -13,6 +13,7 @@ #include "tux.h" #include "item.h" #include "shot.h" +#include "proto.h" static SDL_Surface *g_item[ITEM_COUNT]; diff --git a/src/net_multiplayer.c b/src/net_multiplayer.c index 3db7572..2cfc898 100644 --- a/src/net_multiplayer.c +++ b/src/net_multiplayer.c @@ -17,597 +17,51 @@ #include "screen_choiceArena.h" #include "arenaFile.h" #include "net_multiplayer.h" +#include "server.h" +#include "client.h" +#include "tcp.h" +#include "udp.h" static int netGameType; -static int sock_server; - -static list_t *listClient; -static buffer_t *clientBuffer; -static arena_t *arena; - -int initServer(int port) -{ - sock_server = newSocket(port , NULL); - - if( sock_server < 0 ) - { - return -1; - } - - listClient = newList(); - netGameType = NET_GAME_TYPE_SERVER; - - printf("server listen port %d\n", port); - - return 0; -} - -int initClient(int port, char *ip) -{ - sock_server = newSocket(port , ip); - - if( sock_server < 0 ) - { - return -1; - } - - clientBuffer = newBuffer( LIMIT_BUFFER ); - netGameType = NET_GAME_TYPE_CLIENT; - - printf("connect %s %d\n", ip, port); - - return 0; -} - -void netSetArena(arena_t *p) -{ - arena = p; -} int getNetTypeGame() { return netGameType; } -static void sendServer(char *msg) -{ - int ret; - - ret = write(sock_server, msg, strlen(msg)); - - if ( ret == 0 ) - { - fprintf(stderr, "server uzatvoril sietovy socket\n"); - setWorldEnd(); - } - - if ( ret < 0 ) - { - fprintf(stderr, "nastala chyba pri poslani spravy serveru\n"); - setWorldEnd(); - } -} - -static void sendClient(client_t *p, char *msg) -{ - if( p->status == NET_STATUS_OK ) - { - int ret; - - ret = write(p->socket, msg, strlen(msg)); - - if( ret == 0 ) - { - fprintf(stderr, "client sa odpojil\n"); - p->status = NET_STATUS_ZOMBIE; - } - - if( ret < 0 ) - { - fprintf(stderr, "nastala chyba pri posielanie spravy clientovy\n"); - p->status = NET_STATUS_ZOMBIE; - } - } -} - -static void sendAllClientBut(char *msg, client_t *p) -{ - client_t *thisClient; - int i; - - for( i = 0 ; i < listClient->count; i++) - { - thisClient = (client_t *) listClient->list[i]; - - if( thisClient != p ) - { - sendClient(thisClient, msg); - } - } -} - -static void sendAllClient(char *msg) -{ - sendAllClientBut(msg, NULL); -} - -static client_t* newClient(int sock) -{ - client_t *new; - - new = malloc( sizeof(client_t) ); - memset(new, 0, sizeof(client_t)); - - new->socket = sock; - new->status = NET_STATUS_OK; - new->buffer = newBuffer(LIMIT_BUFFER); - new->tux = newTux(); - new->tux->control = TUX_CONTROL_NET; - addList(arena->listTux, new->tux); - - return new; -} - -static void destroyClient(client_t *p) -{ - int index; - - close(p->socket); - destroyBuffer(p->buffer); - index = searchListItem(arena->listTux, p->tux); - delListItem(arena->listTux, index, destroyTux); - free(p); -} - -void proto_send_init_server(client_t *client) -{ - char msg[STR_SIZE]; - int n; - - getSettingCountRound(&n); - - sprintf(msg, "init %d %d %d %d %s\n", - client->tux->id, client->tux->x, client->tux->y, - n, getArenaNetName( getChoiceArenaId() )); - - sendClient(client, msg); -} - -void proto_recv_init_client(char *msg) -{ - char cmd[STR_SIZE]; - char arena_name[STR_SIZE]; - tux_t *tux; - int id; - int x, y, n; - - sscanf(msg, "%s %d %d %d %d %s\n", - cmd, &id, &x, &y, &n, arena_name); - - setWorldArena( getArenaIdFormNetName(arena_name) ); - setMaxCountRound(n); - - tux = newTux(); - tux->id = id; - tux->x = x; - tux->y = y; - tux->control = TUX_CONTROL_KEYBOARD_RIGHT; - getSettingNameRight(tux->name); - - proto_send_context_client(tux); - addList(arena->listTux, tux); -} - -void proto_send_event_server(tux_t *tux, int action, client_t *client) -{ - char msg[STR_SIZE]; - - sprintf(msg, "event %d %d\n", tux->id, action); - - sendAllClientBut(msg, client); -} - -void proto_recv_event_client(char *msg) -{ - char cmd[STR_SIZE]; - int id, action; - tux_t *tux; - - sscanf(msg, "%s %d %d", cmd, &id, &action); - - tux = getTuxID(arena->listTux, id); - - if( tux != NULL ) - { - actionTux(tux, action); - } -} - -void proto_send_event_client(int action) -{ - char msg[STR_SIZE]; - - sprintf(msg, "event %d\n", action); - - sendServer(msg); -} - -void proto_recv_event_server(client_t *client, char *msg) -{ - char cmd[STR_SIZE]; - int action; - - sscanf(msg, "%s %d", cmd, &action); - - actionTux(client->tux, action); - - proto_send_event_server(client->tux, action, client); -} - -void proto_send_newtux_server(client_t *client, tux_t *tux) -{ - char msg[STR_SIZE]; - - sprintf(msg, "newtux %d %d %d %d %d %d %s %d %d %d %d %d %d %d %d %d %d %d\n", - tux->id ,tux->x, tux->y, tux->position ,tux->frame, tux->score, tux->name, - tux->gun, tux->bonus, tux->shot[GUN_SIMPLE], tux->shot[GUN_DUAL_SIMPLE], - tux->shot[GUN_SCATTER], tux->shot[GUN_TOMMY], tux->shot[GUN_LASSER], - tux->shot[GUN_MINE], tux->shot[GUN_BOMBBALL], - tux->bonus_time, tux->pickup_time); - - if( client == NULL ) - { - sendAllClient(msg); - } - else - { - sendClient(client, msg); - } -} - -void proto_recv_newtux_client(char *msg) -{ - char cmd[STR_SIZE]; - char name[STR_NAME_SIZE]; - int id, x, y, position, frame, score; - int myGun, myBonus; - int gun1, gun2, gun3, gun4, gun5, gun6, gun7; - int time1, time2; - tux_t *tux; - - sscanf(msg, "%s %d %d %d %d %d %d %s %d %d %d %d %d %d %d %d %d %d %d", - cmd, &id, &x, &y, &position, &frame, &score, name, - &myGun, &myBonus, &gun1, &gun2, &gun3, &gun4, &gun5, &gun6, &gun7, &time1, &time2); - - tux = getTuxID(arena->listTux, id); - - if( tux == NULL ) - { - tux = newTux(); - tux->control = TUX_CONTROL_NET; - addList(arena->listTux, tux); - } - - tux->id = id; - tux->x = x; - tux->y = y; - tux->position = position; - tux->frame = frame; - tux->score = score; - strcpy(tux->name, name); - tux->gun = myGun; - tux->bonus = myBonus; - tux->shot[GUN_SIMPLE] = gun1; - tux->shot[GUN_DUAL_SIMPLE] = gun2; - tux->shot[GUN_SCATTER] = gun3; - tux->shot[GUN_TOMMY] = gun4; - tux->shot[GUN_LASSER] = gun5; - tux->shot[GUN_MINE] = gun6; - tux->shot[GUN_BOMBBALL] = gun7; - tux->bonus_time = time1; - tux->pickup_time = time2; - tux->status = TUX_STATUS_ALIVE; -} - -void proto_send_deltux_server(client_t *client) -{ - char msg[STR_SIZE]; - - sprintf(msg, "deltux %d\n", client->tux->id); - - sendAllClientBut(msg, client); -} - -void proto_recv_deltux_client(char *msg) -{ - char cmd[STR_SIZE]; - int id; - tux_t *tux; - - sscanf(msg, "%s %d\n", cmd, &id); - - tux = getTuxID(arena->listTux, id); - - if( tux != NULL ) - { - int index; - - index = searchListItem(arena->listTux, tux); - delListItem(arena->listTux, index, destroyTux); - } -} - -void proto_send_additem_server(item_t *p) -{ - char msg[STR_SIZE]; - int id = -1; - - if( p->author != NULL ) - { - id = p->author->id; - } - - sprintf(msg, "additem %d %d %d %d %d %d\n", - p->type, p->x, p->y, p->count, p->frame, id); - - sendAllClient(msg); -} - -void proto_recv_additem_client(char *msg) +int initNetMuliplayer(int type, char *ip, int port) { - char cmd[STR_SIZE]; - int type, x, y, count, frame, id; - item_t *item; - - sscanf(msg, "%s %d %d %d %d %d %d\n", cmd, &type, &x, &y, &count, &frame, &id); - - item = newItem(x, y, type, getTuxID(arena->listTux, id)); - - if( isConflictWithListItem(arena->listItem, item->x, item->y, item->w, item->h) ) - { - destroyItem(item); - return; - } - - item->count = count; - item->frame = frame; - - addList(arena->listItem, item); -} - -void proto_send_context_client(tux_t *tux) -{ - char msg[STR_SIZE]; - - sprintf(msg, "context %s\n", tux->name); - - sendServer(msg); -} - -void proto_recv_context_server(client_t *client, char *msg) -{ - char cmd[STR_SIZE]; - char name[STR_NAME_SIZE]; - - sscanf(msg, "%s %s\n", cmd, name); - - strcpy(client->tux->name, name); - - proto_send_newtux_server(NULL, client->tux); -} - -void eventCreateNewClient(int sock) -{ - client_t *client; - client_t *thisClient; - tux_t *thisTux; - item_t *thisItem; - int i; - - client = newClient( getNewClient(sock) ); - addList(listClient, client); - - proto_send_init_server(client); - - proto_send_newtux_server(client, (tux_t *)(arena->listTux->list[0]) ); - - for( i = 0 ; i < listClient->count; i++) - { - thisClient = (client_t *) listClient->list[i]; - thisTux = thisClient->tux; + netGameType = type; - if( thisTux != client->tux ) - { - proto_send_newtux_server(thisClient, client->tux); - proto_send_newtux_server(client, thisTux); - } - } - - for( i = 0 ; i < arena->listItem->count; i++) - { - thisItem = (item_t *) arena->listItem->list[i]; - proto_send_additem_server(thisItem); - } -} - -static void eventClientSelect(client_t *client) -{ - char buffer[STR_SIZE]; - int ret; - - assert( client != NULL ); - - memset(buffer, 0, STR_SIZE); - ret = read(client->socket, buffer, STR_SIZE-1); - - if( ret <= 0 ) - { - client->status = NET_STATUS_ZOMBIE; - return; - } - - if( addBuffer(client->buffer, buffer, ret) != 0 ) - { - client->status = NET_STATUS_ZOMBIE; - return; - } -} - -static void eventClientBuffer(client_t *client) -{ - char line[STR_SIZE]; - - if( netGameType == NET_GAME_TYPE_NONE ) - { - return; - } - - /* obsluha udalosti od clientov */ - - while( getBufferLine(client->buffer, line, STR_SIZE) >= 0 ) - { - //printf("dostal som %s", line); - - if( strncmp(line, "event", 5) == 0 )proto_recv_event_server(client, line); - if( strncmp(line, "context", 7) == 0 )proto_recv_context_server(client, line); - } -} - -static void eventClientListBuffer() -{ - client_t *thisClient; - int i; - - for( i = 0 ; i < listClient->count; i++) - { - thisClient = (client_t *) listClient->list[i]; - eventClientBuffer(thisClient); - } -} - -static void selectServerSocket() -{ - fd_set readfds; - struct timeval tv; - client_t *thisClient; - int max_fd; - int i; - - tv.tv_sec = 0; - tv.tv_usec = 0; - - FD_ZERO(&readfds); - FD_SET(sock_server, &readfds); - max_fd = sock_server; - - for( i = 0 ; i < listClient->count; i++) - { - thisClient = (client_t *) listClient->list[i]; - - FD_SET(thisClient->socket, &readfds); - - if( thisClient->socket > max_fd ) - { - max_fd = thisClient->socket; - } - } - - select(max_fd+1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &tv); - - if( FD_ISSET(sock_server, &readfds) ) - { - eventCreateNewClient(sock_server); - } - - for( i = 0 ; i < listClient->count; i++) - { - thisClient = (client_t *) listClient->list[i]; - - if( FD_ISSET(thisClient->socket, &readfds) ) - { - eventClientSelect(thisClient); - } - - if( thisClient->status == NET_STATUS_ZOMBIE ) - { - proto_send_deltux_server(thisClient); - delListItem(listClient, i, destroyClient); - } - } -} - -static void eventServerSelect(int sock) -{ - char buffer[STR_SIZE]; - int ret; - - memset(buffer,0 ,STR_SIZE); - ret = read(sock, buffer, STR_SIZE-1); - - if( ret == 0 ) - { - fprintf(stderr, "server uzatovril sietovy socket\n"); - setWorldEnd(); - return; - } - - if( ret < 0 ) - { - fprintf(stderr, "chyba, spojenie prerusene \n"); - setWorldEnd(); - return; - } - - if( addBuffer(clientBuffer, buffer, ret) != 0 ) + switch( netGameType ) { - fprintf(stderr, "chyba, nemozem zapisovat do mojho buffera !\n"); - setWorldEnd(); - return; - } -} - -static void eventServerBuffer() -{ - char line[STR_SIZE]; + case NET_GAME_TYPE_NONE : + break; - if( netGameType == NET_GAME_TYPE_NONE ) - { - return; - } + case NET_GAME_TYPE_SERVER : + if( initTcpServer(port) != 0 ) + { + fprintf(stderr, "Neomzem inicalizovat sietovu hru pre server !\n"); + netGameType = NET_GAME_TYPE_NONE; + return -1; + } + break; - /* obsluha udalosti od servera */ - - while ( getBufferLine(clientBuffer, line, STR_SIZE) >= 0 ) - { - //printf("dostal som %s", line); + case NET_GAME_TYPE_CLIENT : + if( initTcpClient(ip, port) != 0 ) + { + fprintf(stderr, "Neomzem inicalizovat sietovu hru pre clienta !\n"); + netGameType = NET_GAME_TYPE_NONE; + return -1; + } + break; - if( strncmp(line, "init", 4) == 0 )proto_recv_init_client(line); - if( strncmp(line, "event", 5) == 0 )proto_recv_event_client(line); - if( strncmp(line, "newtux", 6) == 0 )proto_recv_newtux_client(line); - if( strncmp(line, "deltux", 6) == 0 )proto_recv_deltux_client(line); - if( strncmp(line, "additem", 7) == 0 )proto_recv_additem_client(line); + default : + assert( ! "Premenna netGameType ma zlu hodnotu !" ); + break; } -} - -static void selectClientSocket() -{ - fd_set readfds; - struct timeval tv; - int max_fd; - tv.tv_sec = 0; - tv.tv_usec = 0; - - FD_ZERO(&readfds); - FD_SET(sock_server, &readfds); - max_fd = sock_server; - - select(max_fd+1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &tv); - - if( FD_ISSET(sock_server, &readfds) ) - { - eventServerSelect(sock_server); - } + return 0; } void eventNetMultiplayer() @@ -618,12 +72,12 @@ void eventNetMultiplayer() break; case NET_GAME_TYPE_SERVER : - selectServerSocket(); + selectServerTcpSocket(); eventClientListBuffer(); break; case NET_GAME_TYPE_CLIENT : - selectClientSocket(); + selectClientTcpSocket(); eventServerBuffer(); break; @@ -633,20 +87,6 @@ void eventNetMultiplayer() } } -static void quitServer() -{ - destroyListItem(listClient, destroyClient); - close(sock_server); - printf("quit port\n"); -} - -static void quitClient() -{ - destroyBuffer(clientBuffer); - close(sock_server); - printf("quit conenct\n"); -} - void quitNetMultiplayer() { switch( netGameType ) @@ -655,11 +95,11 @@ void quitNetMultiplayer() break; case NET_GAME_TYPE_SERVER : - quitServer(); + quitTcpServer(); break; case NET_GAME_TYPE_CLIENT : - quitClient(); + quitTcpClient(); break; default : diff --git a/src/network.c b/src/network.c index ebd209a..dee3c73 100755 --- a/src/network.c +++ b/src/network.c @@ -1,5 +1,7 @@ #include "network.h" +#include "tcp.h" +#include "udp.h" #include #include diff --git a/src/proto.c b/src/proto.c new file mode 100644 index 0000000..8304c6d --- /dev/null +++ b/src/proto.c @@ -0,0 +1,252 @@ + +#include "list.h" +#include "tux.h" +#include "item.h" +#include "network.h" +#include "string_length.h" +#include "screen_world.h" +#include "screen_setting.h" +#include "screen_choiceArena.h" +#include "arenaFile.h" +#include "net_multiplayer.h" +#include "client.h" +#include "server.h" +#include "proto.h" + +void proto_send_init_server(client_t *client) +{ + char msg[STR_SIZE]; + int n; + + getSettingCountRound(&n); + + sprintf(msg, "init %d %d %d %d %s\n", + client->tux->id, client->tux->x, client->tux->y, + n, getArenaNetName( getChoiceArenaId() )); + + sendClient(client, msg); +} + +void proto_recv_init_client(char *msg) +{ + char cmd[STR_SIZE]; + char arena_name[STR_SIZE]; + tux_t *tux; + int id; + int x, y, n; + + sscanf(msg, "%s %d %d %d %d %s\n", + cmd, &id, &x, &y, &n, arena_name); + + setWorldArena( getArenaIdFormNetName(arena_name) ); + setMaxCountRound(n); + + tux = newTux(); + tux->id = id; + tux->x = x; + tux->y = y; + tux->control = TUX_CONTROL_KEYBOARD_RIGHT; + getSettingNameRight(tux->name); + + proto_send_context_client(tux); + addList(getWorldArena()->listTux, tux); +} + +void proto_send_event_server(tux_t *tux, int action, client_t *client) +{ + char msg[STR_SIZE]; + + sprintf(msg, "event %d %d\n", tux->id, action); + + sendAllClientBut(msg, client); +} + +void proto_recv_event_client(char *msg) +{ + char cmd[STR_SIZE]; + int id, action; + tux_t *tux; + + sscanf(msg, "%s %d %d", cmd, &id, &action); + + tux = getTuxID(getWorldArena()->listTux, id); + + if( tux != NULL ) + { + actionTux(tux, action); + } +} + +void proto_send_event_client(int action) +{ + char msg[STR_SIZE]; + + sprintf(msg, "event %d\n", action); + + sendServer(msg); +} + +void proto_recv_event_server(client_t *client, char *msg) +{ + char cmd[STR_SIZE]; + int action; + + sscanf(msg, "%s %d", cmd, &action); + + actionTux(client->tux, action); + + proto_send_event_server(client->tux, action, client); +} + +void proto_send_newtux_server(client_t *client, tux_t *tux) +{ + char msg[STR_SIZE]; + + sprintf(msg, "newtux %d %d %d %d %d %d %s %d %d %d %d %d %d %d %d %d %d %d\n", + tux->id ,tux->x, tux->y, tux->position ,tux->frame, tux->score, tux->name, + tux->gun, tux->bonus, tux->shot[GUN_SIMPLE], tux->shot[GUN_DUAL_SIMPLE], + tux->shot[GUN_SCATTER], tux->shot[GUN_TOMMY], tux->shot[GUN_LASSER], + tux->shot[GUN_MINE], tux->shot[GUN_BOMBBALL], + tux->bonus_time, tux->pickup_time); + + if( client == NULL ) + { + sendAllClient(msg); + } + else + { + sendClient(client, msg); + } +} + +void proto_recv_newtux_client(char *msg) +{ + char cmd[STR_SIZE]; + char name[STR_NAME_SIZE]; + int id, x, y, position, frame, score; + int myGun, myBonus; + int gun1, gun2, gun3, gun4, gun5, gun6, gun7; + int time1, time2; + tux_t *tux; + + sscanf(msg, "%s %d %d %d %d %d %d %s %d %d %d %d %d %d %d %d %d %d %d", + cmd, &id, &x, &y, &position, &frame, &score, name, + &myGun, &myBonus, &gun1, &gun2, &gun3, &gun4, &gun5, &gun6, &gun7, &time1, &time2); + + tux = getTuxID(getWorldArena()->listTux, id); + + if( tux == NULL ) + { + tux = newTux(); + tux->control = TUX_CONTROL_NET; + addList(getWorldArena()->listTux, tux); + } + + tux->id = id; + tux->x = x; + tux->y = y; + tux->position = position; + tux->frame = frame; + tux->score = score; + strcpy(tux->name, name); + tux->gun = myGun; + tux->bonus = myBonus; + tux->shot[GUN_SIMPLE] = gun1; + tux->shot[GUN_DUAL_SIMPLE] = gun2; + tux->shot[GUN_SCATTER] = gun3; + tux->shot[GUN_TOMMY] = gun4; + tux->shot[GUN_LASSER] = gun5; + tux->shot[GUN_MINE] = gun6; + tux->shot[GUN_BOMBBALL] = gun7; + tux->bonus_time = time1; + tux->pickup_time = time2; + tux->status = TUX_STATUS_ALIVE; +} + +void proto_send_deltux_server(client_t *client) +{ + char msg[STR_SIZE]; + + sprintf(msg, "deltux %d\n", client->tux->id); + + sendAllClientBut(msg, client); +} + +void proto_recv_deltux_client(char *msg) +{ + char cmd[STR_SIZE]; + int id; + tux_t *tux; + + sscanf(msg, "%s %d\n", cmd, &id); + + tux = getTuxID(getWorldArena()->listTux, id); + + if( tux != NULL ) + { + int index; + + index = searchListItem(getWorldArena()->listTux, tux); + delListItem(getWorldArena()->listTux, index, destroyTux); + } +} + +void proto_send_additem_server(item_t *p) +{ + char msg[STR_SIZE]; + int id = -1; + + if( p->author != NULL ) + { + id = p->author->id; + } + + sprintf(msg, "additem %d %d %d %d %d %d\n", + p->type, p->x, p->y, p->count, p->frame, id); + + sendAllClient(msg); +} + +void proto_recv_additem_client(char *msg) +{ + char cmd[STR_SIZE]; + int type, x, y, count, frame, id; + item_t *item; + + sscanf(msg, "%s %d %d %d %d %d %d\n", cmd, &type, &x, &y, &count, &frame, &id); + + item = newItem(x, y, type, getTuxID(getWorldArena()->listTux, id)); + + if( isConflictWithListItem(getWorldArena()->listItem, item->x, item->y, item->w, item->h) ) + { + destroyItem(item); + return; + } + + item->count = count; + item->frame = frame; + + addList(getWorldArena()->listItem, item); +} + +void proto_send_context_client(tux_t *tux) +{ + char msg[STR_SIZE]; + + sprintf(msg, "context %s\n", tux->name); + + sendServer(msg); +} + +void proto_recv_context_server(client_t *client, char *msg) +{ + char cmd[STR_SIZE]; + char name[STR_NAME_SIZE]; + + sscanf(msg, "%s %s\n", cmd, name); + + strcpy(client->tux->name, name); + + proto_send_newtux_server(NULL, client->tux); +} + diff --git a/src/screen_world.c b/src/screen_world.c index b35e82e..068ac08 100644 --- a/src/screen_world.c +++ b/src/screen_world.c @@ -30,6 +30,7 @@ #include "net_multiplayer.h" #include "arena.h" #include "arenaFile.h" +#include "proto.h" static arena_t *arena; static int count; @@ -47,6 +48,8 @@ void setGameType() { int ret = 0; + ret = initNetMuliplayer( getSettingGameType(), getSettingIP(), getSettingPort() ); +/* if( getSettingGameType() == NET_GAME_TYPE_SERVER ) { ret = initServer( getSettingPort() ); @@ -56,7 +59,7 @@ void setGameType() { ret = initClient( getSettingPort() , getSettingIP() ); } - +*/ if( ret != 0 ) { fprintf(stderr, "Chyba inicalizacie sieti !\n"); @@ -72,7 +75,6 @@ arena_t* getWorldArena() void setWorldArena(int id) { arena = getArena(id); - netSetArena(arena); } void setMaxCountRound(int n) diff --git a/src/server.c b/src/server.c new file mode 100644 index 0000000..5a04e91 --- /dev/null +++ b/src/server.c @@ -0,0 +1,285 @@ + +#include "list.h" +#include "tux.h" +#include "network.h" +#include "buffer.h" +#include "net_multiplayer.h" +#include "screen_world.h" +#include "tcp.h" +#include "udp.h" +#include "proto.h" +#include "server.h" +#include "assert.h" + +static int protocolType; +static sock_tcp_t *sock_server_tcp; +static sock_udp_t *sock_server_udp; +static list_t *listClient; + +int initTcpServer(int port) +{ + protocolType = NET_PROTOCOL_TYPE_TCP; + + sock_server_tcp = bindTcpSocket(port); + listClient = newList(); + + if( sock_server_tcp == NULL ) + { + return -1; + } + + printf("server listen port %d\n", port); + + return 0; +} + +static client_t* newAnyClient() +{ + client_t *new; + + new = malloc( sizeof(client_t) ); + memset(new, 0, sizeof(client_t)); + + new->status = NET_STATUS_OK; + new->buffer = newBuffer(LIMIT_BUFFER); + new->tux = newTux(); + new->tux->control = TUX_CONTROL_NET; + addList(getWorldArena()->listTux, new->tux); + + return new; +} + +client_t* newTcpClient(sock_tcp_t *sock_tcp) +{ + client_t *new; + + new = newAnyClient(); + new->socket_tcp = sock_tcp; + + return new; +} + +client_t* newUdpClient(sock_udp_t *sock_udp) +{ + client_t *new; + + new = newAnyClient(); + new->socket_udp = sock_udp; + + return new; +} + +void destroyClient(client_t *p) +{ + int index; + + if( p->socket_tcp != NULL ) + { + closeTcpSocket(p->socket_tcp); + } + + if( p->socket_udp != NULL ) + { + closeUdpSocket(p->socket_udp); + } + + destroyBuffer(p->buffer); + index = searchListItem(getWorldArena()->listTux, p->tux); + delListItem(getWorldArena()->listTux, index, destroyTux); + + free(p); +} + +void sendClient(client_t *p, char *msg) +{ + if( p->status == NET_STATUS_OK ) + { + int ret; + + if( protocolType == NET_PROTOCOL_TYPE_TCP ) + { + ret = writeTcpSocket(p->socket_tcp, msg, strlen(msg)); + + if( ret == 0 ) + { + fprintf(stderr, "client sa odpojil\n"); + p->status = NET_STATUS_ZOMBIE; + } + + if( ret < 0 ) + { + fprintf(stderr, "nastala chyba pri posielanie spravy clientovy\n"); + p->status = NET_STATUS_ZOMBIE; + } + } + + if( protocolType == NET_PROTOCOL_TYPE_UDP ) + { + } + } +} + +void sendAllClientBut(char *msg, client_t *p) +{ + client_t *thisClient; + int i; + + for( i = 0 ; i < listClient->count; i++) + { + thisClient = (client_t *) listClient->list[i]; + + if( thisClient != p ) + { + sendClient(thisClient, msg); + } + } +} + +void sendAllClient(char *msg) +{ + sendAllClientBut(msg, NULL); +} + +static void eventCreateNewTcpClient(sock_tcp_t *socket_tcp) +{ + client_t *client; + client_t *thisClient; + tux_t *thisTux; + item_t *thisItem; + int i; + + client = newTcpClient( getTcpNewClient(socket_tcp) ); + addList(listClient, client); + + proto_send_init_server(client); + + proto_send_newtux_server(client, (tux_t *)(getWorldArena()->listTux->list[0]) ); + + for( i = 0 ; i < listClient->count; i++) + { + thisClient = (client_t *) listClient->list[i]; + thisTux = thisClient->tux; + + if( thisTux != client->tux ) + { + proto_send_newtux_server(thisClient, client->tux); + proto_send_newtux_server(client, thisTux); + } + } + + for( i = 0 ; i < getWorldArena()->listItem->count; i++) + { + thisItem = (item_t *) getWorldArena()->listItem->list[i]; + proto_send_additem_server(thisItem); + } +} + +static void eventClientTcpSelect(client_t *client) +{ + char buffer[STR_SIZE]; + int ret; + + assert( client != NULL ); + + memset(buffer, 0, STR_SIZE); + ret = readTcpSocket(client->socket_tcp, buffer, STR_SIZE-1); + + if( ret <= 0 ) + { + client->status = NET_STATUS_ZOMBIE; + return; + } + + if( addBuffer(client->buffer, buffer, ret) != 0 ) + { + client->status = NET_STATUS_ZOMBIE; + return; + } +} + +static void eventClientBuffer(client_t *client) +{ + char line[STR_SIZE]; + + /* obsluha udalosti od clientov */ + + while( getBufferLine(client->buffer, line, STR_SIZE) >= 0 ) + { + //printf("dostal som %s", line); + + if( strncmp(line, "event", 5) == 0 )proto_recv_event_server(client, line); + if( strncmp(line, "context", 7) == 0 )proto_recv_context_server(client, line); + } +} + +void eventClientListBuffer() +{ + int i; + client_t *thisClient; + + for( i = 0 ; i < listClient->count; i++) + { + thisClient = (client_t *) listClient->list[i]; + eventClientBuffer(thisClient); + } +} + +void selectServerTcpSocket() +{ + fd_set readfds; + struct timeval tv; + client_t *thisClient; + int max_fd; + int i; + + tv.tv_sec = 0; + tv.tv_usec = 0; + + FD_ZERO(&readfds); + FD_SET(sock_server_tcp->sock, &readfds); + max_fd = sock_server_tcp->sock; + + for( i = 0 ; i < listClient->count; i++) + { + thisClient = (client_t *) listClient->list[i]; + + FD_SET(thisClient->socket_tcp->sock, &readfds); + + if( thisClient->socket_tcp->sock > max_fd ) + { + max_fd = thisClient->socket_tcp->sock; + } + } + + select(max_fd+1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &tv); + + if( FD_ISSET(sock_server_tcp->sock, &readfds) ) + { + eventCreateNewTcpClient(sock_server_tcp); + } + + for( i = 0 ; i < listClient->count; i++) + { + thisClient = (client_t *) listClient->list[i]; + + if( FD_ISSET(thisClient->socket_tcp->sock, &readfds) ) + { + eventClientTcpSelect(thisClient); + } + + if( thisClient->status == NET_STATUS_ZOMBIE ) + { + proto_send_deltux_server(thisClient); + delListItem(listClient, i, destroyClient); + } + } +} + +void quitTcpServer() +{ + destroyListItem(listClient, destroyClient); + closeTcpSocket(sock_server_tcp); + printf("quit port\n"); +} + + diff --git a/src/tcp.c b/src/tcp.c new file mode 100755 index 0000000..bcd7764 --- /dev/null +++ b/src/tcp.c @@ -0,0 +1,210 @@ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "tcp.h" + +#define BUFSIZE 1000 + +sock_tcp_t* newSockTcp() +{ + sock_tcp_t *new; + + new = malloc( sizeof(sock_tcp_t) ); + memset(new, 0, sizeof(sock_tcp_t)); + + return new; +} + +void destroySockTcp(sock_tcp_t *p) +{ + free(p); +} + +sock_tcp_t* bindTcpSocket(int port) +{ + sock_tcp_t *new; + int len; + + assert( port > 0 && port < 65535 ); + + new = newSockTcp(); + + new->sock = socket(AF_INET, SOCK_STREAM, 0); + + if( new->sock < 0 ) + { + fprintf(stderr, "Nemozem vytvorit sietovy socket\n"); + destroySockTcp(new); + return NULL; + } + + new->sockAddr.sin_family = AF_INET; + new->sockAddr.sin_addr.s_addr = htonl(INADDR_ANY); + new->sockAddr.sin_port = htons(port); + + len = sizeof(new->sockAddr); + + if ( bind(new->sock, (struct sockaddr *)&new->sockAddr, len) < 0 ) + { + fprintf(stderr, "Nemozem obsadit sietovy port %d\n", port); + destroySockTcp(new); + return NULL; + } + + listen(new->sock, 5); + + return new; +} + +sock_tcp_t* getTcpNewClient(sock_tcp_t *p) +{ + sock_tcp_t *new; + int client_len; + + assert( new->sock >= 0 ); + + new = newSockTcp(); + + client_len = sizeof(new->sockAddr); + + new->sock = accept(p->sock, (struct sockaddr *)&new->sockAddr, + (socklen_t *)&client_len); + + return new; +} + +void getSockTcpIp(sock_tcp_t *p, char *str_ip) +{ + strcpy(str_ip, inet_ntoa(p->sockAddr.sin_addr)); +} + +sock_tcp_t* connectTcpSocket(char *ip, int port) +{ + sock_tcp_t *new; + int len; + + assert( port > 0 && port < 65535 ); + + new = newSockTcp(); + + new->sock = socket(AF_INET, SOCK_STREAM, 0); + + if( new->sock < 0 ) + { + fprintf(stderr, "Nemozem vytvorit sietovy socket\n"); + destroySockTcp(new); + return NULL; + } + + new->sockAddr.sin_family = AF_INET; + new->sockAddr.sin_addr.s_addr = inet_addr(ip); + new->sockAddr.sin_port = htons(port); + + len = sizeof(new->sockAddr); + + if ( connect(new->sock, (struct sockaddr *)&new->sockAddr, len) < 0 ) + { + fprintf(stderr, "Nemozem sa pripojit na %s %d\n", ip, port); + destroySockTcp(new); + return NULL; + } + + return new; +} + +int readTcpSocket(sock_tcp_t *p, void *address, int len) +{ + return read(p->sock, address, len); +} + +int writeTcpSocket(sock_tcp_t *p, void *address, int len) +{ + return write(p->sock, address, len); +} + +void closeTcpSocket(sock_tcp_t *p) +{ + close(p->sock); + destroySockTcp(p); +} + +static int myWait(sock_tcp_t *p) +{ + fd_set readfds; + fd_set errorfds; + struct timeval tv; + int max_fd; + + tv.tv_sec = 1; + tv.tv_usec = 0; + + FD_ZERO(&readfds); + FD_ZERO(&errorfds); + max_fd = p->sock; + + FD_SET(p->sock, &readfds); + FD_SET(p->sock, &errorfds); + + select(max_fd+1, &readfds, (fd_set *)0, &errorfds, &tv); + + if( FD_ISSET(p->sock, &readfds) ) + { + FD_CLR(p->sock, &readfds); + return 1; + } + + return 0; +} + +int test_tcp_main(int argc, char **argv) +{ + sock_tcp_t *sock; + char buf[BUFSIZE]; + int ret; + + if( strcmp(argv[1], "s") == 0 ) + { + sock_tcp_t *cli; + + sock = bindTcpSocket( atoi(argv[2]) ); + + while(1) + { + while( myWait(sock) == 0 ) + ; + + cli = getTcpNewClient(sock); + + memset(buf, 0, BUFSIZE); + ret = readTcpSocket(cli, buf, BUFSIZE); + writeTcpSocket(cli, buf, ret); + + closeTcpSocket(cli); + } + } + + if( strcmp(argv[1], "c") == 0 ) + { + sock = connectTcpSocket("127.0.0.1", atoi(argv[2])); + + strcpy(buf, "Hello world !\n"); + writeTcpSocket(sock, buf, strlen(buf)); + + memset(buf, 0, BUFSIZE); + readTcpSocket(sock, buf, BUFSIZE); + + printf("buf = %s", buf); + + closeTcpSocket(sock); + } +} diff --git a/src/tux.c b/src/tux.c index 2f8c6fc..a39c3d2 100644 --- a/src/tux.c +++ b/src/tux.c @@ -20,6 +20,7 @@ #include "myTimer.h" #include "net_multiplayer.h" #include "dynamicInt.h" +#include "proto.h" static SDL_Surface *g_tux_up; static SDL_Surface *g_tux_right; diff --git a/src/udp.c b/src/udp.c new file mode 100644 index 0000000..72a7448 --- /dev/null +++ b/src/udp.c @@ -0,0 +1,198 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFSIZE 1000 + +typedef struct struct_sock_udp_t +{ + int sock; + struct sockaddr_in sockAddr; +} sock_udp_t; + +sock_udp_t* newSockUdp() +{ + sock_udp_t *new; + + new = malloc( sizeof(sock_udp_t) ); + memset(new, 0, sizeof(sock_udp_t)); + + return new; +} + +void destroySockUdp(sock_udp_t *p) +{ + free(p); +} + +sock_udp_t* bindUdpSocket(int port) +{ + sock_udp_t *new; + + new = newSockUdp(); + + if( ( new->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) ) < 0 ) + { + fprintf(stderr, "nemozem obsadit sokcet !\n"); + destroySockUdp(new); + return NULL; + } + + new->sockAddr.sin_family = AF_INET; + new->sockAddr.sin_port = htons(port); + new->sockAddr.sin_addr.s_addr = INADDR_ANY; + + if( bind(new->sock, (struct sockaddr *)&(new->sockAddr), sizeof(new->sockAddr)) < 0 ) + { + fprintf(stderr, "nemozem nastavit sokcet !\n"); + destroySockUdp(new); + return NULL; + } + + + return new; +} + +sock_udp_t* connectUdpSocket(char *address, int port) +{ + struct hostent *host; + sock_udp_t *new; + + new = newSockUdp(); + + if( ( new->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) ) < 0 ) + { + fprintf(stderr, "nemozem sa pripojit na sokcet !\n"); + destroySockUdp(new); + return NULL; + } + + host = gethostbyname(address); + new->sockAddr.sin_family = AF_INET; + new->sockAddr.sin_port = htons(port); + memcpy(&(new->sockAddr.sin_addr), host->h_addr, host->h_length); + + return new; +} + +int readUdpSocket(sock_udp_t *src, sock_udp_t *dst, void *address, int len) +{ + int addrlen; + int size; + + addrlen = sizeof(src->sockAddr); + + if( ( size = recvfrom(src->sock, address, len, 0, + (struct sockaddr *)&dst->sockAddr, (socklen_t *)&addrlen) ) < 0 ) + { + fprintf(stderr, "nemozem nacitat sokcet !\n"); + return -1; + } + + return size; +} + +int writeUdpSocket(sock_udp_t *src, sock_udp_t *dst, void *address, int len) +{ + int addrlen; + int size; + + addrlen = sizeof(src->sockAddr); + + if( ( size = sendto(src->sock, address, len, 0, + (struct sockaddr *)&dst->sockAddr, (socklen_t)addrlen) ) < 0 ) + { + fprintf(stderr, "nemozem nacitat sokcet !\n"); + return -1; + } + + return size; +} + +void getSockUdpIp(sock_udp_t *p, char *str_ip) +{ + strcpy(str_ip, inet_ntoa(p->sockAddr.sin_addr)); +} + +void closeUdpSocket(sock_udp_t *p) +{ + close(p->sock); + destroySockUdp(p); +} + +static int myWait(sock_udp_t *p) +{ + fd_set readfds; + fd_set errorfds; + struct timeval tv; + int max_fd; + + tv.tv_sec = 1; + tv.tv_usec = 0; + + FD_ZERO(&readfds); + FD_ZERO(&errorfds); + max_fd = p->sock; + + FD_SET(p->sock, &readfds); + FD_SET(p->sock, &errorfds); + + select(max_fd+1, &readfds, (fd_set *)0, &errorfds, &tv); + + if( FD_ISSET(p->sock, &readfds) ) + { + FD_CLR(p->sock, &readfds); + return 1; + } + + return 0; +} + +int test_udp_main(int argc, char *argv[]) +{ + sock_udp_t *sock; + char buf[BUFSIZE]; + int ret; + + if( strcmp(argv[1], "s") == 0 ) + { + sock_udp_t *cli; + + sock = bindUdpSocket( atoi(argv[2]) ); + cli = newSockUdp(); + + while(1) + { + while( myWait(sock) == 0 ) + ; + + memset(buf, 0, BUFSIZE); + ret = readUdpSocket(sock, cli, buf, BUFSIZE); + writeUdpSocket(sock, cli, buf, ret); + } + } + + if( strcmp(argv[1], "c") == 0 ) + { + sock = connectUdpSocket("127.0.0.1", atoi(argv[2])); + + strcpy(buf, "Hello world !\n"); + writeUdpSocket(sock, sock, buf, strlen(buf)); + + memset(buf, 0, BUFSIZE); + readUdpSocket(sock, sock, buf, BUFSIZE); + + printf("buf = %s", buf); + + closeUdpSocket(sock); + } + + return 0; +} -- cgit v1.2.3