Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 34 additions & 32 deletions client/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,39 +363,41 @@ int main(int argc, char *argv[])
continue;
}

// Raccourci: si l'utilisateur tape juste un nombre 0..5, traiter comme PLAY/MOVE <nombre>
if (tk0 && !tk1) {
int numeric = 1;
for (const char* p = tk0; *p; ++p) {
if (!isdigit((unsigned char)*p)) { numeric = 0; break; }
}
if (numeric) {
if (!g_en_partie) {
printf("[CLIENT] Vous n'etes pas en partie. Ignorer entree numerique.\n");
} else {
int trou = atoi(tk0);
if (trou < 0 || trou >= NB_TROUS_CAMP) {
printf("[CLIENT] Trou invalide (0..5).\n");
} else if (g_partie.joueur_courant != g_role_local) {
printf("[CLIENT] Ce n'est pas votre tour.\n");
} else if (!awale_verifier_legalite(&g_partie, trou)) {
printf("[CLIENT] Coup illegal localement.\n");
} else if (!awale_jouer_coup(&g_partie, trou)) {
printf("[CLIENT] Echec lors de l'application locale du coup.\n");
} else {
printf("\n=== Votre coup joue localement (trou %d) ===\n", trou);
awale_afficher_plateau(&g_partie);

char out[32];
int len = snprintf(out, sizeof(out), "MOVE %d", trou);
nbytes = write(sockfd, out, len);
write(sockfd, "\n", 1);
if (nbytes < 0) erreur("Erreur ecriture socket (MOVE)");
// Raccourci: si l'utilisateur tape juste un nombre 0..5, traiter comme PLAY/MOVE <nombre>
if (tk0 && !tk1) {
int numeric = 1;
for (const char* p = tk0; *p; ++p) {
if (!isdigit((unsigned char)*p)) { numeric = 0; break; }
}
if (numeric) {
if (!g_en_partie) {
printf("[CLIENT] Vous n'etes pas en partie. Ignorer entree numerique.\n");
}
else {
int trou = atoi(tk0);
if (trou < 0 || trou >= NB_TROUS_CAMP) {
printf("[CLIENT] Trou invalide (0..5).\n");
} else if (g_partie.joueur_courant != g_role_local) {
printf("[CLIENT] Ce n'est pas votre tour.\n");
} else if (!awale_verifier_legalite(&g_partie, trou)) {
printf("[CLIENT] Coup illegal localement.\n");
} else if (!awale_jouer_coup(&g_partie, trou)) {
printf("[CLIENT] Echec lors de l'application locale du coup.\n");
} else {
printf("\n=== Votre coup joue localement (trou %d) ===\n", trou);
awale_afficher_plateau(&g_partie);

char out[32];
int len = snprintf(out, sizeof(out), "MOVE %d", trou);
nbytes = write(sockfd, out, len);
write(sockfd, "\n", 1);
if (nbytes < 0) erreur("Erreur ecriture socket (MOVE)");
}
}
continue;
}
}
}
continue;
}
}

// Envoi par défaut tel quel au serveur (DEFI, ACCEPT, REFUSE, QUIT, etc.)
int cmd_len = strlen(buffer);
nbytes = write(sockfd, buffer, cmd_len);
Expand Down
7 changes: 7 additions & 0 deletions server/chat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "events.h"
#include "matches.h"

void handle_message(int sock, int argc, char** argv, int pipe_write_to_p)
{

}
113 changes: 113 additions & 0 deletions server/defi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#include "events.h"

/*void handle_defi(int sock, int argc, char** argv, int pipe_write_to_p) {
// argv[0] = "DEFI", argv[1] = pseudo_local, argv[2] = adversaire
if (argc < 3) {
envoyer_message(sock, "ERREUR_PROTOCOLE Commande DEFI incomplete. Usage: DEFI <adversaire>");
return;
}

const char *pseudo_local = argv[1];
const char *adversaire = argv[2];

if (strcmp(pseudo_local, adversaire) == 0) {
envoyer_message(sock, "ERREUR_DEFI Vous ne pouvez pas vous defier vous-meme.");
return;
}

// ENVOI AU PÈRE VIA IPC : DEFI <defiante> <adversaire>
char ipc_msg[MAX_BUFFER];
snprintf(ipc_msg, MAX_BUFFER, "DEFI %s %s", pseudo_local, adversaire);

envoyer_ipc(pipe_write_to_p, ipc_msg);

printf("FIL (%s): Defi envoye au PERE pour repartition vers %s.\n", pseudo_local, adversaire);
envoyer_message(sock, "DEFI_ENVOYE En attente de la reponse de l'adversaire...");
}*/

void handle_defi(int sock, int argc, char** argv, int pipe_write_to_p)
{
const char *defiante = argv[1];
const char *adversaire = argv[2];

printf("%s %s\n", defiante, adversaire);
int idx_defiante = trouver_index_joueur(defiante);
int idx_adversaire = trouver_index_joueur(adversaire);

if (idx_adversaire == -1) {
// Le joueur ciblé n'est pas actif
if (idx_defiante != -1) {
char notif[MAX_BUFFER];
snprintf(notif, MAX_BUFFER, "ERREUR_DEFI Le joueur %s n'est pas actif.", adversaire);
envoyer_ipc(joueurs_actifs[idx_defiante].pipe_p_to_f, notif);
}
} else if (idx_defiante != -1 && joueurs_actifs[idx_defiante].en_partie) {
// Le défieur est déjà en partie
char notif[MAX_BUFFER];
snprintf(notif, MAX_BUFFER, "ERREUR_DEFI Vous etes deja en partie.");
envoyer_ipc(joueurs_actifs[idx_defiante].pipe_p_to_f, notif);
} else if (joueurs_actifs[idx_adversaire].en_partie) {
// Le joueur défié est occupé
if (idx_defiante != -1) {
char notif[MAX_BUFFER];
snprintf(notif, MAX_BUFFER, "ERREUR_DEFI Le joueur %s est deja en partie.", adversaire);
envoyer_ipc(joueurs_actifs[idx_defiante].pipe_p_to_f, notif);
}
} else {
// Relayer le défi au fils de l'adversaire
char notif[MAX_BUFFER];
snprintf(notif, MAX_BUFFER, "DEFI_RECU %s", defiante);
envoyer_ipc(joueurs_actifs[idx_adversaire].pipe_p_to_f, notif);
printf("PÈRE: Défi de %s relayé à %s.\n", defiante, adversaire);
}
}

void handle_refuse(int sock, int argc, char** argv, int pipe_write_to_p) {
// argv[0] = "REFUSE", argv[1] = pseudo_local, argv[2] = defiante

if (argc < 3) {
envoyer_message(sock, "ERREUR_PROTOCOLE Commande REFUSE incomplete. Usage: REFUSE <defiante>");
return;
}

const char *pseudo_local = argv[1];
const char *defiante = argv[2];

if (strcmp(pseudo_local, defiante) == 0) {
envoyer_message(sock, "ERREUR_REFUSE Vous ne pouvez pas vous refuser vous-meme.");
return;
}

// ENVOI AU PÈRE VIA IPC : REFUSE <défié> <defiante>
char ipc_msg[MAX_BUFFER];
snprintf(ipc_msg, MAX_BUFFER, "REFUSE %s %s", pseudo_local, defiante);

envoyer_ipc(pipe_write_to_p, ipc_msg);

printf("FIL (%s): Refus de defi envoye au PERE pour notification vers %s.\n", pseudo_local, defiante);
envoyer_message(sock, "DEFI_REFUSE_ENVOYE Refus du defi envoye.");
}

void handle_accept(int sock, int argc, char** argv, int pipe_write_to_p) {
// argv[0] = "ACCEPT", argv[1] = pseudo_local (défié), argv[2] = defiante (défiant)
if (argc < 3) {
envoyer_message(sock, "ERREUR_PROTOCOLE Commande ACCEPT incomplete. Usage: ACCEPT <defiante>");
return;
}

const char *pseudo_local = argv[1];
const char *defiante = argv[2];

if (strcmp(pseudo_local, defiante) == 0) {
envoyer_message(sock, "ERREUR_ACCEPT Vous ne pouvez pas accepter votre propre defi.");
return;
}

// ENVOI AU PÈRE VIA IPC : ACCEPT <defie> <defiante>
char ipc_msg[MAX_BUFFER];
snprintf(ipc_msg, MAX_BUFFER, "ACCEPT %s %s", pseudo_local, defiante);
envoyer_ipc(pipe_write_to_p, ipc_msg);

// Accusé de réception côté client (le père enverra ensuite les notifications aux 2 joueurs)
envoyer_message(sock, "DEFI_ACCEPT_ENVOYE Acceptation envoyee. En attente de synchronisation...");
}
6 changes: 6 additions & 0 deletions server/event_interceptor.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "event_interceptor.h"

void intercep_event(int sock, int pipe)
{

}
7 changes: 7 additions & 0 deletions server/event_interceptor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "../shared/socket.h"

/**
* Intercept an event received by one of the child processes.
* The goal of this method is to transmit it to the main process that will deal with received data.
*/
void intercept_event(int sock, int pipe);
25 changes: 25 additions & 0 deletions server/events.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef EVENTS_H
#define EVENTS_H

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "matches.h"
#include "models.h"
#include "../shared/socket.h"

// Events related to challenges
void handle_quit(int sock, int argc, char** argv, int pipe_write_to_p);
void handle_defi(int sock, int argc, char** argv, int pipe_write_to_p);
void handle_accept(int sock, int argc, char** argv, int pipe_write_to_p);

// Events related to game itself

void handle_move(int sock, int argc, char** argv, int pipe_write_to_p);
void handle_quit(int sock, int argc, char** argv, int pipe_write_to_p);

// Events related to communication between players

void handle_message(int sock, int argc, char** argv, int pipe_write_to_p);

#endif
31 changes: 31 additions & 0 deletions server/game.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "events.h"

void handle_quit(int sock, int argc, char** argv, int pipe_write_to_p) {
// Le fils doit informer le père de la déconnexion
envoyer_ipc(pipe_write_to_p, "QUIT");
}

void handle_move(int sock, int argc, char** argv, int pipe_write_to_p) {
// argv[0] = "MOVE", argv[1] = pseudo_local, argv[2] = trou_idx
if (argc < 3) {
envoyer_message(sock, "ERREUR_PROTOCOLE Commande MOVE incomplete. Usage: MOVE <trou(0-5)>");
return;
}

const char *pseudo_local = argv[1];
const char *trou_str = argv[2];

// Validation simple locale (format)
int trou_idx = atoi(trou_str);
if (trou_idx < 0 || trou_idx >= NB_TROUS_CAMP) {
envoyer_message(sock, "ERREUR_COUP Trou invalide (0..5).");
return;
}

// ENVOI AU PÈRE VIA IPC : MOVE <joueur> <trou>
char ipc_msg[MAX_BUFFER];
snprintf(ipc_msg, MAX_BUFFER, "MOVE %s %d", pseudo_local, trou_idx);
envoyer_ipc(pipe_write_to_p, ipc_msg);

// L'ACK et la synchronisation seront gérées par le PÈRE
}
Empty file removed server/joueur.h
Empty file.
60 changes: 60 additions & 0 deletions server/matches.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include "matches.h"

int trouver_index_joueur(const char* pseudo)
{
for (int i = 0; i < nb_joueurs_actifs; i++)
{
if (strcmp(joueurs_actifs[i].pseudo, pseudo) == 0)
{
return i;
}
}

return -1;
}

int trouver_match_index(const char* sud, const char* nord) {
for (int i = 0; i < nb_matches; i++) {
if (matches[i].actif &&
strcmp(matches[i].sud, sud) == 0 &&
strcmp(matches[i].nord, nord) == 0) {
return i;
}
}
return -1;
}

int creer_match(const char* sud, const char* nord) {
int idx = trouver_match_index(sud, nord);
if (idx != -1) {
// Déjà créé et actif
return idx;
}

// Tenter de réutiliser un slot inactif
int free_idx = -1;
for (int i = 0; i < nb_matches; i++) {
if (!matches[i].actif) {
free_idx = i;
break;
}
}

// Sinon, allouer un nouveau slot si possible
if (free_idx == -1) {
if (nb_matches >= MAX_MATCHES) {
return -1;
}
free_idx = nb_matches++;
}

// Initialiser le match
strncpy(matches[free_idx].sud, sud, MAX_PSEUDO_LEN - 1);
matches[free_idx].sud[MAX_PSEUDO_LEN - 1] = '\0';
strncpy(matches[free_idx].nord, nord, MAX_PSEUDO_LEN - 1);
matches[free_idx].nord[MAX_PSEUDO_LEN - 1] = '\0';

awale_init(&matches[free_idx].partie); // Initialise partie locale serveur
matches[free_idx].actif = 1;
return free_idx;
}
26 changes: 26 additions & 0 deletions server/matches.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef JOUEURS_H
#define JOUEURS_H

#include <string.h>
#include "models.h"

#define MAX_JOUEURS 100
#define MAX_MATCHES 100

/**
* Trouver un joueur actif à l'aide de son pseudo
*/
int trouver_index_joueur(const char* pseudo);

/**
* Trouver un match entre 2 joueurs actifs
*/
int trouver_match_index(const char* sud, const char* nord);

/**
* Creer un match entre 2 joueurs. Retourne l'index du match.
* Si le match existe déjà entre ces 2 joueurs, la fonction retourne l'index du match courant.
*/
int creer_match(const char* sud, const char* nord);

#endif
Loading