Пример #1
0
/*********************************************************************
 Callback from client listening to server in its own thread
 Only used for data transfers
 *********************************************************************/
static int async_data_recv(void * p_pData)
{
	context_t * l_pContext = (context_t *) p_pData;

	while (true)
	{
		uint32_t l_FrameSize = 0U;

		if (network_read_bytes(l_pContext->socket_data, (char *) &l_FrameSize,
				sizeof(uint32_t)) == RET_NOK)
		{
			break;
		}

		{
			l_FrameSize = ntohl(l_FrameSize);
			wlog(LOGDEVELOPER, "received on data %u bytes long frame on socket %u",
					l_FrameSize, l_pContext->socket_data);

			NetworkFrame l_Frame(l_FrameSize);

			if (network_read_bytes(l_pContext->socket_data,
					(char *) l_Frame.getFrame(), l_FrameSize) == RET_NOK)
			{
				break;
			}
			if (parse_incoming_data(l_pContext, l_Frame) == RET_NOK)
			{
				break;
			}
		}
	}

	werr(LOGUSER, "Socket closed on server side.");

	context_set_connected(l_pContext, false);
	SDLNet_TCP_Close(l_pContext->socket);
	SDLNet_TCP_Close(l_pContext->socket_data);
	context_set_socket(l_pContext, 0);
	context_set_socket_data(l_pContext, 0);

	screen_quit();

	return 0;
}
Пример #2
0
/*****************************
 Disconnect a character.
 This kill a NPC AI thread
return -1 if fails
*****************************/
int character_disconnect( const char * id)
{
	context_t * ctx;

	werr(LOGDEBUG,"Disconnecting %s",id);

	ctx = context_find(id);
	context_set_in_game(ctx,false);
	context_set_connected(ctx,false);
	context_spread(ctx);

	if( context_is_npc(ctx) == true ) {
		/* Wake up NPC */
		if( SDL_TryLockMutex (ctx->cond_mutex) == 0 ) {
			SDL_CondSignal (ctx->cond);
			SDL_UnlockMutex (ctx->cond_mutex);
		}
	}

	return 0;
}
Пример #3
0
/**************************************
Return RET_NOK on error
**************************************/
ret_code_t parse_incoming_data(context_t * context, Uint32 command, Uint32 command_size, char * data)
{
	char * value = NULL;
	char * fullname;
	char * elements[512];
	char * cksum;
	int i;
	char * user_name;
	char * password;

	if( !context_get_connected(context) && ( command != CMD_REQ_LOGIN  && command != CMD_REQ_FILE) ) {
		werr(LOGUSER,"Request from not authenticated client, close connection");
		return RET_NOK;
	}

	switch(command) {
	case CMD_REQ_LOGIN:
		wlog(LOGDEBUG,"Received CMD_REQ_LOGIN");
		user_name = _strsep(&data,NETWORK_DELIMITER);
		password = _strsep(&data,NETWORK_DELIMITER);

		if(entry_read_string(PASSWD_TABLE, user_name, &value, PASSWD_KEY_PASSWORD,NULL) == RET_NOK) {
			return RET_NOK;
		}
		if( strcmp(value, password) != 0) {
			free(value);
			werr(LOGUSER,"Wrong login for %s",user_name);
			// send answer
			network_send_command(context, CMD_SEND_LOGIN_NOK, 0, NULL, false);
			// force client disconnection
			return RET_NOK;
		} else {
			free(value);

			if( context_set_username(context, user_name) == RET_NOK ) {
				return RET_NOK;
			}
			context_set_connected(context, true);

			// send answer
			network_send_command(context, CMD_SEND_LOGIN_OK, 0, NULL, false);
			wlog(LOGUSER,"Login successful for user %s",context->user_name);
		}
		break;
	case CMD_REQ_CHARACTER_LIST :
		wlog(LOGDEBUG,"Received CMD_REQ_CHARACTER_LIST");
		character_send_list(context);
		wlog(LOGDEBUG,"character list sent");
		break;
	case CMD_REQ_FILE :
		i = 0;
		elements[i] = _strsep(&data,NETWORK_DELIMITER);
		while(elements[i]) {
			i++;
			elements[i] = _strsep(&data,NETWORK_DELIMITER);
		}

		if(elements[0]==NULL || elements[1]==NULL) {
			werr(LOGDEV,"Received erroneous CMD_REQ_FILE");
			break;
		}
		wlog(LOGDEBUG,"Received CMD_REQ_FILE for %s",elements[0]);
		/* compare checksum */
		fullname = strconcat(base_directory,"/",elements[0],NULL);

		cksum = checksum_file(fullname);
		free(fullname);

		if( cksum == NULL) {
			werr(LOGUSER,"Required file %s doesn't exists",elements[0]);
			break;
		}

		if( strcmp(elements[1],cksum) == 0 ) {
			wlog(LOGDEBUG,"Client has already newest %s file",elements[0]);
			free(cksum);
			break;
		}
		free(cksum);

		network_send_file(context,elements[0]);
		wlog(LOGDEBUG,"File %s sent",elements[0]);
		break;
	case CMD_REQ_USER_CHARACTER_LIST :
		wlog(LOGDEBUG,"Received CMD_REQ_USER_CHARACTER_LIST");
		character_user_send_list(context);
		wlog(LOGDEBUG,"user %s's character list sent",context->user_name);
		break;
	case CMD_REQ_START :
		if( context->in_game == false ) {
			context->id = strdup(data);
			context->in_game = true;
			context_update_from_file(context);
			context_spread(context);
			context_request_other_context(context);
		}
		wlog(LOGDEBUG,"Received CMD_REQ_START for %s /%s",context->user_name,context->id);
		break;
	case CMD_REQ_STOP :
		wlog(LOGDEBUG,"Received CMD_REQ_STOP for %s /%s",context->user_name,context->id);
		if( context->in_game == true ) {
			context->in_game = false;
			if( context->map ) {
				free(context->map);
			}
			context->map = NULL;
			if( context->prev_map ) {
				free(context->prev_map);
			}
			context->prev_map = NULL;
			if( context->id ) {
				free(context->id);
			}
			context->id = NULL;
			context_spread(context);
		}
		break;
	case CMD_REQ_ACTION :
		i = 0;
		elements[i] = NULL;
		elements[i] = _strsep(&data,NETWORK_DELIMITER);
		while(elements[i]) {
			i++;
			elements[i] = _strsep(&data,NETWORK_DELIMITER);
		}
		elements[i+1] = NULL;

		wlog(LOGDEBUG,"Received CMD_REQ_ACTION %s from %s /%s",elements[0],context->user_name,context->character_name);

		action_execute(context,elements[0],&elements[1]);
		break;
	default:
		werr(LOGDEV,"Unknown request %d from client",command);
		return RET_NOK;
	}

	return RET_OK;
}
Пример #4
0
/**************************************
Called from client
**************************************/
void context_add_or_update_from_network_frame(context_t * context,char * data)
{
	context_t * ctx = NULL;
	char * user_name = NULL;
	char * name = NULL;
	char * map = NULL;
	int in_game;
	bool connected;
	int pos_tx;
	int pos_ty;
	char * type = NULL;
	char * id = NULL;
	char * selected_character = NULL;
	char * selected_map = NULL;
	int selected_map_x = 0;
	int selected_map_y = 0;
	char * selected_equipment = NULL;
	char * selected_item = NULL;

	/* First decode the data */

	user_name = strdup(data);
	data += (strlen(data)+1);

	name = strdup(data);
	data += (strlen(data)+1);

	map = strdup(data);
	data += (strlen(data)+1);

	in_game = atoi(data);
	data += (strlen(data)+1);

	connected = atoi(data);
	data += (strlen(data)+1);

	pos_tx = atoi(data);
	data += (strlen(data)+1);

	pos_ty = atoi(data);
	data += (strlen(data)+1);

	type = strdup(data);
	data += (strlen(data)+1);

	id = strdup(data);
	data += (strlen(data)+1);

	selected_character = strdup(data);
	data += (strlen(data)+1);

	selected_map = strdup(data);
	data += (strlen(data)+1);

	selected_map_x = atoi(data);
	data += (strlen(data)+1);

	selected_map_y = atoi(data);
	data += (strlen(data)+1);

	selected_equipment = strdup(data);
	data += (strlen(data)+1);

	selected_item = strdup(data);
	data += (strlen(data)+1);

	/* search for this context */
	context_lock_list();
	ctx = context_list_start;

	while( ctx != NULL ) {
		if( strcmp( id, ctx->id) == 0 ) {
			ctx->in_game = in_game;
			ctx->connected = connected;

			if( in_game == true ) {
				wlog(LOGDEBUG,"Updating context %s / %s",user_name,name);
				/* do not call context_set_* function since we already have the lock */
				_context_set_map(ctx,map);

				_context_set_pos_tx(ctx,pos_tx);
				_context_set_pos_ty(ctx,pos_ty);

				free(ctx->type);
				ctx->type = strdup(type);

				if( ctx->selection.map ) {
					free(ctx->selection.map );
				}
				ctx->selection.map = strdup(selected_map);
				ctx->selection.map_coord[0] = selected_map_x;
				ctx->selection.map_coord[1] = selected_map_y;

				if( ctx->selection.id ) {
					free(ctx->selection.id );
				}
				ctx->selection.id = strdup(selected_character);

				if( ctx->selection.equipment ) {
					free(ctx->selection.equipment );
				}
				ctx->selection.equipment = strdup(selected_equipment);

				if( ctx->selection.inventory ) {
					free(ctx->selection.inventory );
				}
				ctx->selection.inventory = strdup(selected_item);
			}

			if( connected == false ) {
				wlog(LOGDEBUG,"Deleting context %s / %s",user_name,name);
				context_free(ctx);
			}
			context_unlock_list();

			goto  context_add_or_update_from_network_frame_free;
		}
		ctx = ctx->next;
	}

	context_unlock_list();

	wlog(LOGDEBUG,"Creating context %s / %s",user_name,name);
	ctx = context_new();
	context_set_username(ctx,user_name);
	context_set_character_name(ctx,name);
	context_set_map(ctx,map);
	context_set_type(ctx,type);
	context_set_pos_tx(ctx,pos_tx);
	context_set_pos_ty(ctx,pos_ty);
	context_set_id(ctx,id);
	context_set_connected(ctx,connected);
	context_set_in_game(ctx,in_game);
	context_set_selected_character(ctx,selected_character);
	context_set_selected_tile(ctx,selected_map,selected_map_x,selected_map_y);
	context_set_selected_equipment(ctx,selected_equipment);
	context_set_selected_item(ctx,selected_item);

context_add_or_update_from_network_frame_free:
	free(user_name);
	free(name);
	free(map);
	free(type);
	free(id);
	free(selected_character);
	free(selected_map);
	free(selected_equipment);
	free(selected_item);
}