Пример #1
0
/**
 * Receiving a sex change request (sex is reversed).
 * @param fd: fd to parse from (char-serv)
 * @param id: id of char-serv
 * @param ip: char-serv ip (used for info)
 * @return 0 not enough info transmitted, 1 success
 */
int logchrif_parse_reqchgsex(int fd, int id, char* ip){
	if( RFIFOREST(fd) < 6 )
		return 0;
	else{
		struct mmo_account acc;
		AccountDB* accounts = login_get_accounts_db();

		uint32 account_id = RFIFOL(fd,2);
		RFIFOSKIP(fd,6);

		if( !accounts->load_num(accounts, &acc, account_id) )
			ShowNotice("Char-server '%s': Error of sex change (account: %d not found, ip: %s).\n", ch_server[id].name, account_id, ip);
		else if( acc.sex == 'S' )
			ShowNotice("Char-server '%s': Error of sex change - account to change is a Server account (account: %d, ip: %s).\n", ch_server[id].name, account_id, ip);
		else{
			unsigned char buf[7];
			char sex = ( acc.sex == 'M' ) ? 'F' : 'M'; //Change gender

			ShowNotice("Char-server '%s': Sex change (account: %d, new sex %c, ip: %s).\n", ch_server[id].name, account_id, sex, ip);

			acc.sex = sex;
			// Save
			accounts->save(accounts, &acc);

			// announce to other servers
			WBUFW(buf,0) = 0x2723;
			WBUFL(buf,2) = account_id;
			WBUFB(buf,6) = sex_str2num(sex);
			logchrif_sendallwos(-1, buf, 7);
		}
	}
	return 1;
}
Пример #2
0
size_t to_server_list_result(char* buf, const Packet* packet)
{
	ServerListHeader* header = (ServerListHeader*)packet->param.Data;
	uint16 count = header->server_count;
	size_t res = 47 + 32 * count;
	memset(buf, 0, res);

	PUINT16(buf, 0) = 0x69; // opcode.
	PUINT16(buf, 2) = res; // length :-)

	uint32 id1 = header->id1;
	uint32 id2 = header->id2;
	uint32 account = header->account;
	uint8 sex = header->sex;
	uint32 ip = header->ip;

	PUINT32(buf, 4) = id1;
	PUINT32(buf, 8) = account;
	PUINT32(buf, 12) = id2;
	PUINT32(buf, 16) = 0;

	PUINT16(buf, 44) = 0; // unknown
	PUINT8(buf, 46) = sex_str2num(sex);

	int i = 0;
	for (; i < count; ++i)
	{
		ServerInfo* info = (ServerInfo*)(packet->param.Data + sizeof(ServerListHeader) + sizeof(ServerInfo) * i);
		uint32 subnet_char_ip = lan_subnetcheck(ip);
		PUINT32(buf, 47 + i * 32) = htonl((subnet_char_ip) ? subnet_char_ip : info->ip);
		printf("IP of Server : %d.%d.%d.%d.\n", CONVIP(info->ip));
		printf("Port of Server : %d\n", info->port);

		PUINT16(buf, 47 + i * 32 + 4) = ntows(htons(info->port));

		memcpy(PCHAR(buf, 47 + i * 32 + 6), info->name, 20);
		PUINT16(buf, 47 + i * 32 + 26) = info->users;// users
		PUINT16(buf, 47 + i * 32 + 28) = info->maintenance; // maintenance
		PUINT16(buf, 47 + i * 32 + 30) = info->new_; // new_
	}
	return res;
}
Пример #3
0
/**
 * Auth successful, inform client and create a temp auth_node.
 * @param sd: player session
 */
static void logclif_auth_ok(struct login_session_data* sd) {
	int fd = sd->fd;
	uint32 ip = session[fd]->client_addr;

	uint8 server_num, n;
	uint32 subnet_char_ip;
	struct auth_node* node;
	int i;

#if PACKETVER < 20170315
	int cmd = 0x69; // AC_ACCEPT_LOGIN
	int header = 47;
	int size = 32;
#else
	int cmd = 0xac4; // AC_ACCEPT_LOGIN3
	int header = 64;
	int size = 160;
#endif

	if( runflag != LOGINSERVER_ST_RUNNING ){
		// players can only login while running
		logclif_sent_auth_result(fd,1); // server closed
		return;
	}

	if( login_config.group_id_to_connect >= 0 && sd->group_id != login_config.group_id_to_connect ) {
		ShowStatus("Connection refused: the required group id for connection is %d (account: %s, group: %d).\n", login_config.group_id_to_connect, sd->userid, sd->group_id);
		logclif_sent_auth_result(fd,1); // server closed
		return;
	} else if( login_config.min_group_id_to_connect >= 0 && login_config.group_id_to_connect == -1 && sd->group_id < login_config.min_group_id_to_connect ) {
		ShowStatus("Connection refused: the minimum group id required for connection is %d (account: %s, group: %d).\n", login_config.min_group_id_to_connect, sd->userid, sd->group_id);
		logclif_sent_auth_result(fd,1); // server closed
		return;
	}

	server_num = 0;
	for( i = 0; i < ARRAYLENGTH(ch_server); ++i )
		if( session_isActive(ch_server[i].fd) )
			server_num++;

	if( server_num == 0 )
	{// if no char-server, don't send void list of servers, just disconnect the player with proper message
		ShowStatus("Connection refused: there is no char-server online (account: %s).\n", sd->userid);
		logclif_sent_auth_result(fd,1); // server closed
		return;
	}

	{
		struct online_login_data* data = (struct online_login_data*)idb_get(online_db, sd->account_id);
		if( data )
		{// account is already marked as online!
			if( data->char_server > -1 )
			{// Request char servers to kick this account out. [Skotlex]
				uint8 buf[6];
				ShowNotice("User '%s' is already online - Rejected.\n", sd->userid);
				WBUFW(buf,0) = 0x2734;
				WBUFL(buf,2) = sd->account_id;
				logchrif_sendallwos(-1, buf, 6);
				if( data->waiting_disconnect == INVALID_TIMER )
					data->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, login_waiting_disconnect_timer, sd->account_id, 0);
				logclif_sent_auth_result(fd,8); // 08 = Server still recognizes your last login
				return;
			}
			else
			if( data->char_server == -1 )
			{// client has authed but did not access char-server yet
				// wipe previous session
				idb_remove(auth_db, sd->account_id);
				login_remove_online_user(sd->account_id);
				data = NULL;
			}
		}
	}

	login_log(ip, sd->userid, 100, "login ok");
	ShowStatus("Connection of the account '%s' accepted.\n", sd->userid);

	WFIFOHEAD(fd,header+size*server_num);
	WFIFOW(fd,0) = cmd;
	WFIFOW(fd,2) = header+size*server_num;
	WFIFOL(fd,4) = sd->login_id1;
	WFIFOL(fd,8) = sd->account_id;
	WFIFOL(fd,12) = sd->login_id2;
	WFIFOL(fd,16) = 0; // in old version, that was for ip (not more used)
	//memcpy(WFIFOP(fd,20), sd->lastlogin, 24); // in old version, that was for name (not more used)
	memset(WFIFOP(fd,20), 0, 24);
	WFIFOW(fd,44) = 0; // unknown
	WFIFOB(fd,46) = sex_str2num(sd->sex);
#if PACKETVER >= 20170315
	memset(WFIFOP(fd,47),0,17); // Unknown
#endif
	for( i = 0, n = 0; i < ARRAYLENGTH(ch_server); ++i ) {
		if( !session_isValid(ch_server[i].fd) )
			continue;
		subnet_char_ip = lan_subnetcheck(ip); // Advanced subnet check [LuzZza]
		WFIFOL(fd,header+n*size) = htonl((subnet_char_ip) ? subnet_char_ip : ch_server[i].ip);
		WFIFOW(fd,header+n*size+4) = ntows(htons(ch_server[i].port)); // [!] LE byte order here [!]
		memcpy(WFIFOP(fd,header+n*size+6), ch_server[i].name, 20);
		WFIFOW(fd,header+n*size+26) = ch_server[i].users;
		WFIFOW(fd,header+n*size+28) = ch_server[i].type;
		WFIFOW(fd,header+n*size+30) = ch_server[i].new_;
#if PACKETVER >= 20170315
		memset(WFIFOP(fd, header+n*size+32), 0, 128); // Unknown
#endif
		n++;
	}
	WFIFOSET(fd,header+size*server_num);

	// create temporary auth entry
	CREATE(node, struct auth_node, 1);
	node->account_id = sd->account_id;
	node->login_id1 = sd->login_id1;
	node->login_id2 = sd->login_id2;
	node->sex = sd->sex;
	node->ip = ip;
	node->clienttype = sd->clienttype;
	idb_put(auth_db, sd->account_id, node);
	{
		struct online_login_data* data;
		// mark client as 'online'
		data = login_add_online_user(-1, sd->account_id);
		// schedule deletion of this node
		data->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, login_waiting_disconnect_timer, sd->account_id, 0);
	}
}