예제 #1
0
void usa_objecto (int i, pid_t pid)
{
	int u, p;
	u = find_user_index (pid);
	p = find_user_playing_index (pid);

	user_list[u].hp += user_list[u].saco[i].hp_diff;
	users_playing[p].hp += users_playing[p].saco[i].hp_diff;
	
	// garantir que o hp nao fica maior que hp_max 
	if (user_list[u].hp >= user_list[u].hp_max)
		user_list[u].hp = user_list[u].hp_max; 

	if (users_playing[p].hp >= users_playing[p].hp_max)
		users_playing[p].hp = users_playing[p].hp_max;

	// pode-se usar o objecto as vezes que quiser se max_suo==0
	if (user_list[u].saco[i].max_uso == 0)
		return;

	// case exceda o numero de usos remover do saco
	user_list[u].saco[i].n_uso++;
	users_playing[p].saco[i].n_uso++;

	if (user_list[u].saco[i].n_uso == user_list[u].saco[i].max_uso)
		remove_object_saco (i, user_list[u].client_pid);

	if (users_playing[p].saco[i].n_uso == users_playing[p].saco[i].max_uso)
		remove_object_saco (i, users_playing[p].client_pid);
}
예제 #2
0
/*
 * Add a new user
 */
void add_user(user_chat_box_t *users, char *buf, int server_fd)
{
	/***** Insert YOUR code *******/
	
	/* 
	 * Check if user limit reached.
	 *
	 * If limit is okay, add user, set up non-blocking pipes and
	 * notify on server shell
	 *
	 * NOTE: You may want to remove any newline characters from the name string 
	 * before adding it. This will help in future name-based search.
	 */
	int i;
	pid_t pid;
	char* user_name = extract_name(ADD_USER, buf);
	char msg[MSG_SIZE];
	char arg1[MSG_SIZE];
	char arg2[MSG_SIZE];
	if (find_user_index(users, user_name) != -1){
		printf("%s already exists.\n", user_name);
		return;
	}
	else
	{
		if ((i = find_empty_slot(users)) == -1)
		{
			printf("Users are full.\n");
			return;
		}
		else
		{
			sprintf(msg, "Adding %s...\n", user_name);
			users[i].status = SLOT_FULL;
			strcpy(users[i].name, user_name);
			pipe(users[i].ptoc);
			pipe(users[i].ctop);
			fcntl(users[i].ptoc[0],F_SETFL, O_NONBLOCK);
			fcntl(users[i].ctop[0],F_SETFL, O_NONBLOCK);
			if (write(server_fd, msg, strlen(msg) + 1) < 0)
				perror("Writing to server shell");
		}
	}
	//Fork a child process to execute added user's Xterm
	if ((users[i].pid = fork()) < 0)
		perror("Add_user fork error");
	else if (users[i].pid == 0)
	{
		sprintf(arg1, "%d", users[i].ptoc[0]);
		sprintf(arg2, "%d", users[i].ctop[1]);
		execl(XTERM_PATH, XTERM, "+hold", "-e", "./shell", arg1, arg2, user_name, (char *)0);
	} 
	return;
}
예제 #3
0
/*
 * Send personal message. Print error on the user shell if user not found.
 */
void send_p2p_msg(int idx, user_chat_box_t *users, char *buf)
{
	/* get the target user by name (hint: call (extract_name() and send message */
	
	char *target_name;
	int target_idx;
	char *s;
	char text[MSG_SIZE];
	target_name = extract_name(P2P, buf);
	target_idx = find_user_index(users, target_name);
	s = strtok(NULL, SH_DELIMS); //extract the messege
	sprintf(text, "%s : %s", users[idx].name, s);
	write(users[target_idx].ptoc[1], text, strlen(text) + 1);
}
예제 #4
0
void apanha_objecto (int i, pid_t pid)
{
	int u, p;
	user_t c;

	u = find_user_index (pid);
	p = find_user_playing_index (pid);
	c = find_user (pid);

	// copiar o objecto da sala para o utilizador correspondente
	// tanto na lista de utilizadores como da dos que estao a jogar
	user_list[u].saco[user_list[u].n_obj] = labirinto[c.lin][c.col].objectos[i];
	user_list[u].peso_saco += labirinto[c.lin][c.col].objectos[i].peso;

	users_playing[p].saco[users_playing[p].n_obj] = labirinto[c.lin][c.col].objectos[i];
	users_playing[p].peso_saco += labirinto[c.lin][c.col].objectos[i].peso;

	user_list[i].n_obj++; users_playing[i].n_obj++;

	remove_object_sala (i, c.lin, c.col);	
}
예제 #5
0
void remove_object_saco (int i, pid_t pid)
{
	int j, u, p;
	user_t c;
	u = find_user_index (pid);
	p = find_user_playing_index (pid);
	c = find_user (pid);

	user_list[u].peso_saco -= user_list[u].saco[i].peso;

	for (j = i; j < c.n_obj-1; j++)
		user_list[u].saco[j] = user_list[u].saco[j+1];
	
	memset (&user_list[u].saco[c.n_obj], 0, sizeof (object_t));

	users_playing[p].peso_saco -= users_playing[p].saco[i].peso;
	for (j = i; j < c.n_obj-1; j++)
		users_playing[p].saco[j] = users_playing[p].saco[j+1];

	memset (&users_playing[p].saco[c.n_obj], 0, sizeof (object_t));

	user_list[u].n_obj--; users_playing[p].n_obj--;
}
예제 #6
0
int main(int argc, char **argv)
{

	user_chat_box_t user_list[MAX_USERS];
	server_ctrl_t server_shell;
	char arg1[MSG_SIZE];
	char arg2[MSG_SIZE];
	char command[MSG_SIZE];
	int cmd_num;
	char* str_pid;
	char* user_name;
	int k;
	int i;
	int idx;
	/* open non-blocking bi-directional pipes for communication with server shell */

	initialize_users(user_list);
	pipe(server_shell.ptoc);
	pipe(server_shell.ctop);
	fcntl(server_shell.ptoc[0],F_SETFL,O_NONBLOCK);
	fcntl(server_shell.ctop[0],F_SETFL,O_NONBLOCK);

	/* Fork the server shell */	
	pid_t pid = fork();
	if (pid < 0) 
		printf("Fork error.\n");
	else if (pid == 0)
	{
		sprintf(arg1, "%d", server_shell.ptoc[0]);
		sprintf(arg2, "%d", server_shell.ctop[1]);
		if(execl("./shell", "shell", arg1, arg2, "Server", (char *)0) < 0){
			perror("execl error");
		}
	}
		/* 
	 	 * Inside the child.
		 * Start server's shell.
	 	 * exec the SHELL program with the required program arguments.
	 	 */

	/* Inside the parent. This will be the most important part of this program. */

		/* Start a loop which runs every 1000 usecs.
	 	 * The loop should read messages from the server shell, parse them using the 
	 	 * parse_command() function and take the appropriate actions. */
	else 
	{	
		server_shell.pid = pid;
		while (1) 
		{
			/* Let the CPU breathe */
			usleep(1000);
			/* 
		 	 * 1. Read the message from server's shell, if any
		 	 * 2. Parse the command
		 	 * 3. Begin switch statement to identify command and take appropriate action
		 	 *
		 	 * 		List of commands to handle here:
		 	 * 			CHILD_PID
		 	 * 			LIST_USERS
		 	 * 			ADD_USER
		 	 * 			KICK
		 	 * 			EXIT
		 	 * 			BROADCAST 
		 	 */

			/* Fork a process if a user was added (ADD_USER) */
				/* Inside the child */
				/*
			 	 * Start an xterm with shell program running inside it.
			 	 * execl(XTERM_PATH, XTERM, "+hold", "-e", <path for the SHELL program>, ..<rest of the arguments for the shell program>..);
			 	 */
		 	if (read(server_shell.ctop[0], command, MSG_SIZE) > 0)
		 	{
		 		cmd_num = parse_command(command);
		 		switch (cmd_num)
		 		{
		 			case CHILD_PID:
		 				str_pid = extract_name(CHILD_PID, command);
		 				server_shell.child_pid = atoi(str_pid);
		 				break;
		 			case LIST_USERS:
		 				list_users(user_list, server_shell.ptoc[1]);
		 				break;
		 			case ADD_USER:
		 				add_user(user_list, command, server_shell.ptoc[1]);
		 				break;
		 			case KICK:
		 				user_name = extract_name(KICK, command);
		 				if ((idx = find_user_index(user_list, user_name)) == -1)
		 					break;
		 				cleanup_user(idx, user_list);
		 				break;
		 			case EXIT:
		 				cleanup_users(user_list);
		 				cleanup_server(server_shell);
		 				break;
		 			case BROADCAST:
		 				broadcast_msg(user_list, command, server_shell.ptoc[1], "Server");
		 				break;
		 		}
		 		if(cmd_num == EXIT)break;
		 	}
		 	
			/* Back to our main while loop for the "parent" */
			/* 
		 	 * Now read messages from the user shells (ie. LOOP) if any, then:
		 	 * 		1. Parse the command
		 	 * 		2. Begin switch statement to identify command and take appropriate action
		 	 *
		 	 * 		List of commands to handle here:
		 	 * 			CHILD_PID
		 	 * 			LIST_USERS
		 	 * 			P2P
		 	 * 			EXIT
		 	 * 			BROADCAST
		 	 *
		 	 * 		3. You may use the failure of pipe read command to check if the 
		 	 * 		user chat windows has been closed. (Remember waitpid with WNOHANG 
		 	 * 		from recitations?)
		 	 * 		Cleanup user if the window is indeed closed.
		 	 */
		 	int nsize;
		 	for (i = 0; i < MAX_USERS; i++)
		 	{
		 		if (user_list[i].status == SLOT_EMPTY)
					continue;
		 		if ((nsize = read(user_list[i].ctop[0], command, MSG_SIZE)) > 0)
		 		{
			 		cmd_num = parse_command(command);
			 		switch (cmd_num)
			 		{
			 			case CHILD_PID:
			 				str_pid = extract_name(CHILD_PID, command);
			 				user_list[i].child_pid = atoi(str_pid);
			 				break;
			 			case LIST_USERS:
			 				list_users(user_list, user_list[i].ptoc[1]);
			 				break;
			 			case P2P:
			 				send_p2p_msg(i, user_list, command);
			 				break;
			 			case EXIT:
			 				cleanup_user(i, user_list);
			 				break;
			 			case BROADCAST:
			 				broadcast_msg(user_list, command, server_shell.ptoc[1], user_list[i].name);
			 				break;
			 		}
		 		} else if(nsize == 0) {
		 			int status;
		 			if(waitpid(user_list[i].child_pid, &status, WNOHANG) < 0) {
		 				cleanup_user(i, user_list);
		 			}
		 		}
		 	}
		}
	}	/* while loop ends when server shell sees the \exit command */

	return 0;
}