void crearCaja(char ** caja){ //CREA LA UNIDAD CAJA Y LA ENGANCHA EN LA LISTA DE RECURSOS DEL NIVEL

	pthread_mutex_lock(&mutex_listas);
	CrearCaja(items, caja[1][0],atoi(caja[3]), atoi(caja[4]), atoi(caja[2]));
	pthread_mutex_unlock(&mutex_listas);

	pthread_mutex_lock(&mutex_log);
	log_info(logger, "Se crea la caja de %s", caja[1]);
	pthread_mutex_unlock(&mutex_log);
}
Exemple #2
0
void crearCajasConVector(char** array) {
	char id = array[1][0];
	int instancia = atoi(array[2]);
	int pos_x = atoi(array[3]);
	int pos_y = atoi(array[4]);

	if (pos_x <= col && pos_y <= fil) {
		CrearCaja(listaRecursos, id, pos_x, pos_y, instancia);
		log_info(logFile, "Se creo la caja:%c, cantidad:%d, Pos:(%d,%d)", id,
				instancia, pos_x, pos_y);
	} else {
		log_warning(logFile,
				"No se creo la caja:%c, cantidad:%d, Pos:(%d,%d), sobrepasa los limites",
				id, instancia, pos_x, pos_y);
	}
}
ITEM_NIVEL* crearNivel(nivelConfigStruct nivel) {

        ITEM_NIVEL* ListaItems = NULL;
        int32_t i;
        cajaStruct *caja;
        int32_t r,c;

                nivel_gui_inicializar();
                nivel_gui_get_area_nivel(&r, &c);
                rows = r;
                cols = c;

                for (i = 0; i < list_size(nivel.cajas) ; i++)
                {
                        caja = list_get(nivel.cajas,i);
                        CrearCaja(&ListaItems,caja->simbolo,caja->posX,caja->posY,caja->instancias);
                }

return ListaItems;

}
Exemple #4
0
t_nivel* configuracion_inicializar(char* path) {

	t_nivel* nivel = malloc(sizeof(t_nivel));
	nivel->lista_items = NULL;
	t_config* configuracion_nivel = config_create(path);
//nombre
	nivel->nombre = string_duplicate(
			config_get_string_value(configuracion_nivel, "Nombre"));
//deadlock
	nivel->deadlock = config_get_int_value(configuracion_nivel,
			"TiempoChequeoDeadlock");
//recovery
	nivel->recovery = config_get_int_value(configuracion_nivel, "Recovery");
//ip y puerto
	char* ip_puerto = config_get_string_value(configuracion_nivel,
			"orquestador");
	char**ip = string_split(ip_puerto, ":");
	strcpy(nivel->ip, ip[0]);
	//puerto
	char* puerto = ip[1];
	nivel->puerto = atoi(puerto);
	free(ip[0]);
	free(ip[1]);
	free(ip);

	//ip y puerto del nivel todo get ip
		char* ip_puerto_nivel= config_get_string_value(configuracion_nivel,
				"ip_nivel");
		char**ip_nivel = string_split(ip_puerto_nivel, ":");
		strcpy(nivel->ip_nivel, ip_nivel[0]);
		//puerto
		char* puerto_nivel = ip_nivel[1];
		nivel->puerto_nivel = atoi(puerto_nivel);
		free(ip_nivel[0]);
		free(ip_nivel[1]);
		free(ip_nivel);

	//cantidad de key en el archivo, que son de cajas nada mas, resto 6 por ahora
	cantidad_key = config_keys_amount(configuracion_nivel) - 5;
	//los numeros de caja empiezan de 1 y van en orden(siempre)
	int count;
	for (count = 1; count <= cantidad_key; count++) {
		//armo las keys de las cajas
		char* key = string_from_format("Caja %d", count);

		if (config_has_property(configuracion_nivel, key)) {

			char* caja = (char*) config_get_string_value(configuracion_nivel,
					key);
			char** array_values = string_split(caja, ",");
//del array saco el char del string que me viene
			char id = array_values[1][1];

			CrearCaja(&(nivel->lista_items), id, atoi(array_values[3]),
					atoi(array_values[4]), atoi(array_values[2]));
		}
	}
	config_destroy(configuracion_nivel);
	nivel->personajes_deadlock = list_create();
	log_info(logger, "se ha inicializado un nivel");
	return nivel;
}
int main(int argc, char* argv[]) {
    // Lo puse t0d0 en el llamado de abajo, no se porque y si se puede capturar 2 veces la señal como estaba hecho.
    // signal(SIGINT, notificarPersonajes);

    pthread_mutex_init(&semNiv, NULL);

    logger = logInit(argv, argv[1]);

    // Capturamos sigint y avisamos a los personajes para que cierren y cerramos el nivel.
    signal(SIGINT, cerrarForzado);

    t_config *configNivel;
    char** arrCaja;
    char* nom_nivel;
    char* ip_orq;
    char* port_orq;
    char* dir_orq;
    char ip[16];
    int puerto;

    //--Creamos el config
    configNivel = config_try_create(
                      //"nivel1.config" //Modo Debug
                      argv[1], "Nombre,orquestador,TiempoChequeoDeadlock,Recovery,ip,puerto,Caja1");

    ITEM_NIVEL *ListaItems = NULL;

    //--Creamos cada caja de recursos
    char* cajaAux;
    cajaAux = malloc(sizeof(char) * 6);
    sprintf(cajaAux, "Caja1");

    //--Inicializa la lista con los personajes y sus recursos
    personajes = list_create();
    personaje_t pjAux;

    int t = 1;
    int cols = 0;
    int rows = 0;
    int posXCaja = 0;
    int posYCaja = 0;
    nivel_gui_inicializar();
    // Conseguimos el area del nivel
    char state = nivel_gui_get_area_nivel(&cols, &rows);
    // Validamos que no haya habido error
    if (state != EXIT_SUCCESS) {
        cerrarNivel("Error al intentar conseguir el area del nivel (GUI).");
        exit(EXIT_FAILURE);
    }
    char* messageLimitErr;
    messageLimitErr = malloc(sizeof(char) * 100);

    //--Mientras pueda levantar el array
    while ((arrCaja = config_try_get_array_value(configNivel, cajaAux)) != NULL ) {
        posXCaja = atoi(arrCaja[3]);
        posYCaja = atoi(arrCaja[4]);
        // Validamos que la caja a crear esté dentro de los valores posibles del mapa
        if (posXCaja > rows || posYCaja > cols || posXCaja < 1 || posYCaja < 1) {
            sprintf(messageLimitErr, "La caja %c excede los limites de la pantalla. (%d,%d) - (%d,%d)", arrCaja[1][0], posXCaja, posYCaja, rows, cols);
            cerrarNivel(messageLimitErr);
            exit(EXIT_FAILURE);
        }
        // Si pasó la validacion, la creamos.
        CrearCaja(&ListaItems, arrCaja[1][0], atoi(arrCaja[3]), atoi(arrCaja[4]), atoi(arrCaja[2]));
        //--Rearma el cajaAux para la iteracion
        sprintf(cajaAux, "Caja%d", ++t);
    }

    free(cajaAux);

    //--Boludeces de los sockets
    message_t message;
    fd_set master, temp;
    struct sockaddr_in myAddress;
    struct sockaddr_in remoteAddress;
    int maxSock;
    int sockListener;
    int sockOrq;

    //--Saludo al orquestador

    //--Obetenemos el string del nombre y dirección del orquestador
    nom_nivel = config_get_string_value(configNivel, "Nombre");
    dir_orq = config_get_string_value(configNivel, "orquestador");
    puerto = config_get_int_value(configNivel, "puerto");
    memcpy(ip, config_get_string_value(configNivel, "ip"), 16);
    // Conseguimos el tiempo de espera de chequeo
    int tiempoChequeo = config_get_int_value(configNivel, "TiempoChequeoDeadlock");

    ip_orq = strtok(dir_orq, ":"); 	//--Separar ip
    port_orq = strtok(NULL, ":");	//--Separar puerto

    // Crear un socket:
    struct sockaddr_in socketInfo;
    if ((sockOrq = socket(AF_INET, SOCK_STREAM, 0)) != 0) {

        socketInfo.sin_family = AF_INET;
        socketInfo.sin_addr.s_addr = inet_addr(ip_orq);
        socketInfo.sin_port = htons(atoi(port_orq));

        // Conectar el socket con la direccion 'socketInfo'.
        if (connect(sockOrq, (struct sockaddr*) &socketInfo, sizeof(socketInfo)) == -1) {
            perror("Connect");
            exit(EXIT_FAILURE);
        }

        log_info(logger, "Conexión con orquestador.");

        orq_t orqMsj;
        orqMsj.type = NIVEL;
        orqMsj.detail = SALUDO;
        strcpy(orqMsj.name, nom_nivel);

        //memcpy(orqMsj.ip, &localhost->sin_addr.s_addr, 16);
        strcpy(orqMsj.ip, ip);
        orqMsj.port = puerto;

        //--Envía el "Saludo" para ser agregado
        if (send(sockOrq, &orqMsj, sizeof(orq_t), 0) == -1) {
            perror("Saludo");
            exit(EXIT_FAILURE);
        }
    }

    // Definimos los threads
    pthread_t thr_interbloqueos;
    paramInterbloqueo_t parametros;
    parametros.numSock = sockOrq;
    parametros.tiempoChequeo = tiempoChequeo;
    parametros.recovery = config_get_int_value(configNivel, "Recovery");

    // y los lanzamos
    if (pthread_create(&thr_interbloqueos, NULL, (void*) detectInterbloqueos, (void *) &parametros)) {
        log_error(logger, strerror(errno));
        exit(EXIT_FAILURE);
    }

    int maxRows, maxCols;
    int posX, posY;
    int posItemY, posItemX;
    int i;

    nivel_gui_get_area_nivel(&maxRows, &maxCols);

    nivel_gui_dibujar(ListaItems, nom_nivel);

    iniSocks(&master, &temp, &myAddress, remoteAddress, &maxSock, &sockListener, puerto, logger);
    while (1) {
        //--Gestiona un cliente ya conectado
        i = getSockChanged(&master, &temp, &maxSock, sockListener, &remoteAddress, &message, sizeof(message_t), logger);
        if (i != -1) {

            pthread_mutex_lock(&semNiv);

            int contPj;
            int contRec;
            char *auxRec;
            personaje_t *tempAux;
            //--Recibe mensaje y define comportamiento según el tipo
            switch (message.type) {
            case SALUDO:
                //--Agregamos personaje a la lista de items y a la de personajes/recursos
                CrearPersonaje(&ListaItems, i, message.name, INIX, INIY);
                pjAux.numSock = i;
                pjAux.chirimbolo = message.name;
                pjAux.blocked = false;
                pjAux.recursos = list_create();
                list_add_new(personajes, &pjAux, sizeof(personaje_t));

                //--Armamos la estrucura para enviar la posición inicial
                message.type = SALUDO;
                message.detail = INIX;
                message.detail2 = INIY;

                log_info(logger, "Se agregó el personaje %c con el socket %d", message.name, i);

                if (send(i, &message, sizeof(message), 0) == -1)
                    perror("Respuesta posición inicial");
                break;
            case POSICION:
                //--Obtiene posición del item pedido
                getPosRec(ListaItems, message.detail, &posX, &posY);

                //--Armamos la estrucura para enviar la posición del recurso pedido
                message.type = POSICION;
                message.detail = posX;
                message.detail2 = posY;

                if (send(i, &message, sizeof(message), 0) == -1)
                    perror("Respuesta posición recurso");
                break;
            case MOVIMIENTO:
                //--Devuelve las posiciones X e Y del item
                if (getPosPer(ListaItems, i, &posX, &posY) == -1)
                    perror("GetPosItem");

                switch (message.detail) {

                case ARRIBA:
                    if (posY > 1)
                        posY--;
                    break;

                case ABAJO:
                    if (posY < maxRows)
                        posY++;
                    break;

                case IZQUIERDA:
                    if (posX > 1)
                        posX--;
                    break;
                case DERECHA:
                    if (posX < maxCols)
                        posX++;
                    break;
                }

                //--Define confirmación y la devuelve
                message.type = MOVIMIENTO;
                message.detail2 = message.detail;
                message.detail = 1;
                if (send(i, &message, sizeof(message), 0) == -1)
                    perror("Confirmacion");

                //--Desbloquear en caso de que esté bloqueado
                for (contPj = 0; contPj < list_size(personajes); contPj++) {
                    tempAux = list_get(personajes, contPj);

                    if (tempAux->numSock == i && tempAux->blocked)
                        tempAux->blocked = false;
                }

                MoverPersonaje(ListaItems, i, posX, posY);
                break;
            case PEDIDO:
                //--Obtiene posición del item pedido y del personaje
                getPosRec(ListaItems, message.detail, &posItemX, &posItemY);
                getPosPer(ListaItems, i, &posX, &posY);

                //--Valida si llegó al recurso
                if ((posItemX == posX) && (posItemY == posY)) {

                    //-- Siempre le tiene que agregar a la lista de recursos, este o no bloqueado
                    //--Agrega el recurso a la lista de recursos del personaje
                    int contPj;
                    personaje_t* tempAux;
                    for (contPj = 0; contPj < list_size(personajes); contPj++) {
                        tempAux = list_get(personajes, contPj);

                        if (tempAux->numSock == i) {
                            list_add_new(tempAux->recursos, &(message.detail), sizeof(message.detail));
                            break;
                        }
                    }

                    //--Resta uno a la cantidad del item
                    int result = restarQuantityRec(ListaItems, message.detail);

                    if (result >= 0) {

                        log_info(logger, "A %d se le da el recurso %c", i, message.detail);

                        //--Si pudo restar la cantidad
                        tempAux->blocked = false;
                        //--Define confirmación y la devuelve
                        message.detail = 1;
                        if (send(i, &message, sizeof(message), 0) == -1)
                            perror("Confirmacion");

                    } else {
                        //--Si el recurso ya no tiene instacias
                        tempAux->blocked = true;

                        log_info(logger, "A %d se le niega el recurso %c", i, message.detail);
                        //--Define rechazo y lo devuelve
                        message.detail = 0;
                        if (send(i, &message, sizeof(message), 0) == -1)
                            perror("Confirmacion");
                    }
                } else {
                    log_error(logger, "Posicion erronea al pedir recurso");
                    exit(EXIT_FAILURE);
                }

                break;
            case SALIR:
                for (contPj = 0; contPj < list_size(personajes); contPj++) {
                    tempAux = list_get(personajes, contPj);

                    if (tempAux->numSock == i) {
                        //--Elimina y libera la lista de recursos de personaje

                        for (contRec = 0; contRec < list_size(tempAux->recursos); contRec++) {
                            auxRec = list_get(tempAux->recursos, contRec);
                            //--Suma la cantidad de recursos que el personaje libera
                            sumarQuantityRec(ListaItems, *auxRec, 1);
                        }

                        list_destroy_and_destroy_elements(tempAux->recursos, free);

                        //--Elimina y libera al personaje de la lista de personajes
                        list_remove_and_destroy_element(personajes, contPj, free);
                        BorrarPer(&ListaItems, i);
                        break;
                    }
                }

                log_debug(logger, "%d se desconectó", i);
                break;
            }
            nivel_gui_dibujar(ListaItems, nom_nivel);

            pthread_mutex_unlock(&semNiv);
        }

    }

    nivel_gui_terminar();
    return 0;
}
void crearGuiRecursos(void* item) {
	DataRecurso* resource = (DataRecurso *) item;
	CrearCaja(&listaItems, resource->recurso->simbolo, resource->posicion.x, resource->posicion.y, resource->recurso->cantidad);
}