Beispiel #1
0
static int broadcast_to_client(CLIENT_MAP *client)
{
	uint16_t fd_offset;
	uint16_t *fd;
	int i;
	int ret = 0;
	PROTO_HEAD *real_head;
	PROTO_HEAD_CONN_BROADCAST *head = (PROTO_HEAD_CONN_BROADCAST *)(client->buf);
	real_head = &head->real_head;
	fd_offset = htons(real_head->len) + offsetof(PROTO_HEAD_CONN_BROADCAST, real_head);
	fd = (uint16_t *)((char *)head + fd_offset);

	//check len
	if (fd_offset + sizeof(uint16_t) * head->num_fd != htons(head->len)) {
		log4c_category_log(mycat, LOG4C_PRIORITY_ERROR,
			"%s: broadcast len wrong [%u] [%u]", __FUNCTION__, htons(real_head->len), htons(head->len));
		return (-1);		
	}
	
	for (i = 0; i < head->num_fd; ++i) {
//		if (send(fd[i], real_head, htons(real_head->len), 0) != htons(real_head->len)) {
		if (send_one_msg(fd[i], real_head, 1) != htons(real_head->len)) {		
			log4c_category_log(mycat, LOG4C_PRIORITY_ERROR,
				"%s: broadcast to client[%u] failed err[%d]", __FUNCTION__, fd[i], errno);
			ret = (-1);
		}
	}
	return (ret);
}
Beispiel #2
0
static int send_logout_request(CLIENT_MAP *client)
{
	PROTO_HEAD_CONN *head;
	LOGOUT_REQUEST *req;
	char sendbuf[sizeof(PROTO_HEAD_CONN) + sizeof(LOGOUT_REQUEST)];
	head = (PROTO_HEAD_CONN *)(&sendbuf[0]);
	req = (LOGOUT_REQUEST *)(&sendbuf[sizeof(PROTO_HEAD_CONN)]);
	head->msg_id = htons(CS__MESSAGE__ID__LOGOUT_REQUEST);
	head->len = htons(sizeof(sendbuf));
	head->fd = client->fd;
	req->reason = 0;
	CLIENT_MAP *server;
	
	server = get_first_client_map(&server_map_head);	
	if (unlikely(!server)) {
		log4c_category_log(mycat, LOG4C_PRIORITY_ERROR,
			"%s: do not have game server connected", __FUNCTION__);
		if (cache_to_gamesrv_buf((PROTO_HEAD *)head) != 0) {
			log4c_category_log(mycat, LOG4C_PRIORITY_ERROR,
				"%s: cache_to_gamesrv_buf failed", __FUNCTION__);			
		}
		return (0);
	}
	
	if (send_one_msg(server->fd, (PROTO_HEAD *)head, 0) != htons(head->len)) {
		log4c_category_log(mycat, LOG4C_PRIORITY_ERROR,
			"%s: send to gameserver failed err[%d]", __FUNCTION__, errno);
		return (-1);
	}
	return (0);
}
Beispiel #3
0
int fetch_role_handle(PROTO_HEAD *head, uint16_t fd, int len)
{
//	int i;
	MYSQL_RES *res;
	MYSQL_ROW row;	
	char sql[256];
	FETCH_ROLE_DATA_RESPONSE *resp;	
	char sendbuf[sizeof(PROTO_HEAD) + sizeof(*resp)];
	FETCH_ROLE_DATA_REQUEST *request = (FETCH_ROLE_DATA_REQUEST *)head->data;
	

	resp = (FETCH_ROLE_DATA_RESPONSE *)(&sendbuf[sizeof(PROTO_HEAD)]);
	head = (PROTO_HEAD *)(&sendbuf[0]);

	resp->info.name[0] = '\0';
	
	if (len != sizeof(PROTO_HEAD) + sizeof(FETCH_ROLE_DATA_REQUEST)) {
		log4c_category_log(mycat, LOG4C_PRIORITY_INFO, "%s: len[%d] with msg[%u] server[?] fail\n",
			__FUNCTION__, head->len, head->msg_id);
		return (-1);
	}
	sprintf(sql, "select id, name, profession, level, scene_id, pos_x, pos_y from DBRoleInfo where id = %lu", request->id);
	res = query(sql, 1, NULL);
	if (!res) {
		log4c_category_log(mycat, LOG4C_PRIORITY_INFO, "%s: can not fetch role %lu\n",
			__FUNCTION__, request->id);
		resp->result = -1;
		goto done;
	}
	row = fetch_row(res);
	if (!row) {
		log4c_category_log(mycat, LOG4C_PRIORITY_INFO, "%s: can not fetch role %lu\n",
			__FUNCTION__, request->id);
		resp->result = -1;
		goto done;		
	}
	resp->result = 0;
	strcpy(resp->info.name, row[1]);
	resp->info.profession = atoi(row[2]);
	resp->info.level = atoi(row[3]);
	resp->info.scene_id = atoi(row[4]);
	resp->info.pos.pos_x = atoi(row[5]);
	resp->info.pos.pos_y = atoi(row[6]);				

//	resp->bag.max_thing_num = 10;
done:
	if (res)
		free_query(res);
	resp->id = request->id;
	head->len = htons(sizeof(sendbuf));
	head->msg_id = htons(SERVER_PROTO_FETCH_ROLE_RESPONSE);
	send_one_msg(fd, head);
//	send(fd, sendbuf, sizeof(sendbuf), 0);	
	return (0);
}
Beispiel #4
0
/**
 *\brief 通过网络发送数据得发送函数,非阻塞的请求模式,需要上层自己控制。
 *\param fs 定义了套接子得相关属性。
 *\param msg 定义了需要发送得消息。
 *\param mlen 定义了需要发送得消息得长度。
 *\param timeout_usec 定义消息发送得超时时间。
 *\retval E_OK 表示成功。
 */
e_int32 fsocket_send(fsocket_t *fs, e_uint8 *msg, e_uint32 mlen,
		e_uint32 timeout_usec) {
	e_int32 ret;
	e_assert(fs&&fs->state, E_ERROR_INVALID_HANDLER);
	ret = semaphore_timeoutwait(&fs->send_sem, timeout_usec);
	e_assert(ret, E_ERROR_INVALID_CALL);
	ret = send_one_msg(fs, msg, mlen, timeout_usec);
	//处理完成,提醒可以发下一个请求了,非阻塞的请求模式
	semaphore_post(&fs->send_sem);
	return ret;
}
Beispiel #5
0
int send_to_game_srv(int fd, PROTO_HEAD *head)
{
	if (send_one_msg(fd, head, 0) != htons(head->len)) {
		log4c_category_log(mycat, LOG4C_PRIORITY_INFO,
			"%s: failed, cache it", __FUNCTION__);
		if (cache_to_gamesrv_buf(head) != 0) {
			log4c_category_log(mycat, LOG4C_PRIORITY_ERROR,
				"%s: cache_to_gamesrv_buf failed", __FUNCTION__);			
		}
		return (-1);
	}
	return (0);
}
Beispiel #6
0
static int send_all_cached_gamesrv_buf(int fd)
{
	PROTO_HEAD *head;
	int i;
	int len;

	if (cached_len <= 0)
		return (0);
	
	for (i = 0; i < cached_len; i += len) {
		head = (PROTO_HEAD *)&cached_buf[i];
		len = htons(head->len);
		if (send_one_msg(fd, head, 0) != len) {
			log4c_category_log(mycat, LOG4C_PRIORITY_ERROR,
				"%s: send to gameserver failed err[%d]", __FUNCTION__, errno);
			cached_len = 0;
			return (-1);
		}
	}
	cached_len = 0;
	return (0);
}
Beispiel #7
0
static int transfer_to_client(CLIENT_MAP *client)
{
	uint16_t old_len, old_msgid;
	PROTO_HEAD *head;	
	PROTO_HEAD_CONN *head_conn;
	uint16_t fd;
	assert(client);
	head = (PROTO_HEAD *)(client->buf + sizeof(uint16_t));
	head_conn = (PROTO_HEAD_CONN *)(client->buf);

	if (head_conn->msg_id == SERVER_PROTO_BROADCAST)
		return broadcast_to_client(client);
	else if (htons(head_conn->msg_id) == SERVER_PROTO_KICK_ROLE_NOTIFY)
		return kick_role(client);
	
	fd = head_conn->fd;

	old_len = htons(head_conn->len);
	old_msgid = htons(head_conn->msg_id);
	head->msg_id = head_conn->msg_id;
	head->len = htons(old_len - sizeof(uint16_t));

	if (old_len == 0) {
		log4c_category_log(mycat, LOG4C_PRIORITY_ERROR,
			"%s: len wrong drop all msg", __FUNCTION__);
		return (-1);
	}

//	int ret = send(fd, head, htons(head->len), 0);
	int ret = send_one_msg(fd, head, 1);
	if (ret != htons(head->len)) {
		log4c_category_log(mycat, LOG4C_PRIORITY_ERROR,
			"%s: send to client failed err[%d]", __FUNCTION__, errno);
		return (0);
	}
	head_conn->len = htons(old_len);
	head_conn->msg_id = htons(old_msgid);	
	return (0);
}
Beispiel #8
0
int create_role_handle(PROTO_HEAD *head, uint16_t fd, int len)
{
	uint64_t effect = 0;
	CREATE_ROLE_REQUEST *req = (CREATE_ROLE_REQUEST *)&head->data;
	CREATE_ROLE_RESPONSE *resp;
	
	char sendbuf[sizeof(PROTO_HEAD) + sizeof(*resp)];
	char sql[256];
	char *p = sql;

	resp = (CREATE_ROLE_RESPONSE *)(&sendbuf[sizeof(PROTO_HEAD)]);
	head = (PROTO_HEAD *)(&sendbuf[0]);
	
	p += sprintf(sql, "insert into DBRoleInfo set id = %lu, profession = %u, scene_id = 1, pos_x = 1000, pos_y = 500, name = \'",
		req->id, req->profession);
	p += escape_string(p, req->name, strlen(req->name));
	*p++ = '\'';
	*p++ = '\0';
	query(sql, 1, &effect);	
	if (effect != 1) {
		log4c_category_log(mycat, LOG4C_PRIORITY_INFO, "%s: execute query for %u %s failed\n",
			__FUNCTION__, req->id, req->name);
		resp->result = -1;
		goto done;
	}
	resp->result = 0;
	memcpy(resp->info.name, req->name, sizeof(resp->info.name));	
	resp->info.profession = req->profession;
	resp->info.level = 1;
	resp->info.scene_id = 1;
	resp->info.pos.pos_x = 1000;
	resp->info.pos.pos_y = 500;
done:
	head->len = htons(sizeof(sendbuf));
	head->msg_id = htons(SERVER_PROTO_CREATE_ROLE_RESPONSE);
	resp->id = req->id;
	send_one_msg(fd, head);
	return (0);
}
Beispiel #9
0
static int transfer_to_gameserver(CLIENT_MAP *client)
{
	uint16_t old_len;
	PROTO_HEAD *head;
	PROTO_HEAD_CONN *head_conn;
	CLIENT_MAP *server;	
	assert(client);
	head = (PROTO_HEAD *)CLIENT_MAP_BUF_HEAD(client);
	head_conn = (PROTO_HEAD_CONN *)(client->buf);
	old_len = htons(head->len);
	
	head_conn->len = htons(old_len + sizeof(uint16_t));
	head_conn->msg_id = head->msg_id;	
	head_conn->fd = client->fd;

	server = get_first_client_map(&server_map_head);
	
	if (unlikely(!server)) {
		log4c_category_log(mycat, LOG4C_PRIORITY_INFO,
			"%s: do not have game server connected, cache it", __FUNCTION__);
		if (cache_to_gamesrv_buf((PROTO_HEAD *)head_conn) != 0) {
			log4c_category_log(mycat, LOG4C_PRIORITY_ERROR,
				"%s: cache_to_gamesrv_buf failed", __FUNCTION__);			
		}
		goto done;
	}
	
	if (send_one_msg(server->fd, (PROTO_HEAD *)head_conn, 0) != htons(head_conn->len)) {		
		log4c_category_log(mycat, LOG4C_PRIORITY_ERROR,
			"%s: send to gameserver failed err[%d]", __FUNCTION__, errno);
		goto done;
	}
done:
	head->len = htons(old_len);
	return (0);
}
Beispiel #10
0
/**
 *\brief 网络连接发送请求函数。
 *\param fs 定义了套接子得相关属性。
 *\param msg 定义了发送请求消息。
 *\param mlen 定义了发送请求消息长度。
 *\param recv_buf 定义了接收缓存。
 *\param recv_len 定义了接收消息长度。
 *\param timeout_usec 定义了接收消息超时时间。
 *\retval E_OK 表示成功。
 */
e_int32 fsocket_request(fsocket_t *fs, e_uint8 *msg, e_uint32 mlen,
		e_uint8 *recv_buf, e_uint32 recv_len, e_uint32 timeout_usec) {
	e_int32 ret;
	e_uint8 req_id;
	e_uint8 s_id;
	int req_iid = -1, s_iid = -1;

	/* Timeval structs for handling timeouts */
	e_uint32 beg_time, elapsed_time;

	e_assert(fs&&fs->state, E_ERROR_INVALID_HANDLER);

//	DMSG((STDOUT, "FAKE SOCKE [%s:%u] try request,current rq_id=%u...\r\n", fs->name, (unsigned int) fs->id,(unsigned int) fs->rq_id));

	//请求发送锁
	ret = semaphore_timeoutwait(&fs->send_sem, timeout_usec);
	e_assert(ret, E_ERROR_LOCK_FAILED);

	/* Acquire the elapsed time since epoch */
	beg_time = GetTickCount();

	//发送请求
	ret = send_one_msg(fs, msg, mlen, timeout_usec);
	if (e_failed(ret))
		goto END;

	//等待回复
	elapsed_time = GetTickCount() - beg_time;

	while (timeout_usec <= 0
			|| (elapsed_time = GetTickCount() - beg_time) < timeout_usec) {
		if (timeout_usec <= 0) //没有设置超时,死等
				{
			ret = wait_for_reply_forever(fs);
		} else {
			ret = wait_for_reply(fs, timeout_usec - elapsed_time);
		}
		if (!e_failed(ret)) {
			//取出消息,和请求号
			recv_len = recv_len >= MSG_MAX_LEN ? MSG_MAX_LEN : recv_len;
			sscanf(fs->buf, "#%02X%02X%[^@]", &s_iid, &req_iid, recv_buf);
			s_id = s_iid & 0xFF;
			req_id = req_iid & 0xFF;
			//TODO:无视过时消息?
			if (req_id < fs->rq_id) {
				DMSG((STDOUT, "FAKE SOCKE [%s:%u:%u] 取到过时消息:id=%u \n忽略,继续等待下一个消息\n", fs->name, (unsigned int) fs->id, (unsigned int) fs->rq_id, (unsigned int) req_id));
				continue;
			} else if (req_id > fs->rq_id) {
//				DMSG((STDOUT,"出现消息号异常,请检查!\n"));
//				while (1)
//					;
			}
			break;
		}
		break;
	}

	END:
	//处理完成,提醒可以发下一个请求了
	ret = semaphore_post(&fs->send_sem);
	e_assert(ret, E_ERROR_TIME_OUT);
//	DMSG(
//	(STDOUT, "[%s_%u_%u]FAKE SOCKET release send sem...\r\n", fs->name, (unsigned int)fs->id,(unsigned int)fs->rq_id));

	elapsed_time = GetTickCount() - beg_time;
	if (MSG_LEVEL_VERBOSE)
		DMSG((STDOUT, "FAKE SOCKET [%s:%u:%u]  request done in %u Ms...\r\n", fs->name, (unsigned int) fs->id, req_id, (int) (elapsed_time
				/ 1000)));
	return E_OK;
}