Nantes Université

Skip to content
Extraits de code Groupes Projets
Vérifiée Valider 9d31d4bb rédigé par Leo LEMAIRE's avatar Leo LEMAIRE
Parcourir les fichiers

Question utilisateur + fix message en plusieurs parties

parent 5d69c894
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
......@@ -187,9 +187,32 @@ void master_onRequest(user_t* u){
// si aucun joueur s'y oppose
mc_resp.ok = 1;
send_message(u->pipes[1], req.send_id, &mc_resp, sizeof(mc_resp), M_RESPONSE);
break;
break;
case REQ_USER:
;
printf("User request from %d\n", req.send_id);
user_request u_req;
memcpy(&u_req, u->r_data->r_buf, sizeof(u_req));
printf("%s", u_req.content);
if(!u_req.expect_response)
break;
response u_resp = {
.t = RESP_USER,
.id = u->id,
};
user_response uo_resp = {
.parent = u_resp,
};
fgets(uo_resp.response, USER_RESPONSE_MSG_LEN, stdin);
send_message(u->pipes[1], req.send_id, &uo_resp, sizeof(uo_resp), M_RESPONSE);
break;
default:
fprintf(stderr, "Unimplemented request handler called, dropping it, (not good)");
fprintf(stderr, "Unimplemented request handler called, dropping it, (not good) (%d)\n", req.t);
break;
}
}
......
......@@ -21,15 +21,11 @@ void receive_loop(user_t* u){
return;
}
//printf("%d received message type %d\n", data->id, in.t);
printf("%d received message type %d %d %d\n", data->id, in.t, data->cont_id, in.id);
if(in.t == M_CONT){
if(in.id != data->cont_id){
fprintf(stderr, "Continuation message of an unknown source, dropping it");
return;
}
if(in.t != data->cont_type){
fprintf(stderr, "Continuation message of the wrong type, dropping it");
fprintf(stderr, "Continuation message of an unknown source, dropping it\n");
return;
}
}
......@@ -38,12 +34,13 @@ void receive_loop(user_t* u){
}
data->r_buf = realloc(data->r_buf, data->content_off + in.content_size);
memcpy(data->r_buf, &in.content + data->content_off, in.content_size);
memcpy(data->r_buf + data->content_off, &in.content, in.content_size);
data->content_off += in.content_size;
if(in.cont_id != -1){ // si ce n'est pas le dernier message
data->cont_id = in.cont_id;
data->cont_type = in.t;
data->cont_id = in.cont_id;
if(in.cont_id != -1){ // si c'est un message en plusieurs parties
if(in.t != M_CONT) // si on est sur le premier de la chaine
data->cont_type = in.t; // on enregistre le type attendu
return;
}
......@@ -51,10 +48,19 @@ void receive_loop(user_t* u){
case M_REQUEST:
data->onRequest(u);
break;
case M_CONT:
switch(data->cont_type){
case M_REQUEST:
data->onRequest(u);
break;
case M_RESPONSE:
data->onResponse(u);
break;
case M_CONT:
fprintf(stderr, "Reached end of a splitted message of type M_CONT, this should not happen\n");
break;
}
break;
case M_RESPONSE:
data->onResponse(u);
break;
......@@ -66,13 +72,13 @@ void send_message(int pipe, int dest_id, void* content, int content_size, M_TYPE
for(int i = 0; i < content_size; i += M_SIZE){
int chunk_size = MIN(M_SIZE, content_size - i);
message out = {
.t = type,
.t = i==0?type:M_CONT,
.id = id,
.dest_id = dest_id,
.content_size = chunk_size,
};
memcpy(out.content, content + i, chunk_size);
if(chunk_size == M_SIZE){
if(i + M_SIZE <= content_size){
id = abs(rand());
out.cont_id = id;
}
......@@ -95,7 +101,7 @@ void send_request_and_wait_for_response_handler(user_t* u){
message_wait_message_received = 1;
}
else{
fprintf(stderr, "Received unexpected response while waiting for another request, dropping the unknwown one");
fprintf(stderr, "Received unexpected response while waiting for another request, dropping the unknwown one (%d/%d) \n", res.t, message_wait_req_type);
return;
}
}
......@@ -106,7 +112,7 @@ void send_request_and_wait_for_response_handler(user_t* u){
char* send_request_and_wait_for_response(user_t* u, int dest_id, void* content, int content_size, REQ_TYPE type){
message_wait_req_type = get_corresponding_response(type);
if(message_wait_req_type == RESP_UNKNOWN){
fprintf(stderr,"waiting for an unkwown response type, this will hang (bad)");
fprintf(stderr,"waiting for an unkwown response type, this will hang (bad) (%d %d)\n", type, REQ_USER);
}
send_message(u->pipes[1], dest_id, content, content_size, M_REQUEST);
......
......@@ -8,6 +8,7 @@ typedef enum REQ_TYPE {
REQ_PLAY, // demande a un joueur de jouer
REQ_DICE, // demande un lancer de de
REQ_MOVE_CASE, // demande un mouvement vers une case (ne bouge pas de pion, demande juste si ce mouvement est valable, un peu comme dans un mariage quand on demande si quelqu'un s'oppose a cette union)
REQ_USER, // fait une demande a l'utilisateur (plutot prevu pour etre demande au master)
} REQ_TYPE;
typedef struct {
......@@ -37,3 +38,11 @@ typedef struct {
int move_case; // id de la case sur laquelle on veut se deplacer
int orig_case; // id de la case de laquelle on part (-1 pour une case en dehors de chemin (enclos/escalier))
} move_case_request;
#define USER_REQUEST_MSG_LEN 256
typedef struct {
request parent;
char content[USER_REQUEST_MSG_LEN]; // si le message depasse USER_REQUEST_LEN il suffit de le decoupep et d'envoyer les differents morceau en tant que message n'attendnat pas de response
int expect_response; // si on s'attend a une reponse
} user_request;
......@@ -11,6 +11,10 @@ RESP_TYPE get_corresponding_response(REQ_TYPE req){
return RESP_ID;
case REQ_PLAY:
return RESP_PLAY;
case REQ_MOVE_CASE:
return RESP_MOVE_CASE;
case REQ_USER:
return RESP_USER;
default:
return RESP_UNKNOWN;
}
......
......@@ -6,6 +6,7 @@ typedef enum RESP_TYPE {
RESP_PLAY,
RESP_DICE,
RESP_MOVE_CASE,
RESP_USER,
RESP_UNKNOWN, // type inconnu (request n'ayant pas de reponse, ne pas en attendre)
} RESP_TYPE;
......@@ -47,4 +48,10 @@ typedef struct {
MOVE_CONDITION cond; // conditions au mouvement
} move_case_response;
#define USER_RESPONSE_MSG_LEN 128
typedef struct {
response parent;
char response[USER_RESPONSE_MSG_LEN];
} user_response;
RESP_TYPE get_corresponding_response(REQ_TYPE req);
......@@ -243,10 +243,84 @@ void user_play(user_t* user, request* orig){
}
}
else{ // si on as deja des chevaux de sortis
// TODO :
// check which horses are playable
// if more than one playable horse :
// ask which one the player want to move
request req = {
.t = REQ_MOVE_CASE,
.send_id = user->id,
};
move_case_request m_req = {
.parent = req,
};
int playable[user->nb_chevals];
int nb_playable = 0;
for(int i = 0; i < user->nb_chevals; i++){
cheval_t c = user->c[i];
if(c.enclos || c.escalier){
playable[i] = 0;
continue;
}
m_req.orig_case = c.pos;
m_req.move_case = c.pos + user->dice;
char* resp_r = send_request_and_wait_for_response(user, -1, &m_req, sizeof(m_req), REQ_MOVE_CASE);
move_case_response resp;
memcpy(&resp, resp_r, sizeof(resp));
free(resp_r);
playable[i] = resp.ok;
nb_playable += resp.ok?1:0;
}
if(nb_playable == 1){ // TODO : > 1 (debug)
char message[USER_REQUEST_MSG_LEN];
int msg_ind = 0;
int res = sprintf(message, "Joueur %d peut jouer plusieurs chevaux. Votre choix : [", user->id);
if(res < 0)
fprintf(stderr, "Error making user request message buffer");
msg_ind += res;
int first_send = 1;
for(int i = 0; i < user->nb_chevals; i++){
if(playable[i]){
int res = 0;
if(first_send){
res = sprintf(&message[msg_ind], "%d", i);
first_send = 0;
}
else{
res = sprintf(&message[msg_ind], ",%d", i);
}
if(res < 0)
fprintf(stderr, "Error making user request message buffer");
msg_ind += res;
}
}
sprintf(&message[msg_ind], "] : \n");
request req = {
.t = REQ_USER,
.send_id = user->id,
};
user_request u_req = {
.parent = req,
.expect_response = 1,
};
memcpy(u_req.content, message, USER_REQUEST_MSG_LEN);
printf("%d sending dialog to user\n", user->id);
char* resp_r = send_request_and_wait_for_response(user, -1, &u_req, sizeof(u_req), REQ_USER);
free(resp_r);
}
// TODO
// request horse mouvement
// move the horse
}
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter