#include // Affichages #include // Struct in_addr et sockaddr_in #include // Sprintf #include "sock.h" // Socket #include "sockdist.h" // Socket distante #include #include // Select #include // Select #include "position.h" #include #include "tir.h" // Pour les coups joués // ===== Variables ===== int nb_joueurs = 0; // On gère 10 joueurs maxi. bool demarrage = false; int joueur_desc[10]; // Tableau des N° de BR Joueurs char joueur_nom[10][256]; // Tableau des NOM de Joueurs Tir* joueur_coup[10]; // Tableau des coups joués dans le tour char coups[10][256]; // Chaine de caractere des coups joués char saisie[256]; int joueur_etat[10]; /* Tableau des etat des joueurs 0 -> nouveau 1 -> Pret 2 -> Le joueur a joué son coup 3 -> Le joueur envoit des coordonnées de sa grille */ int joueur_demande[10]; // A qui le joueur envoit sa grille int compteur_jeu = 0; //Compte le nbre de joueur qui a joué // Gestion des communications int accepte; int desc; int ecoute; int reception; int envoie; fd_set table; fd_set erreurs; int appel; // Données échangées int typercv; /* Signal de réception 1 -> Signal du début de partie 2 -> Le joueur est pret 3 -> Le joueur joue un coup 4 -> Client chat 5 -> Demade Grille 6 -> Fin transfert grille 7 -> Coup joué */ int typeenv; /* Type d'envoi 1 -> Joueur accepté 2 -> Joueur refusé 3 -> Le joueur est accepté et doit donner le signal de départ 4 -> Début de la partie 5 -> Début du jeu quand tous les joueurs sont prets 6 -> Envoi d'une grille 7 -> Envoi tous les résultats 8 -> Liste des joueurs 9 -> Message chat 10-> Demande de grille 11-> Coup joué */ char msgenv[256]; char msgrcv[256]; int joueur = 0; int colonne = 0; int ligne = 0; ///////////////////////////////////// ////// METHODES ///////// ///////////////////////////////////// /* Affichage */ void Affiche(char* t){cout << t << endl;} ///////////////////////////////////// ////// JOUEURS ///////// ///////////////////////////////////// /* liste_joueurs */ void ListeJoueurs(int i){ //Envoi la liste des joueurs au joueur i typeenv = 8; send(joueur_desc[i],&typeenv,sizeof(typeenv),0); send(joueur_desc[i],&nb_joueurs,sizeof(nb_joueurs),0);// -1- Envoi le nombre de joueurs for (int j = 0; j < nb_joueurs; j++){// -2- Envoi la liste des joueurs send(joueur_desc[i],&joueur_nom[j], sizeof(joueur_nom[j]), 0); } } ///////////////////////////////////// ////// SERVEUR ///////// ///////////////////////////////////// /* Ferme Serveur */ void FermeServeur(char * t){ Affiche(t); close(desc); for (int i = 0; i < nb_joueurs; i++){close(joueur_desc[i]);}//-1- ferme toutes les connections exit(0);//-2- termine le processus } /* Termine(joueur)*/ void termine(int i, char* t){ Affiche(t); close(joueur_desc[i]); // -1- ferme la connection avec le joueur i for (int j = i; j < nb_joueurs; j++){ // -2-supprime les données de ce joueur dans les infos stockées joueur_nom[j] = joueur_nom[j+1]; joueur_desc[j] = joueur_desc[j+1]; joueur_etat[j] = joueur_desc[j+1]; } nb_joueurs --; if (nb_joueurs == 0) demarrage=false; // Aceppte de nouvelles connections else { for (int i = 0; i < nb_joueurs; i++){ListeJoueurs(i);}} // nouvelle liste de joueurs } ///////////////////////////////////// ////// CHAT ///////// ///////////////////////////////////// /* RecoitChat() */ void RecoitChat(int i){ if(recv(joueur_desc[i], &typercv, sizeof(typercv),0)<=0){ // -1- Recoit le destinataire du message. termine(i, " Erreur de réception."); } if(recv(joueur_desc[i], &msgrcv, sizeof(msgrcv), 0)<=0){// -2-Recoit le message termine(i, " Erreur de réception."); } } /* EnvoieChat() */ void EnvoieChat(int src, int dst, char* msg){ char buf[256]; if (src == -1) {sprintf(buf, " %s", msg);} //Coup joué else{sprintf(buf, " %s > %s", joueur_nom[src], msg);} // Création message chat typeenv = 9; if (dst == nb_joueurs){ // Envoi à tous for (int i = 0; i < nb_joueurs; i++){ send(joueur_desc[i],&typeenv,sizeof(typeenv),0); // On prévient send(joueur_desc[i],&buf,sizeof(buf),0); // Message } } else { send(joueur_desc[dst],&typeenv,sizeof(typeenv),0); // On prévient send(joueur_desc[dst],&buf,sizeof(buf),0); // Message } } ///////////////////////////////////// ////// JEU ///////// ///////////////////////////////////// /* Depart */ void depart(){ for (int i = 0; i < nb_joueurs; i++){// -2-Envoi Signal départ + la liste des joueurs ListeJoueurs(i); typeenv = 4; // -1- Demande à tous les joueurs de placer les bateaux send(joueur_desc[i],&typeenv,sizeof(typeenv),0); } Affiche(" Début de la partie..."); demarrage = true; //On indique que le départ a été donné = plus de nouvelle BR privée autorisée compteur_jeu = 0; } /* Joueur_pret(int) */ void JoueurPret(int j){ joueur_etat[j] = 1; int pret = 0; for (int i = 0; i < nb_joueurs; i++){if (joueur_etat[i] == 1) pret ++;} if (pret == nb_joueurs){ // Tous les joueurs sont prets -> début du jeu typeenv = 5; for (int i = 0; i < nb_joueurs; i++){send(joueur_desc[i],&typeenv,sizeof(typeenv),0);} } } /* NouveauJoueur() */ void NouveauJoueur(){ // -1- Accepte une connection sockaddr_in adCV; socklen_t tailleCV = sizeof(adCV); // -2- Créé une BR privée accepte = accept(desc,(sockaddr*)&adCV, &tailleCV); if (accepte == -1){FermeServeur(" Erreur de connection ");} // -3- Recoit le nom du joueur if (recv(accepte, &msgrcv, sizeof(msgrcv), 0) == -1) { FermeServeur(" Erreur de réception ..."); } else { if (demarrage){ // Le joueur est refusé typeenv = 2; // Connection refusée if(send(accepte, &typeenv, sizeof(typeenv), 0)==-1) { termine(nb_joueurs-1," Erreur d'envoi ... "); } } else { // Le joueur est accepté // Sauvegarde des infos joueur joueur_nom[nb_joueurs] = msgrcv; joueur_desc[nb_joueurs] = accepte; joueur_etat[nb_joueurs] = 0; nb_joueurs ++; // Joueur accepté typeenv = 1; if(send(accepte, &typeenv, sizeof(typeenv), 0)==-1) { termine(nb_joueurs-1," Erreur d'envoi ... "); } // Numéro du joueur typeenv = nb_joueurs-1; if(send(accepte, &typeenv, sizeof(typeenv), 0)==-1) { termine(nb_joueurs-1," Erreur d'envoi ... "); } // Signal spécial au premier joueur (taper 'start') if (nb_joueurs == 1) { typeenv = 3; if(send(accepte, &typeenv, sizeof(typeenv), 0)==-1) { termine(nb_joueurs-1," Erreur d'envoi ... "); } } } } // -5- Envoi de la liste des joueurs à tous les joueurs if (!demarrage){ for (int i = 0; i < nb_joueurs; i++){ ListeJoueurs(i); } } } /* Fin du tour de jeu */ void FinTour(){ compteur_jeu = 0; for (int i = 0; i < nb_joueurs; i++){ for (int j = 0; j < nb_joueurs; j++){ EnvoieChat(-1, i, coups[j]); } typeenv = 12; if(send(joueur_desc[i], &typeenv, sizeof(typeenv), 0)==-1) { termine(i," Erreur d'envoi ... "); } } } ///////////////////////////////////// ////// GRILLE ///////// ///////////////////////////////////// /* Demande La Grille */ void DemandeGrille(int src){ int dest; if (recv(joueur_desc[src], &dest, sizeof(dest), 0) == -1) { //numero du joueur demandé FermeServeur(" Erreur de réception ..."); } typeenv = 10; if(send(joueur_desc[dest], &typeenv, sizeof(typeenv), 0)==-1) {// requete au joueur demandé termine(nb_joueurs-1," Erreur d'envoi ... "); } typeenv = src; if(send(joueur_desc[dest], &typeenv, sizeof(typeenv), 0)==-1) { // Numéro du demandeur termine(nb_joueurs-1," Erreur d'envoi ... "); } } /* Transfert de la grille */ void Transmet(int src){ int dest; if (recv(joueur_desc[src], &dest, sizeof(dest), 0) == -1) {// numéro du joueur cible termine(src," Erreur de réception ..."); } char grille[1000]; if (recv(joueur_desc[src], &grille, sizeof(grille), 0) == -1) {// grille termine(src," Erreur de réception ..."); } if(send(joueur_desc[dest], &grille, strlen(grille)+2, 0)==-1) { // Transfert termine(dest," Erreur d'envoi ... "); } } ///////////////////////////////////// ////// COUPS ///////// ///////////////////////////////////// /* TransmetCoup */ void TransmetCoup(int i){ int dest; char position[256]; //Reçoit le coup if (recv(joueur_desc[i], &dest, sizeof(dest), 0) == -1) {termine(i," Erreur de réception ...");} // joueur destination if (recv(joueur_desc[i], &position, sizeof(position), 0) == -1) {termine(i," Erreur de réception ...");} // coup joué //Gère la liste des coups joués sprintf(coups[i]," %s sur %s -> ",position, joueur_nom[dest]); compteur_jeu++; //Envoie le coup typeenv = 11; if(send(joueur_desc[dest], &typeenv, sizeof(typeenv), 0)==-1) {termine(i," Erreur d'envoi ... ");} //Envoit le coup if(send(joueur_desc[dest], &position, sizeof(position), 0)==-1) {termine(i," Erreur d'envoi ... ");} //Envoit le coup //Reçoit la réponse char rep[2]; if (recv(joueur_desc[dest], &rep, sizeof(rep), 0) == -1) {termine(i," Erreur de réception ...");} // coup joué //Gère la liste des coups joués strcat(coups[i], rep); //Gère le tour de jeu if (compteur_jeu == nb_joueurs){ FinTour(); } } ///////////////////////////////////// ////// PRINCIPAL ///////// ///////////////////////////////////// main() { // ===== Init ===== for (int i = 0; i < 10; i++){ joueur_demande[i] = 0; } // ===== création boite serveur ===== Sock BRServeur (SOCK_STREAM,short(14415)); desc = BRServeur.getsDesc(); // ===== écoute de la boite serveur ===== ecoute = listen(desc,10); if (ecoute==-1) {cout<<" Impossible de créer la file d'attente..."<> saisie; if (strcmp(saisie,"stop")==0){FermeServeur(" Le serveur ferme...");} } // Test interruption BR privées else{ if (FD_ISSET(desc, &table)){NouveauJoueur();} //Port public else { // Ports privés int i = 0; while((!FD_ISSET(joueur_desc[i], &table))&&(i < nb_joueurs)){i++;} // Gestion normale if(recv(joueur_desc[i], &typercv, sizeof(typercv), 0)<=0){ // Type du message char p[100]; sprintf(p," Déconnection : %s", joueur_nom[i]); termine(i, p); } else{ switch(typercv){ case 1: { // Signale le début de la partie depart(); break; } case 2: { // Le joueur est pret JoueurPret(i); break; } case 3: { // Le joueur joue un coup Affiche(" Ya quelqu'un qui m'a parlé"); break; } case 4: { // Le joueur envoi un message RecoitChat(i); EnvoieChat(i, typercv, msgrcv); break; } case 5: { // Le joueur demande une grille DemandeGrille(i); break; } case 6: { // Le joueur envoit la grille Transmet(i); break; } case 7: { // Le joueur envoie un coup TransmetCoup(i); break; } case 8: { // Le joueur est mort sprintf(msgrcv,"Je suis mort(e), noyé(e), abandonné(e) de tous.\nAdieu bande de pirates!\nAAAAARRRRRGGGGGHHHHH!!!!!"); EnvoieChat(i,nb_joueurs,msgrcv); break; } } } } } } } close(accepte); }