Пример #1
0
int recv_to_fifo(int fd)
{
	int len;

	if( !session_isActive(fd) )
		return -1;

	len = sRecv(fd, (char *) session[fd]->rdata + session[fd]->rdata_size, (int)RFIFOSPACE(fd), 0);

	if( len == SOCKET_ERROR )
	{//An exception has occured
		if( sErrno != S_EWOULDBLOCK ) {
			//ShowDebug("recv_to_fifo: code %d, closing connection #%d\n", sErrno, fd);
			set_eof(fd);
		}
		return 0;
	}

	if( len == 0 )
	{//Normal connection end.
		set_eof(fd);
		return 0;
	}

	session[fd]->rdata_size += len;
	session[fd]->rdata_tick = last_tick;
	return 0;
}
Пример #2
0
int chlogif_parse_ackaccreq(int fd, struct char_session_data* sd){
	if (RFIFOREST(fd) < 21)
		return 0;
	{
		uint32 account_id = RFIFOL(fd,2);
		uint32 login_id1 = RFIFOL(fd,6);
		uint32 login_id2 = RFIFOL(fd,10);
		uint8 sex = RFIFOB(fd,14);
		uint8 result = RFIFOB(fd,15);
		int request_id = RFIFOL(fd,16);
		uint8 clienttype = RFIFOB(fd,20);
		RFIFOSKIP(fd,21);

		if( session_isActive(request_id) && (sd=(struct char_session_data*)session[request_id]->session_data) &&
			!sd->auth && sd->account_id == account_id && sd->login_id1 == login_id1 && sd->login_id2 == login_id2 && sd->sex == sex )
		{
			int client_fd = request_id;
			sd->clienttype = clienttype;

			switch( result )
			{
			case 0:// ok
				char_auth_ok(client_fd, sd);
				break;
			case 1:// auth failed
				chclif_reject(client_fd,0); // rejected from server
				break;
			}
		}
	}
	return 1;
}
Пример #3
0
/**
 * Player requesting to change map-serv
 * @param fd: wich fd to parse from
 * @return : 0 not enough data received, 1 success
 */
int chmapif_parse_reqchangemapserv(int fd){
	if (RFIFOREST(fd) < 39)
		return 0;
	{
		int map_id, map_fd = -1;
		struct mmo_charstatus* char_data;
		struct mmo_charstatus char_dat;
		DBMap* char_db_ = char_get_chardb();

		map_id = char_search_mapserver(RFIFOW(fd,18), ntohl(RFIFOL(fd,24)), ntohs(RFIFOW(fd,28))); //Locate mapserver by ip and port.
		if (map_id >= 0)
			map_fd = map_server[map_id].fd;
		//Char should just had been saved before this packet, so this should be safe. [Skotlex]
		char_data = (struct mmo_charstatus*)uidb_get(char_db_,RFIFOL(fd,14));
		if (char_data == NULL) {	//Really shouldn't happen.
			char_mmo_char_fromsql(RFIFOL(fd,14), &char_dat, true);
			char_data = (struct mmo_charstatus*)uidb_get(char_db_,RFIFOL(fd,14));
		}

		if( runflag == CHARSERVER_ST_RUNNING &&
			session_isActive(map_fd) &&
			char_data )
		{	//Send the map server the auth of this player.
			struct online_char_data* data;
			struct auth_node* node;
			DBMap*  auth_db = char_get_authdb();
			DBMap* online_char_db = char_get_onlinedb();

			int aid = RFIFOL(fd,2);

			//Update the "last map" as this is where the player must be spawned on the new map server.
			char_data->last_point.map = RFIFOW(fd,18);
			char_data->last_point.x = RFIFOW(fd,20);
			char_data->last_point.y = RFIFOW(fd,22);
			char_data->sex = RFIFOB(fd,30);

			// create temporary auth entry
			CREATE(node, struct auth_node, 1);
			node->account_id = aid;
			node->char_id = RFIFOL(fd,14);
			node->login_id1 = RFIFOL(fd,6);
			node->login_id2 = RFIFOL(fd,10);
			node->sex = RFIFOB(fd,30);
			node->expiration_time = 0; // FIXME (this thing isn't really supported we could as well purge it instead of fixing)
			node->ip = ntohl(RFIFOL(fd,31));
			node->group_id = RFIFOL(fd,35);
			node->changing_mapservers = 1;
			idb_put(auth_db, aid, node);

			data = idb_ensure(online_char_db, aid, char_create_online_data);
			data->char_id = char_data->char_id;
			data->server = map_id; //Update server where char is.

			//Reply with an ack.
			chmapif_changemapserv_ack(fd,0);
		} else { //Reply with nak
			chmapif_changemapserv_ack(fd,1);
		}
		RFIFOSKIP(fd,39);
	}
Пример #4
0
int recv_to_fifo(int fd)
{
	int len;

	if( !session_isActive(fd) )
		return -1;

	len = sRecv(fd, (char *) session[fd]->rdata + session[fd]->rdata_size, (int)RFIFOSPACE(fd), 0);

	if( len == SOCKET_ERROR ) { //An exception has occured
		if( sErrno != S_EWOULDBLOCK ) {
			//ShowDebug("recv_to_fifo: %s, closing connection #%d\n", error_msg(), fd);
			set_eof(fd);
		}
		return 0;
	}

	if( len == 0 ) { //Normal connection end.
		set_eof(fd);
		return 0;
	}

	session[fd]->rdata_size += len;
	session[fd]->rdata_tick = last_tick;
#ifdef SHOW_SERVER_STATS
	socket_data_i += len;
	socket_data_qi += len;
	if (!session[fd]->flag.server) {
		socket_data_ci += len;
	}
#endif
	return 0;
}
Пример #5
0
void mapif_parse_accinfo2(bool success, int map_fd, int u_fd, int u_aid, int account_id, const char *userid, const char *user_pass, const char *email, const char *last_ip, const char *lastlogin, const char *pin_code, const char *birthdate, int group_id, int logincount, int state) {
	if (map_fd <= 0 || !session_isActive(map_fd))
		return; // check if we have a valid fd

	if(!success) {
		inter_msg_to_fd(map_fd, u_fd, u_aid, "No account with ID '%d' was found.", account_id);
		return;
	}

		inter_msg_to_fd(map_fd, u_fd, u_aid, read_message("Source.char.inter_parse_accinfo_s7"), account_id);
		inter_msg_to_fd(map_fd, u_fd, u_aid, read_message("Source.char.inter_parse_accinfo_s8"), userid, group_id, state);

		if(user_pass && *user_pass != '\0') { /* password is only received if your gm level is greater than the one you're searching for */
			if(pin_code && *pin_code != '\0')
				inter_msg_to_fd(map_fd, u_fd, u_aid, read_message("Source.char.inter_parse_accinfo_s17"), user_pass, pin_code);
			else
				inter_msg_to_fd(map_fd, u_fd, u_aid, read_message("Source.char.inter_parse_accinfo_s9"), user_pass);
			}

		inter_msg_to_fd(map_fd, u_fd, u_aid, read_message("Source.char.inter_parse_accinfo_s10"), email, birthdate);
		inter_msg_to_fd(map_fd, u_fd, u_aid, read_message("Source.char.inter_parse_accinfo_s11"), last_ip, geoip_getcountry(str2ip(last_ip)));
		inter_msg_to_fd(map_fd, u_fd, u_aid, read_message("Source.char.inter_parse_accinfo_s12"), logincount, lastlogin);
		inter_msg_to_fd(map_fd, u_fd, u_aid, read_message("Source.char.inter_parse_accinfo_s13"));


		if(SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`, `name`, `char_num`, `class`, `base_level`, `job_level`, `online` "
	                                              "FROM `%s` WHERE `account_id` = '%d' ORDER BY `char_num` LIMIT %d", char_db, account_id, MAX_CHARS)
			|| Sql_NumRows(sql_handle) == 0) {

			if(Sql_NumRows(sql_handle) == 0) {
				inter_msg_to_fd(map_fd, u_fd, u_aid, read_message("Source.char.inter_parse_accinfo_s14"));
			} else {
				inter_msg_to_fd(map_fd, u_fd, u_aid, read_message("Source.char.inter_parse_accinfo_s15"));
				Sql_ShowDebug(sql_handle);
			}
		} else {
			while(SQL_SUCCESS == Sql_NextRow(sql_handle)) {
				char *data;
				int char_id, class_;
				short char_num, base_level, job_level, online;
				char name[NAME_LENGTH];

				Sql_GetData(sql_handle, 0, &data, NULL); char_id = atoi(data);
				Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name));
				Sql_GetData(sql_handle, 2, &data, NULL); char_num = atoi(data);
				Sql_GetData(sql_handle, 3, &data, NULL); class_ = atoi(data);
				Sql_GetData(sql_handle, 4, &data, NULL); base_level = atoi(data);
				Sql_GetData(sql_handle, 5, &data, NULL); job_level = atoi(data);
				Sql_GetData(sql_handle, 6, &data, NULL); online = atoi(data);

				inter_msg_to_fd(map_fd, u_fd, u_aid, read_message("Source.char.inter_parse_accinfo_s16"), char_num, char_id, name, job_name(class_), base_level, job_level, online?"On":"Off");
			}
		}
		Sql_FreeResult(sql_handle);

	return;
}
Пример #6
0
// Save account_reg into sql (type=2)
int mapif_parse_Registry(int fd)
{
	int account_id = RFIFOL(fd, 4), char_id = RFIFOL(fd, 8), count = RFIFOW(fd, 12);

	if( count ) {
		int cursor = 14, i;
		bool isLoginActive = session_isActive(login_fd);

		if( isLoginActive )
			chlogif_upd_global_accreg(account_id,char_id);

		for(i = 0; i < count; i++) {
			size_t lenkey = RFIFOB( fd, cursor );
			const char* src_key= RFIFOCP(fd, cursor + 1);
			std::string key( src_key, lenkey );
			cursor += lenkey + 1;

			unsigned int  index = RFIFOL(fd, cursor);
			cursor += 4;

			switch (RFIFOB(fd, cursor++)) {
				// int
				case 0:
				{
					intptr_t lVal = RFIFOL( fd, cursor );
					inter_savereg( account_id, char_id, key.c_str(), index, lVal, false );
					cursor += 4;
					break;
				}
				case 1:
					inter_savereg(account_id,char_id,key.c_str(),index,0,false);
					break;
				// str
				case 2:
				{
					size_t len_val = RFIFOB( fd, cursor );
					const char* src_val= RFIFOCP(fd, cursor + 1);
					std::string sval( src_val, len_val );
					cursor += len_val + 1;
					inter_savereg( account_id, char_id, key.c_str(), index, (intptr_t)sval.c_str(), true );
					break;
				}
				case 3:
					inter_savereg(account_id,char_id,key.c_str(),index,0,true);
					break;
				default:
					ShowError("mapif_parse_Registry: unknown type %d\n",RFIFOB(fd, cursor - 1));
					return 1;
			}

		}

		if (isLoginActive)
			chlogif_prepsend_global_accreg();
	}
	return 0;
}
Пример #7
0
/*======================================
 *  CORE : Socket Sub Function
 *--------------------------------------*/
void set_eof(int fd)
{
	if(session_isActive(fd)) {
#ifdef SEND_SHORTLIST
		// Add this socket to the shortlist for eof handling.
		send_shortlist_add_fd(fd);
#endif
		session[fd]->flag.eof = 1;
	}
}
Пример #8
0
/**
 * Show account info from login-server to user
 */
void mapif_accinfo_ack(bool success, int map_fd, int u_fd, int u_aid, int account_id, int8 type,
	int group_id, int logincount, int state, const char *email, const char *last_ip, const char *lastlogin,
	const char *birthdate, const char *user_pass, const char *pincode, const char *userid)
{
	
	if (map_fd <= 0 || !session_isActive(map_fd))
		return; // check if we have a valid fd

	if (!success) {
		inter_to_fd(map_fd, u_fd, u_aid, (char *)msg_txt(216), account_id);
		return;
	}

	if (type == 1) { //type 1 we don't want all the info [lighta] @CHECKME
		mapif_acc_info_ack(map_fd, u_fd, account_id, userid);
		return;
	}

	inter_to_fd(map_fd, u_fd, u_aid, (char *)msg_txt(217), account_id);
	inter_to_fd(map_fd, u_fd, u_aid, (char *)msg_txt(218), userid, group_id, state);
	inter_to_fd(map_fd, u_fd, u_aid, (char *)msg_txt(219), user_pass[0] != '\0' ? user_pass : msg_txt(220), pincode[0] != '\0' ? msg_txt(220) : pincode);
	inter_to_fd(map_fd, u_fd, u_aid, (char *)msg_txt(221), email, birthdate);
	inter_to_fd(map_fd, u_fd, u_aid, (char *)msg_txt(222), last_ip, geoip_getcountry(str2ip(last_ip)));
	inter_to_fd(map_fd, u_fd, u_aid, (char *)msg_txt(223), logincount, lastlogin);
	inter_to_fd(map_fd, u_fd, u_aid, (char *)msg_txt(224));

	if ( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`, `name`, `char_num`, `class`, `base_level`, `job_level`, `online` FROM `%s` WHERE `account_id` = '%d' ORDER BY `char_num` LIMIT %d", schema_config.char_db, account_id, MAX_CHARS)
		|| Sql_NumRows(sql_handle) == 0 )
	{
		if( Sql_NumRows(sql_handle) == 0 )
			inter_to_fd(map_fd, u_fd, u_aid, (char *)msg_txt(226));
		else {
			inter_to_fd(map_fd, u_fd, u_aid, (char *)msg_txt(213));
			Sql_ShowDebug(sql_handle);
		}
	} else {
		while ( SQL_SUCCESS == Sql_NextRow(sql_handle) ) {
			uint32 char_id, class_;
			short char_num, base_level, job_level, online;
			char name[NAME_LENGTH];
			char *data;

			Sql_GetData(sql_handle, 0, &data, NULL); char_id = atoi(data);
			Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name));
			Sql_GetData(sql_handle, 2, &data, NULL); char_num = atoi(data);
			Sql_GetData(sql_handle, 3, &data, NULL); class_ = atoi(data);
			Sql_GetData(sql_handle, 4, &data, NULL); base_level = atoi(data);
			Sql_GetData(sql_handle, 5, &data, NULL); job_level = atoi(data);
			Sql_GetData(sql_handle, 6, &data, NULL); online = atoi(data);

			inter_to_fd(map_fd, u_fd, u_aid, (char *)msg_txt(225), char_num, char_id, name, job_name(class_), base_level, job_level, online?"Online":"Offline");
		}
	}
	Sql_FreeResult(sql_handle);
}
Пример #9
0
void mapif_parse_accinfo2(bool success, int map_fd, int u_fd, int u_aid, int account_id, const char *userid, const char *user_pass, const char *email, const char *last_ip, const char *lastlogin, const char *pin_code, const char *birthdate, int group_id, int logincount, int state) {
	if (map_fd <= 0 || !session_isActive(map_fd))
		return; // check if we have a valid fd

	if (!success) {
		inter_msg_to_fd(map_fd, u_fd, u_aid, "Nenhuma conta com ID '%d' foi encontrada.", account_id);
		return;
	}

	inter_msg_to_fd(map_fd, u_fd, u_aid, "-- Conta %d --", account_id);
	inter_msg_to_fd(map_fd, u_fd, u_aid, "Usuário: %s | Nível de Conta: %d | Estado: %d", userid, group_id, state);

	if (user_pass && *user_pass != '\0') { /* password is only received if your gm level is greater than the one you're searching for */
		if (pin_code && *pin_code != '\0')
			inter_msg_to_fd(map_fd, u_fd, u_aid, "Senha: %s (PIN:%s)", user_pass, pin_code);
		else
			inter_msg_to_fd(map_fd, u_fd, u_aid, "Senha: %s", user_pass );
	}

	inter_msg_to_fd(map_fd, u_fd, u_aid, "E-mail da conta: %s | Data de Aniversário: %s", email, birthdate);
	inter_msg_to_fd(map_fd, u_fd, u_aid, "Último IP: %s (%s)", last_ip, geoip_getcountry(str2ip(last_ip)));
	inter_msg_to_fd(map_fd, u_fd, u_aid, "Este usuário já logou %d vezes. Última vez em:  %s", logincount, lastlogin);
	inter_msg_to_fd(map_fd, u_fd, u_aid, "-- Detalhes do Personagem --");

	if ( SQL_ERROR == SQL->Query(sql_handle, "SELECT `char_id`, `name`, `char_num`, `class`, `base_level`, `job_level`, `online` "
	                                         "FROM `%s` WHERE `account_id` = '%d' ORDER BY `char_num` LIMIT %d", char_db, account_id, MAX_CHARS)
	  || SQL->NumRows(sql_handle) == 0 ) {
		if (SQL->NumRows(sql_handle) == 0) {
			inter_msg_to_fd(map_fd, u_fd, u_aid, "Esta conta não possui personagens.");
		} else {
			inter_msg_to_fd(map_fd, u_fd, u_aid, "Falha na pesquisa de dados.");
			Sql_ShowDebug(sql_handle);
		}
	} else {
		while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) {
			char *data;
			int char_id, class_;
			short char_num, base_level, job_level, online;
			char name[NAME_LENGTH];

			SQL->GetData(sql_handle, 0, &data, NULL); char_id = atoi(data);
			SQL->GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name));
			SQL->GetData(sql_handle, 2, &data, NULL); char_num = atoi(data);
			SQL->GetData(sql_handle, 3, &data, NULL); class_ = atoi(data);
			SQL->GetData(sql_handle, 4, &data, NULL); base_level = atoi(data);
			SQL->GetData(sql_handle, 5, &data, NULL); job_level = atoi(data);
			SQL->GetData(sql_handle, 6, &data, NULL); online = atoi(data);

			inter_msg_to_fd(map_fd, u_fd, u_aid, "[Slot/CID: %d/%d] %s | %s | Nível: %d/%d | %s", char_num, char_id, name, job_name(class_), base_level, job_level, online?"On":"Off");
		}
	}
	SQL->FreeResult(sql_handle);

	return;
}
Пример #10
0
void mapif_parse_accinfo2(bool success, int map_fd, int u_fd, int u_aid, int account_id, const char *userid, const char *user_pass, const char *email, const char *last_ip, const char *lastlogin, const char *pin_code, const char *birthdate, int group_id, int logincount, int state) {
	if (map_fd <= 0 || !session_isActive(map_fd))
		return; // check if we have a valid fd

	if (!success) {
		inter_msg_to_fd(map_fd, u_fd, u_aid, "No account with ID '%d' was found.", account_id);
		return;
	}

	inter_msg_to_fd(map_fd, u_fd, u_aid, "-- Account %d --", account_id);
	inter_msg_to_fd(map_fd, u_fd, u_aid, "User: %s | GM Group: %d | State: %d", userid, group_id, state);

	if (user_pass && *user_pass != '\0') { /* password is only received if your gm level is greater than the one you're searching for */
		if (pin_code && *pin_code != '\0')
			inter_msg_to_fd(map_fd, u_fd, u_aid, "Password: %s (PIN:%s)", user_pass, pin_code);
		else
			inter_msg_to_fd(map_fd, u_fd, u_aid, "Password: %s", user_pass );
	}

	inter_msg_to_fd(map_fd, u_fd, u_aid, "Account e-mail: %s | Birthdate: %s", email, birthdate);
	inter_msg_to_fd(map_fd, u_fd, u_aid, "Last IP: %s (%s)", last_ip, geoip_getcountry(str2ip(last_ip)));
	inter_msg_to_fd(map_fd, u_fd, u_aid, "This user has logged %d times, the last time were at %s", logincount, lastlogin);
	inter_msg_to_fd(map_fd, u_fd, u_aid, "-- Character Details --");

	if ( SQL_ERROR == SQL->Query(sql_handle, "SELECT `char_id`, `name`, `char_num`, `class`, `base_level`, `job_level`, `online` "
	                                         "FROM `%s` WHERE `account_id` = '%d' ORDER BY `char_num` LIMIT %d", char_db, account_id, MAX_CHARS)
	  || SQL->NumRows(sql_handle) == 0 ) {
		if (SQL->NumRows(sql_handle) == 0) {
			inter_msg_to_fd(map_fd, u_fd, u_aid, "This account doesn't have characters.");
		} else {
			inter_msg_to_fd(map_fd, u_fd, u_aid, "An error occurred, bother your admin about it.");
			Sql_ShowDebug(sql_handle);
		}
	} else {
		while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) {
			char *data;
			int char_id, class_;
			short char_num, base_level, job_level, online;
			char name[NAME_LENGTH];

			SQL->GetData(sql_handle, 0, &data, NULL); char_id = atoi(data);
			SQL->GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name));
			SQL->GetData(sql_handle, 2, &data, NULL); char_num = atoi(data);
			SQL->GetData(sql_handle, 3, &data, NULL); class_ = atoi(data);
			SQL->GetData(sql_handle, 4, &data, NULL); base_level = atoi(data);
			SQL->GetData(sql_handle, 5, &data, NULL); job_level = atoi(data);
			SQL->GetData(sql_handle, 6, &data, NULL); online = atoi(data);

			inter_msg_to_fd(map_fd, u_fd, u_aid, "[Slot/CID: %d/%d] %s | %s | Level: %d/%d | %s", char_num, char_id, name, job_name(class_), base_level, job_level, online?"On":"Off");
		}
	}
	SQL->FreeResult(sql_handle);

	return;
}
Пример #11
0
// Save account_reg into sql (type=2)
int mapif_parse_Registry(int fd)
{
	int account_id = RFIFOL(fd, 4), char_id = RFIFOL(fd, 8), count = RFIFOW(fd, 12);
	
	if( count ) {
		int cursor = 14, i;
		char key[32], sval[254];
		unsigned int index;
		bool isLoginActive = session_isActive(login_fd);

		if( isLoginActive )
			global_accreg_to_login_start(account_id,char_id);
		
		for(i = 0; i < count; i++) {
			safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor));
			cursor += RFIFOB(fd, cursor) + 1;

			index = RFIFOL(fd, cursor);
			cursor += 4;

			switch (RFIFOB(fd, cursor++)) {
				/* int */
				case 0:
					inter_savereg(account_id,char_id,key,index,RFIFOL(fd, cursor),false);
					cursor += 4;
					break;
				case 1:
					inter_savereg(account_id,char_id,key,index,0,false);
					break;
				/* str */
				case 2:
					safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor));
					cursor += RFIFOB(fd, cursor) + 1;
					inter_savereg(account_id,char_id,key,index,(intptr_t)sval,true);
					break;
				case 3:
					inter_savereg(account_id,char_id,key,index,0,true);
					break;
					
				default:
					ShowError("mapif_parse_Registry: unknown type %d\n",RFIFOB(fd, cursor - 1));
					return 1;
			}

		}

		if( isLoginActive )		
			global_accreg_to_login_send();
	}
	return 0;
}
Пример #12
0
int chlogif_parse_ackaccreq(int fd, struct char_session_data* sd){
	if (RFIFOREST(fd) < 25)
		return 0;
	{
		int account_id = RFIFOL(fd,2);
		uint32 login_id1 = RFIFOL(fd,6);
		uint32 login_id2 = RFIFOL(fd,10);
		uint8 sex = RFIFOB(fd,14);
		uint8 result = RFIFOB(fd,15);
		int request_id = RFIFOL(fd,16);
		uint32 version = RFIFOL(fd,20);
		uint8 clienttype = RFIFOB(fd,24);
		RFIFOSKIP(fd,25);

		if( session_isActive(request_id) && (sd=(struct char_session_data*)session[request_id]->session_data) &&
			!sd->auth && sd->account_id == account_id && sd->login_id1 == login_id1 && sd->login_id2 == login_id2 && sd->sex == sex )
		{
			int client_fd = request_id;
			sd->version = version;
			sd->clienttype = clienttype;
			if(sd->version != date2version(PACKETVER))
				ShowWarning("s aid=%d has an incorect version=%d in clientinfo. Server compiled for %d\n",
					sd->account_id,sd->version,date2version(PACKETVER));

			switch( result )
			{
			case 0:// ok
				char_auth_ok(client_fd, sd);
				break;
			case 1:// auth failed
				WFIFOHEAD(client_fd,3);
				WFIFOW(client_fd,0) = 0x6c;
				WFIFOB(client_fd,2) = 0;// rejected from server
				WFIFOSET(client_fd,3);
				break;
			}
		}
	}
	return 1;
}
Пример #13
0
/*======================================
 *	CORE : Socket Sub Function
 *--------------------------------------
 */
static void set_eof(int fd)
{	//Marks a connection eof and invokes the parse_function to disconnect it right away. [Skotlex]
	if (session_isActive(fd))
		session[fd]->eof=1;
}
Пример #14
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);
	}
}