Commit 91f134c0 authored by s.schuler's avatar s.schuler
Browse files

server&client

parent bc1c1daa
#include "client.h"
int player_index = -1;
int max_x = 0;
int max_y = 0;
int main(){
initscr();
timeout(10);
noecho();
cbreak();
start_color();
init_pair(0, COLOR_WHITE, COLOR_RED);
init_pair(1, COLOR_BLACK, COLOR_BLUE);
init_pair(2, COLOR_BLACK, COLOR_YELLOW);
init_pair(3, COLOR_BLACK, COLOR_MAGENTA);
init_pair(4, COLOR_BLACK, COLOR_CYAN);
init_pair(5, COLOR_BLACK, COLOR_GREEN);
init_pair(6, COLOR_BLACK, COLOR_WHITE);
// Couleur bordure + nourriture
init_pair(COLOR_FOOD, COLOR_BLACK,COLOR_GREEN);
init_pair(COLOR_BORDER, COLOR_BLACK, COLOR_WHITE);
curs_set(0); // rend le curseur invisible
FILE *fp;
char send_buff[16];
char logfile[64];
char buff[BUFFER_LEN];
char cmd[BUFFER_LEN];
int sockfd, connfd;
struct sockaddr_in servaddr, cli;
char die_msg[BUFFER_LEN];
int len;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
endwin();
printf("socket creation failed...\n");
exit(0);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);
if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) {
endwin();
printf("connection with the server failed...\n");
exit(0);
}
fp = popen("whoami", "r");
while ( fgets( buff, BUFFER_LEN, fp))
{
write(sockfd,strtok(buff, "\n"),BUFFER_LEN);
}
pclose(fp);
read(sockfd,buff, sizeof(buff));
int opt = 1;
setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(1));
sscanf(buff,"%d/%d/%d",&max_x,&max_y,&player_index);
sprintf(logfile,"client%d.log",player_index);
sprintf(cmd," > %s",logfile);//vide le ficher des archives du client
system(cmd);
keypad(stdscr, TRUE);
sprintf(cmd,"echo 'SERVER map size (%d ; %d)' >> %s"
,max_x,max_y,logfile);
system(cmd);
char ON = 1;
char c = 0;
while(ON){
c = getch();
if (c != -1) {
sprintf(send_buff,"D%dD",c);
//sprintf(cmd,"echo 'SENDING.%s. WITH LEN OF %d' >> client.log",buff,strlen(buff));
//system(cmd);
send(sockfd,send_buff,16,0);
}
bzero(buff,BUFFER_LEN);
len = recv(sockfd, buff, BUFFER_LEN, MSG_DONTWAIT);
//sprintf(cmd,"echo '__RECV__.%s. WITH LEN OF %d' >> %s",buff,strlen(buff),logfile);
//system(cmd);
if(strncmp(buff,"UDIE",4) == 0){
ON = 0;
sscanf(buff,"UDIE%s",die_msg);
break;
}if(len>1){
new_frame(buff);
move(max_y,0);
refresh();
//printw("getch() = %d = %c", c,c);
}
//usleep(SLEEP_TIME);
}
mvprintw(5,5,"!! TU ES MORT !!");
mvprintw(6,5,"!! %s !!",die_msg);
refresh();
usleep(2000000);
getchar();
endwin();
close(sockfd);//close socket
}
#ifdef WIN32 /* si vous êtes sous Windows */
#include <winsock2.h>
#elif defined (linux) /* si vous êtes sous Linux */
#include <curses.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> /* close */
#include <netdb.h> /* gethostbyname */
#define PORT 6488
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
typedef struct in_addr IN_ADDR;
#define SA struct sockaddr
#else /* sinon vous êtes sur une plateforme non supportée */
#error not defined for this platform
#endif
#define COLOR_BORDER 10
#define COLOR_FOOD 11
#define BUFFER_LEN 4096
#define SLEEP_TIME 10000
typedef struct position { // position (x,y) sur la console
int x;
int y;
} pos;
#include "display.h"
#include "client.h"
void new_frame(char * data){
int maxXsize=0, maxYsize=0;
getmaxyx(stdscr,maxYsize,maxXsize); // renvoie la taille de la console dans maxX et maxY
maxXsize/=2;maxXsize-=2;maxYsize-=5; // ajustation de la taille
clear();
//printw("NEW _ FRAME ( %s )\n",data);
//refresh();
char logname_array[10][64] = {0};
int body_index;
int nb_player=0;
pos player_head;
pos head;
char color;
pos food;
char logname[64];
char cmd[BUFFER_LEN];
char foods[BUFFER_LEN];
char body_array[BUFFER_LEN];
char body[BUFFER_LEN];
char body_buff[BUFFER_LEN];
char buff[BUFFER_LEN];
bzero(foods,sizeof(foods));
bzero(body,sizeof(body));
bzero(body_array,sizeof(body_array));
bzero(buff,sizeof(buff));
sscanf(data,"%s %s",body_array,foods);
//printw("foods :%s\n",foods);
//printw("bod array :%s\n",body_array);
attron(COLOR_PAIR(COLOR_BORDER));
for (int y = 0; y <= max_y; y++) {
for (int x = 0; x <= max_x; x++) {
if(x==0||y==0||x>=max_x||y>=max_y){
mvprintw(y,x*2,"##");
}
}
}
attroff(COLOR_PAIR(COLOR_BORDER));
do {
bzero(buff,sizeof(buff));
sscanf(body_array,"B%d@%[^@]@%[^B]B%s",&color,logname,body,buff);
strcpy(logname_array[color],logname);
/*printw("\n\tcolor:%d\n",color);
printw("logname:x%sx\n",logname);
printw("body:%s\n",body);
printw("%s buff:%d\n",buff,strlen(buff));
refresh();*/
body_index=0;
attron(COLOR_PAIR(color) | (color == player_index ? A_STANDOUT : 0));
do {
bzero(body_buff,sizeof(body_buff));
sscanf(body,"(%d;%d)%s",&head.x,&head.y,body_buff);
if(body_index==0 && color==player_index){
player_head.x=head.x;
player_head.y=head.y;
}
/*sprintf(cmd,"echo 'head(%d,%d)' >> client.log",head.x,head.y);
system(cmd);
sprintf(cmd,"echo '%s body_buff:%d' >> client.log",body_buff,strlen(body_buff));
system(cmd);*/
mvprintw(head.y,head.x*2,"<>");
strcpy(body,body_buff);
body_index++;
} while(strlen(body) > 3);
attroff(COLOR_PAIR(color) | (color == player_index ? A_STANDOUT : 0));
strcpy(body_array,buff);
//sprintf(cmd,"echo '%s body_array:%d' >> client.log",body_array,strlen(body_array));
//system(cmd);
//printw("body:%s body_array:%s\n",body,body_array);
//printw("head(%d,%d)\n",head.x,head.y);
} while(strlen(body_array) > 3);
attron(COLOR_PAIR(COLOR_FOOD) | A_BLINK | A_REVERSE); // affiche la nourritue
do {
bzero(buff,sizeof(buff));
sscanf(foods,"(%d;%d)%s",&food.x,&food.y,buff);
//printw(" food @ %d %d\n",food.x,food.y);
mvprintw(food.y,food.x*2,"**");
strcpy(foods,buff);
//printw("%d foods= [%s] strlen(foods)=%d\n",i,foods,strlen(foods));
} while(strlen(buff) > 3);
attroff(COLOR_PAIR(COLOR_FOOD) | A_BLINK | A_REVERSE);
move(max_y+1,1);
for(int i = 0;i<10;i++){
attron(COLOR_PAIR(i));
printw(" %s ",logname_array[i]);
attroff(COLOR_PAIR(i));
}
}
extern int player_index;
extern int max_x;
extern int max_y;
void new_frame(char * data);
#include "server.h"
//char body_map[MAX_X][MAX_Y] = {0};
char * body_map[MAX_X] ; // liste 2d de bool
pos foods[NB_FOOD];
pos * body_array[NB_CLIENTS]; // stock les corps des serpents
int sizes[NB_CLIENTS]; // liste des tailles de serpents
void initGame(){
pos p;
for(int i = 0;i < MAX_X;i++){
body_map[i] = calloc(MAX_Y,sizeof(char));
}
for(int i = 0;i < NB_CLIENTS;i++){
body_array[i] = calloc(BODY_LEN,sizeof(pos));
}
for(int i = 0;i<NB_FOOD;i++){
p = (pos){1+get_random(MAX_X-2),1+get_random(MAX_Y-2)};
foods[i] = p;
}
}
// cree un message de la map actuelle;
void makeMap(char * map){
int index = frame%BODY_LEN;
pos position;
char buff[BUFFER_LEN];
char body[BUFFER_LEN];
char body_buff[BUFFER_LEN];
char body_lst[BUFFER_LEN];
char foods_array[BUFFER_LEN];
pos * bodyptr;
bzero(buff,sizeof(buff));
bzero(body_lst,sizeof(body_lst));
bzero(body,sizeof(body_lst));
bzero(body_buff,sizeof(body_buff));
bzero(foods_array,sizeof(foods_array));
for (int i = 0; i < NB_CLIENTS; i++) { // cree body_lst
if(clients[i] == -1){
continue;
}
bzero(body_buff,sizeof(body_buff));
bodyptr = body_array[i];
for (int s = 0;s < sizes[i];s++ ) { // ajoute successivement les positions du corps dans body_buff
position = bodyptr[(index-s+BODY_LEN)%BODY_LEN];
sprintf(body,"(%d;%d)%s",
position.x,
position.y,body_buff);
strcpy(body_buff,body);
}
position.x = bodyptr[(index-sizes[i]+BODY_LEN)%BODY_LEN].x;
position.y = bodyptr[(index-sizes[i]+BODY_LEN)%BODY_LEN].y;
body_map[position.x][position.y] = 0;
sprintf(body,"B%d@%s@%sB",i+1,logname_array[i],body_buff);
strcat(body_lst,body);
}
for(int i = 0 ; i < NB_FOOD ; i++){ //cree la liste de nourriture
sprintf(foods_array,"%s(%d;%d)",foods_array,foods[i].x,foods[i].y);
}
sprintf(map,"%s %s",body_lst,foods_array);
}
void update(){ // produit une nouvelle frame
/*for(int y = 0;y<MAX_Y;y++){
for(int x = 0;x<MAX_X;x++){
printf("%d",body_map[x][y]);
}
printf("\n");
}*/
printf("-----------\n");
pos d;
pos head;
pos * bodyn;
char buff[BUFFER_LEN];
int index = frame % BODY_LEN;
for(int i = 0 ; i < NB_CLIENTS;i++){
if(clients[i] == -1){
continue;
}
bodyn = body_array[i];
head.y = bodyn[index].y;
head.x = bodyn[index].x;
body_map[head.x][head.y]=i+1;//indique la presence du corp
d.x=dirs[i].x; // dirs[i] est une variable extern qui est modifier par le thread manageClient
d.y=dirs[i].y;
//printf("%s PLAYER INFO %d#\n",logname_array[i],i);
//printf("head(%d, %d) dir(%d,%d) frame %d\n",head.x,head.y,d.x,d.y,frame);
head.x+=d.x;
head.y+=d.y;
if (head.x == MAX_X || head.y == MAX_Y || head.x == 0 || head.y == 0){
printf("%s EST MORT DANS LE MUR @ %d;%d \n",
logname_array[i],head.x,head.y);
has_die(i,"UDIE|Tu_es_sorti_des_bordures_de_la_catre|");
}
else if(body_map[head.x][head.y] && (d.x != 0 || d.y != 0)) {
sprintf(buff,"UDIE|Tu_es_rentre_dans_%s|",logname_array[body_map[head.x][head.y]-1]);
printf("%s EST MORT @ %d;%d \n",
logname_array[i],head.x,head.y);
printf("a cause d'un body ? %d\n", body_map[head.x][head.y]);
has_die(i,buff);
}
bodyn[(index+1)%BODY_LEN].x = head.x;
bodyn[(index+1)%BODY_LEN].y = head.y;
for(int f = 0 ; f < NB_FOOD;f++){
if(foods[f].x==head.x && foods[f].y==head.y){
printf("Joueur %s mange @ %d;%d\n",logname_array[i],head.x,head.y);
sizes[i]++;
foods[f]=(pos){1+get_random(MAX_X-1),1+get_random(MAX_Y-1)};
}
}
}
}
void player_join(int player_index){
int index = frame % BODY_LEN;
pos p = {1+get_random(MAX_X-1),1+get_random(MAX_Y-1)};
sizes[player_index] = 1;
body_array[player_index][index] = p;
dirs[player_index] = (pos){0,0};
printf("%s JOINING at (%d,%d) IN FRAME %d\n",logname_array[player_index],p.x,p.y,frame);
}
void has_die(int player_index,char * die_msg){
pos p;
int index = frame % BODY_LEN;
for (int s = 0;s <= sizes[player_index];s++ ) { // ajoute successivement les positions du corps dans body_buff
p = body_array[player_index][(index-s+BODY_LEN)%BODY_LEN];
body_map[p.x][p.y]=0;
}
send(clients[player_index],die_msg,BUFFER_LEN,0);
clients[player_index] = -1;
}
int get_random (int max){
double val;
val = (double) max * rand ();
val = val / (RAND_MAX + 1.0);
return ((int) val);
}
void initGame();
void update();
void makeMap(char * map);
void player_join(int player_index);
void has_die(int player_index,char * die_msg);
int get_random (int max);
extern int frame;
extern pos dirs[NB_CLIENTS];
extern int clients[NB_CLIENTS];
extern char *logname_array[NB_CLIENTS];
#include "server.h"
#include <pthread.h>
int frame = 0;
pos head;
pos dirs[NB_CLIENTS]; //direction des clients
char *logname_array[NB_CLIENTS]; //nom d'utilisateur
char rcv_ON = 1;
int clients[NB_CLIENTS]; //socket des clients
int main(void) {
srand(time(NULL));
pthread_t thread_recvDir;
char buff[BUFFER_LEN];
char map[BUFFER_LEN];
int i_p; // index du joueur;
initGame();
for(int i = 0;i < NB_CLIENTS;i++){
//logname_array[i] = malloc(sizeof(char)*64);
logname_array[i] = calloc(1,sizeof(char)*64);
}
for (int i = 0; i < NB_CLIENTS; i++) {
clients[i] = -1;
}
// Structure contenant l'adresse
struct sockaddr_in adresse;
adresse.sin_family = AF_INET;
adresse.sin_addr.s_addr = IP;
adresse.sin_port = htons( PORT);
// Descripteur de la socket du serveur
int serverSocket = initSocket(&adresse);
int clientSocket;
int index;
pthread_create(&thread_recvDir, NULL, manageClient, NULL);
while (1) {
update();
//printf("frame%d\n",frame);
bzero(map, sizeof(map));
makeMap(map);
printf("SENDING @ : %s strlen(%d) , sizeof(%d)\n",map,strlen(map),sizeof(map));
for (int i = 0; i < NB_CLIENTS; i++) { // envoi la map a tout les clients connecter
if(clients[i] == -1){continue;}
write(clients[i],map,sizeof(map));
}
// Descripteur de la socket du client, on attend une connexion
frame++;
if ((clientSocket = waitForClient(&serverSocket)) != -1) {
rcv_ON = 0;
pthread_join(thread_recvDir,NULL);
// On ajoute le nouveau client au tableau des descripteurs
i_p = addClientToTab(clientSocket, clients);
player_join(i_p);
sprintf(buff,"%d/%d/%d",MAX_X,MAX_Y,i_p+1);
send(clientSocket,buff,BUFFER_LEN,0);
recv(clientSocket,buff,BUFFER_LEN,0);
strcpy(logname_array[i_p],buff);
printf(".%s. JOIN THE GAME\n",logname_array[i_p]);
rcv_ON = 1;
pthread_create(&thread_recvDir, NULL, manageClient, NULL);
}
usleep(SLEEP_TIME);
}
return EXIT_SUCCESS;
}
///////////////////////
// On traite l'input des clients
void *manageClient(){
// Création d'un tampon pour stocker les messages des clients dans la heap
char buffer[BUFFER_LEN];
char c = 0;
pos d;
while (rcv_ON) {
for (int i = 0; i < NB_CLIENTS; i++) {
// On vérifie les messages
int clientSocket = clients[i];
if (clientSocket == -1) {
continue;
}
bzero(buffer, sizeof(buffer));
int len = recv(clientSocket, buffer, BUFFER_LEN, MSG_DONTWAIT);
//printf("ALIVE\n");
// Booléen pour suivre l'état de la socket
int isClosed = 0;
if (len == -1 && errno != EAGAIN) {
// Une erreur est survenue
printf("Errno [%i] : %s\n", errno, strerror(errno));
isClosed = 1;
} else if (len == 0) {
// Le client s'est déconnecté (extrémité de la socket fermée)
isClosed = 1;
} else if (len > 0) {
printf("recv %s, %d FROM %d[%s]\n",buffer,strlen(buffer),i,logname_array[i]);
sscanf(buffer,"D%dD",&c);
d = controles(c);
if (d.x == 0 && d.y == 0) {
} else {
dirs[i].x = d.x;
dirs[i].y = d.y;
printf("nouvelle direction de %s (%d;%d)\n",logname_array[i],d.x,d.y);
}
} else {
bzero(buffer,sizeof(buffer));
int len = recv(clientSocket, buffer, BUFFER_LEN, MSG_DONTWAIT);
}
//printf("(IS CLOSED = %d \n",isClosed);
if (isClosed == 1) {
// La socket est fermé ou le client veut quitter le serveur !
printf("Fermeture de la connexion avec le client\n");
// Fermeture de la socket
close(clientSocket);
// On fait de la place dans le tableau
clients[i] = -1;
}
usleep(RECV_TIME);
}
}
printf("Thread fini sans erreurs\n");
}
// Démarrage de la socket serveur
int initSocket(struct sockaddr_in * adresse) {
// Descripteur de socket
int fdsocket;
// Nombre d'options
int opt = 1;
// Création de la socket en TCP
if ((fdsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
printf("Echéc de la création: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
printf("Création de la socket\n");
// Paramètrage de la socket
if (setsockopt(fdsocket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt,
sizeof(opt)) != 0) {
printf("Echéc de paramètrage: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
printf("Paramètrage de la socket\n");
// Attachement de la socket sur le port et l'adresse IP
if (bind(fdsocket, (struct sockaddr *) adresse, sizeof(*adresse)) != 0) {
printf("Echéc d'attachement: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
printf("Attachement de la socket sur le port %i\n", PORT);
// Passage en écoute de la socket
if (listen(fdsocket, BACKLOG) != 0) {
printf("Echéc de la mise en écoute: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
// Passage en mode non bloquant
fcntl(fdsocket, F_SETFL, O_NONBLOCK);
printf("Mise en écoute de la socket\n");
return fdsocket;
}
// Attente de connexion d'un client
int waitForClient(int * serverSocket) {
int clientSocket;
// Structure contenant l'adresse du client
struct sockaddr_in clientAdresse;
int addrLen = sizeof(clientAdresse);
if ((clientSocket = accept(*serverSocket, (struct sockaddr*) &clientAdresse,
(socklen_t*) &addrLen)) != -1) {
// Convertion de l'IP en texte
char ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(clientAdresse.sin_addr), ip, INET_ADDRSTRLEN);
printf("Connexion de %s:%i\n", ip, clientAdresse.sin_port);
// Passage en mode non bloquant
int opt = 1;
setsockopt(clientSocket, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(1));
}
return clientSocket;
}
// Ajoute les clients au tableau
int addClientToTab(int clientSocket, int clients[]) {
// On vérifie si on à de la place de libre
int found = -1;
int i;
for (i = 0; i < NB_CLIENTS; i++) {
// On cherche de la place
if (clients[i] == -1) {