int conexionNivel(int iSocketComunicacion, char* sPayload, fd_set* pSetSocketsOrquestador) { int iIndiceNivel; pthread_mutex_lock(&mtxlNiveles); iIndiceNivel = existeNivel(listaNiveles, sPayload); pthread_mutex_unlock(&mtxlNiveles); if (iIndiceNivel >= 0) { tPaquete pkgNivelRepetido; pkgNivelRepetido.type = PL_NIVEL_YA_EXISTENTE; pkgNivelRepetido.length = 0; enviarPaquete(iSocketComunicacion, &pkgNivelRepetido, logger, "Ya se encuentra conectado al orquestador un nivel con el mismo nombre"); free(sPayload); return EXIT_FAILURE; } pthread_t *pPlanificador; tMensaje tipoMensaje; tInfoNivel *pInfoNivel; tNivel *pNivelNuevo = (tNivel *) malloc(sizeof(tNivel)); pPlanificador = (pthread_t *) malloc(sizeof(pthread_t)); log_debug(logger, "Se conecto el nivel %s", sPayload); char* sNombreNivel = (char *)malloc(strlen(sPayload) + 1); strcpy(sNombreNivel, sPayload); free(sPayload); tPaquete pkgHandshake; pkgHandshake.type = PL_HANDSHAKE; pkgHandshake.length = 0; enviarPaquete(iSocketComunicacion, &pkgHandshake, logger, "Handshake Plataforma"); // Ahora debo esperar a que me llegue la informacion de planificacion. recibirPaquete(iSocketComunicacion, &tipoMensaje, &sPayload, logger, "Recibe mensaje informacion del nivel"); pInfoNivel = deserializarInfoNivel(sPayload); free(sPayload); // Validacion de que el nivel me envia informacion correcta if (tipoMensaje == N_DATOS) { crearNivel(listaNiveles, pNivelNuevo, iSocketComunicacion, sNombreNivel, pInfoNivel); crearHiloPlanificador(pPlanificador, pNivelNuevo); delegarConexion(&pNivelNuevo->masterfds, pSetSocketsOrquestador, iSocketComunicacion, &pNivelNuevo->maxSock); log_debug(logger, "Nuevo planificador del nivel: '%s' y planifica con: %i", pNivelNuevo->nombre, pNivelNuevo->algoritmo); free(sNombreNivel); free(pInfoNivel); return EXIT_SUCCESS; } else { log_error(logger,"Tipo de mensaje incorrecto: se esperaba datos del nivel"); return EXIT_FAILURE; } }
void enviarTurno(tNivel *pNivel, tPersonaje *pPersonaje, int delay) { tPaquete pkgProximoTurno; pkgProximoTurno.type = PL_OTORGA_TURNO; pkgProximoTurno.length = 0; usleep(delay); log_debug(logger, "%s: turno al personaje %c", pNivel->nombre, pPersonaje->simbolo); enviarPaquete(pPersonaje->socket, &pkgProximoTurno, logger, "Se otorga un turno al personaje"); }
void entregoPosicionRecursoAlPersonaje(tNivel *pNivel, tPersonaje *pPersonajeActual, int iSocketConexion, char* sPayload, t_log* logger) { tPaquete pkgPosRecurso; obtenerDistanciaFaltante(pPersonajeActual, sPayload); pkgPosRecurso.type = PL_POS_RECURSO; pkgPosRecurso.length = sizeof(int8_t) + sizeof(int8_t); memcpy(pkgPosRecurso.payload, sPayload, pkgPosRecurso.length); enviarPaquete(pPersonajeActual->socket, &pkgPosRecurso, logger, "Envio de posicion de recurso al personaje"); free(sPayload); }
void personajeSolicitaPosicionRecurso(tNivel *pNivel, tPersonaje *pPersonajeActual, int iSocketConexion, char* sPayload, t_log* logger) { tPaquete pkgPosRecurso; pkgPosRecurso.type = PL_POS_RECURSO; pkgPosRecurso.length = sizeof(tSimbolo) + sizeof(tSimbolo); memcpy(pkgPosRecurso.payload, sPayload, pkgPosRecurso.length); free(sPayload); enviarPaquete(pNivel->socket, &pkgPosRecurso, logger, "Solicitud al NIVEL la posicion de recurso"); }
void movimientoPersonaje(int iSocketConexion, char* sPayload, tNivel *pNivel, tPersonaje** pPersonajeActual) { tMovimientoPers *movPers = deserializarMovimientoPers(sPayload); free(sPayload); tPaquete pkgMovimientoPers; serializarMovimientoPers(PL_MOV_PERSONAJE, *movPers, &pkgMovimientoPers); enviarPaquete(pNivel->socket, &pkgMovimientoPers, logger, "Envio movimiento del personaje"); free(movPers); }
void Servidor::darArranque(){ for(int id=0; id < Servidor::getCantidadDeClientesConectados(); id++ ){ if( (clientes[id].activo) && (clientes[id].socket != INVALID_SOCKET) ){ clientes[id].puedeJugar = true; enviarPaquete(clientes[id].socket,paqueteArranque,"dale q va"); Sleep(100); } } }
void Servidor::enviarExplosion(SOCKET s, explosion e){ string expSerializado; expSerializado = StringUtil::int2string((int)e.x); expSerializado += separadorCamposArreglo; expSerializado += StringUtil::int2string((int)e.y); expSerializado += separadorCamposArreglo; expSerializado += StringUtil::int2string((int)e.radio); enviarPaquete(s, paqueteExplosion, expSerializado); }
void Servidor::EnviarSonido(int id, audioEnCola aMandar){ string sonidoSerializado; if(aMandar.reproducir) sonidoSerializado = "1"; else sonidoSerializado = "0"; sonidoSerializado += separadorCamposArreglo; sonidoSerializado += StringUtil::int2string((int)aMandar.s); enviarPaquete(clientes[id].socket, paqueteSonido, sonidoSerializado); }
void Servidor::actualizar(void* clienteN) { int id= (int)clienteN; audioEnCola** colaDeSonidos; int tiempo = 0; while(clientes[id].activo){ try{ recibirDeCliente(&id); if(clientes[id].activo){ enviarCliente(&id, paqueteVista, dibujablesSerializados); //recibe los mensajes que mandan otros clientes sin chocar en los threads if(time(NULL) - mensaje.tiempoActivo == 0){ if(mensaje.emisor != clientes[id].socket) enviarPaquete(clientes[id].socket, paqueteMensajeInfo, mensaje.msj); }else{ mensaje.tiempoActivo=0; } for(int i=0; i< maxExplosionesPorTurno; i++){ if(exp[id][i].radio >= 0){ if(clientes[id].socket != INVALID_SOCKET){ enviarExplosion(clientes[id].socket, exp[id][i]); exp[id][i].radio = -1; } } } //envio el tiempo del reloj a los clientes:5 if(Servidor::tiempo != -1 && Servidor::tiempo <= tiempoTurno){ enviarCliente(&id,paqueteTiempo, StringUtil::int2string(Servidor::tiempo)); } colaDeSonidos = Reproductor::getReproductor()->getColaDeEspera(); for(int i=0; i< numSonidos; i++){ if(!colaDeSonidos[id][i].enviado){ EnviarSonido(id, colaDeSonidos[id][i]); colaDeSonidos[id][i].enviado = true; } } } }catch(exception &e){ cout<<"catch en Servidor::actualizar: "<<e.what()<<endl; } } }
int conexionPersonaje(int iSocketComunicacion, fd_set* socketsOrquestador, char* sPayload) { tHandshakePers* pHandshakePers; pHandshakePers = deserializarHandshakePers(sPayload); free(sPayload); int iIndiceNivel; log_info(logger, "Se conectó el personaje %c pidiendo el nivel '%s'", pHandshakePers->simbolo, pHandshakePers->nombreNivel); pthread_mutex_lock(&mtxlNiveles); iIndiceNivel = existeNivel(listaNiveles, pHandshakePers->nombreNivel); if (iIndiceNivel >= 0) { tNivel *pNivelPedido; pNivelPedido = list_get_data(listaNiveles, iIndiceNivel); pthread_mutex_unlock(&mtxlNiveles); if (pNivelPedido == NULL) { log_error(logger, "Saco mal el nivel: Puntero en NULL"); sendConnectionFail(iSocketComunicacion, PL_NIVEL_INEXISTENTE, "No se encontro el nivel pedido"); } avisoConexionANivel(pNivelPedido->socket, sPayload, pHandshakePers->simbolo); add_new_personaje_in_plataforma(pHandshakePers->simbolo); agregarPersonaje(pNivelPedido, pHandshakePers->simbolo, iSocketComunicacion); free(pHandshakePers->nombreNivel); free(pHandshakePers); delegarConexion(&pNivelPedido->masterfds, socketsOrquestador, iSocketComunicacion, &pNivelPedido->maxSock); pthread_cond_signal(&(pNivelPedido->hayPersonajes)); tPaquete pkgHandshake; pkgHandshake.type = PL_HANDSHAKE; pkgHandshake.length = 0; // Le contesto el handshake enviarPaquete(iSocketComunicacion, &pkgHandshake, logger, "Handshake de la plataforma al personaje"); return EXIT_SUCCESS; } else { pthread_mutex_unlock(&mtxlNiveles); log_error(logger, "El nivel solicitado no se encuentra conectado a la plataforma"); sendConnectionFail(iSocketComunicacion, PL_NIVEL_INEXISTENTE, "No se encontro el nivel pedido"); free(pHandshakePers->nombreNivel); free(pHandshakePers); return EXIT_FAILURE; } }
void confirmarMovimiento(tNivel *nivel, tPersonaje *pPersonajeActual) { int sockPersonaje = pPersonajeActual->socket; if (nivel->algoritmo == RR) { pPersonajeActual->quantumUsado++; pPersonajeActual->remainingDistance--; } else { pPersonajeActual->remainingDistance--; pPersonajeActual->quantumUsado = 0; } tPaquete pkgConfirmacionMov; pkgConfirmacionMov.type = PL_CONFIRMACION_MOV; pkgConfirmacionMov.length = 0; enviarPaquete(sockPersonaje, &pkgConfirmacionMov, logger, "Se envia confirmacion de movimiento al personaje"); }
void Servidor::avisarPartidaTerminada(){ Reproductor::getReproductor()->reiniciar(); Reproductor::getReproductor()->detenerSonidos(); Reproductor::getReproductor()->reproducirSonido(VICTORIA); for(int id=0; id < Servidor::getCantidadDeClientesConectados(); id++ ){ if( (clientes[id].activo) && (clientes[id].socket != INVALID_SOCKET) ){ Sleep(100); enviarPaquete(clientes[id].socket,paquetePartidaTerminada,"termino la partida"); clientes[id].figuras.clear(); clientes[id].puedeJugar = true; } } clientesConectados = 0; }
bool avisoConexionANivel(int sockNivel,char *sPayload, tSimbolo simbolo){ // tMensaje tipoMensaje; tSimbolo simboloMsj = simbolo; tPaquete *paquete = malloc(sizeof(tPaquete)); serializarSimbolo(PL_CONEXION_PERS, simboloMsj, paquete); enviarPaquete(sockNivel, paquete, logger, "Envio al nivel el nuevo personaje que se conecto"); // recibirPaquete(sockNivel, &tipoMensaje, &sPayload, logger, "Recibo confirmacion del nivel"); free(paquete); // if (tipoMensaje == N_CONEXION_EXITOSA) { // return true; // } else if(tipoMensaje == N_PERSONAJE_YA_EXISTENTE) { // return false; // } return false; }
void Servidor::recibirDeCliente(int* clienteN) { Paquete* paquete = new Paquete(); // data buffer char network_data[MAX_PACKET_SIZE]; // get data for that client int data_length = 0; int id; data_length = red->recibirData(clientes[*clienteN].socket, network_data); int cantData = 0; while (cantData < data_length) { paquete->deserializar(&(network_data[cantData])); cantData+= paquete->getPesoPaquete(); switch (paquete->getTipo()) { case paqueteInicial: //en el getMensaje tengo el username id = buscarCliente(paquete->getMensaje()); if(id != -1){ //si existe el username if(!clientes[id].activo){ //si ese username esta congelado clientes[id].activo=true; //descongelo y doy bienvenida clientes[id].time=time(NULL); clientes[id].socket = clientes[*clienteN].socket; *clienteN = id; cliente_id--; //le vuelvo a enviar todas las cosas, por si se reconecta en otra pc enviarEscenario(*clienteN, true); enviarImagenes(clientes[*clienteN].socket); enviarPaquete(clientes[*clienteN].socket, paqueteDescargaLista, ""); cout<<clientes[*clienteN].username<<" se ha reconectado."<<endl; //hago que el bienvenido le aparezca en la vista al cliente enviarPaquete(clientes[*clienteN].socket, paqueteMensajeInfo, "Bienvenido de nuevo, "+clientes[*clienteN].username + "."); //hago que el resto sepa que se reconectó el cliente //for(int cont=0; cont < escenario->maximosClientes; cont++){ // if((clientes[cont].username != clientes[*clienteN].username)&&(clientes[cont].activo)){ // if(clientes[cont].socket != INVALID_SOCKET) enviarPaquete(clientes[cont].socket, paqueteMensajeInfo, clientes[*clienteN].username +" se ha reconectado."); // } //} mensaje.emisor=clientes[*clienteN].socket; mensaje.msj = clientes[*clienteN].username +" se ha reconectado."; mensaje.tiempoActivo=time(NULL); for (std::list<Gusano*>::const_iterator it = clientes[*clienteN].figuras.begin(); it != clientes[*clienteN].figuras.end(); it++) { (*it)->setCongelado(false); } enviarPaquete(clientes[id].socket,paqueteArranque,"dale q va"); }else{ //si no esta congelado, es xq ya existe un usuario con ese nombre enviarPaquete(clientes[*clienteN].socket, paqueteFinal, "Ya existe otro usuario con su nombre."); cliente_id--; clientes[*clienteN].activo=false; } }else{ //si no existe username, tengo que ver si hay lugar para uno nuevo if(cliente_id-1 < escenario->maximosClientes){ //si hay lugar clientes[*clienteN].activo=true; //le asigno un espacio y doy la bienvenida clientes[*clienteN].username = paquete->getMensaje(); clientes[*clienteN].time = time(NULL); enviarEscenario(*clienteN, false); enviarImagenes(clientes[*clienteN].socket); enviarPaquete(clientes[*clienteN].socket, paqueteDescargaLista, ""); cout<<clientes[*clienteN].username<<" se ha conectado."<<endl; mensaje.tiempoActivo=time(NULL); //hago que el bienvenido le aparezca en la vista al cliente enviarPaquete(clientes[*clienteN].socket, paqueteMensajeInfo, "Bienvenido, "+clientes[*clienteN].username + "."); //hago que el resto sepa que se conectó el cliente //for(int cont=0; cont < escenario->maximosClientes; cont++){ // if(clientes[cont].username != clientes[*clienteN].username){ // if(clientes[cont].socket != INVALID_SOCKET) enviarPaquete(clientes[cont].socket, paqueteMensajeInfo, clientes[*clienteN].username +" se ha conectado."); // } //} mensaje.emisor=clientes[*clienteN].socket; mensaje.msj = clientes[*clienteN].username +" se ha conectado."; mensaje.tiempoActivo=time(NULL); clientesConectados++; //cliente_id++; }else{ //si no hay lugar, lo saco enviarPaquete(clientes[*clienteN].socket, paqueteFinal, "Ya se ha alcanzado la cantidad maxima de clientes."); cliente_id--; clientes[*clienteN].activo=false; } } break; case paqueteEvento: if(clientes[*clienteN].username == clientes[Servidor::idJugando].username){ clientes[*clienteN].ultimoEventoSerializado = paquete->getMensaje(); } else{ //cout << "espere su turno, ahora esta jugando " << clientes[Servidor::idJugando].username <<endl; //clientes[*clienteN].ultimoEventoSerializado = paquete->getMensaje(); } break; case paqueteEstado: clientes[*clienteN].time = time(NULL); break; default: break; } } if(clientes[*clienteN].activo){ if(time(NULL) - clientes[*clienteN].time > 3){ //2 segundos de espera clientes[*clienteN].socket = INVALID_SOCKET; cout<<clientes[*clienteN].username<<" se ha desconectado."<<endl; ////hago que el resto sepa que se desconectó el cliente //for(int cont=0; cont < escenario->maximosClientes; cont++){ // if(clientes[cont].username != clientes[*clienteN].username){ // if(clientes[cont].socket != INVALID_SOCKET) enviarPaquete(clientes[cont].socket, paqueteMensajeInfo, clientes[*clienteN].username +" se ha desconectado."); // } //} mensaje.emisor=clientes[*clienteN].socket; mensaje.msj = clientes[*clienteN].username +" se ha desconectado."; mensaje.tiempoActivo=time(NULL); for (std::list<Gusano*>::const_iterator it = clientes[*clienteN].figuras.begin(); it != clientes[*clienteN].figuras.end(); it++) { (*it)->setCongelado(true); } clientes[*clienteN].activo=false; } } delete paquete; }
void Servidor::enviarCliente(int* clienteN, int tipoPaquete, string mensaje){ if(clientes[*clienteN].socket != INVALID_SOCKET) enviarPaquete(clientes[*clienteN].socket, tipoPaquete, mensaje); }
int avisarAlPersonajeDeMuerte(int socketPersonajeMuerto, tSimbolo simbolo, tMensaje tipoDeMuerte){ tPaquete pkgMuertePers; serializarSimbolo(tipoDeMuerte, simbolo, &pkgMuertePers); enviarPaquete(socketPersonajeMuerto, &pkgMuertePers, logger, "Envio mensaje de muerte al personaje"); return EXIT_SUCCESS; }
void sendConnectionFail(int sockPersonaje, tMensaje typeMsj, char *msjInfo){ tPaquete pkgPersonajeRepetido; pkgPersonajeRepetido.type = typeMsj; pkgPersonajeRepetido.length = 0; enviarPaquete(sockPersonaje, &pkgPersonajeRepetido, logger, msjInfo); }