Example #1
0
/**
 * Request of the map-server that a player claimed his achievement rewards.
 * @see inter_parse_frommap
 */
int mapif_parse_achievement_reward(int fd){
	time_t current = time(NULL);
	uint32 char_id = RFIFOL(fd, 2);
	int32 achievement_id = RFIFOL(fd, 6);

	if( Sql_Query( sql_handle, "UPDATE `%s` SET `rewarded` = FROM_UNIXTIME('%u') WHERE `char_id`='%u' AND `id` = '%d' AND `completed` IS NOT NULL AND `rewarded` IS NULL", schema_config.achievement_table, (uint32)current, char_id, achievement_id ) == SQL_ERROR ||
		Sql_NumRowsAffected(sql_handle) <= 0 ){
		current = 0;
	}else if( RFIFOW(fd,10) > 0 ){ // Do not send a mail if no item reward
		char mail_sender[NAME_LENGTH];
		char mail_receiver[NAME_LENGTH];
		char mail_title[MAIL_TITLE_LENGTH];
		char mail_text[MAIL_BODY_LENGTH];
		struct item item;

		memset(&item, 0, sizeof(struct item));
		item.nameid = RFIFOW(fd, 10);
		item.amount = RFIFOL(fd, 12);
		item.identify = 1;

		safesnprintf(mail_sender, NAME_LENGTH, char_msg_txt(227)); // 227: GM
		safestrncpy(mail_receiver, RFIFOCP(fd,16), NAME_LENGTH);
		safesnprintf(mail_title, MAIL_TITLE_LENGTH, char_msg_txt(228)); // 228: Achievement Reward Mail
		safesnprintf(mail_text, MAIL_BODY_LENGTH, char_msg_txt(229), RFIFOCP(fd,16+NAME_LENGTH) ); // 229: [%s] Achievement Reward.

		if( !mail_sendmail(0, mail_sender, char_id, mail_receiver, mail_title, mail_text, 0, &item, 1) ){
			current = 0;
		}
	}

	mapif_achievement_reward(fd, char_id, achievement_id, current);

	return 0;
}
Example #2
0
/*
 * Client request to change pincode
 */
int chclif_parse_pincode_change( int fd, struct char_session_data* sd ){
	if( RFIFOREST(fd) < 14 )
		return 0;
	if( charserv_config.pincode_config.pincode_enabled==0 || RFIFOL(fd,2) != sd->account_id )
		return 1;
	else {
		char oldpin[PINCODE_LENGTH+1];
		char newpin[PINCODE_LENGTH+1];
		
		memset(oldpin,0,PINCODE_LENGTH+1);
		memset(newpin,0,PINCODE_LENGTH+1);
		strncpy(oldpin, RFIFOCP(fd,6), PINCODE_LENGTH);
		strncpy(newpin, RFIFOCP(fd,10), PINCODE_LENGTH);
		RFIFOSKIP(fd,14);
		
		char_pincode_decrypt(sd->pincode_seed,oldpin);
		if( !char_pincode_compare( fd, sd, oldpin ) )
			return 1;
		char_pincode_decrypt(sd->pincode_seed,newpin);

		if( pincode_allowed(newpin) ){
			chlogif_pincode_notifyLoginPinUpdate( sd->account_id, newpin );
			strncpy(sd->pincode, newpin, sizeof(newpin));
			ShowInfo("Pincode changed for AID: %d\n", sd->account_id);
		
			chclif_pincode_sendstate( fd, sd, PINCODE_PASSED );
		}else{
			chclif_pincode_sendstate( fd, sd, PINCODE_ILLEGAL );
		}
	}
	return 1;
}
Example #3
0
/**
 * Map server send information to change an email of an account via char-server.
 * 0x2722 <account_id>.L <actual_e-mail>.40B <new_e-mail>.40B
 * @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_reqchangemail(int fd, int id, char* ip){
	if (RFIFOREST(fd) < 86)
		return 0;
	else{
		struct mmo_account acc;
		AccountDB* accounts = login_get_accounts_db();
		char actual_email[40];
		char new_email[40];

		uint32 account_id = RFIFOL(fd,2);
		safestrncpy(actual_email, RFIFOCP(fd,6), 40);
		safestrncpy(new_email, RFIFOCP(fd,46), 40);
		RFIFOSKIP(fd, 86);

		if( e_mail_check(actual_email) == 0 )
			ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)\n", ch_server[id].name, account_id, ip);
		else if( e_mail_check(new_email) == 0 )
			ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a invalid new e-mail (account: %d, ip: %s)\n", ch_server[id].name, account_id, ip);
		else if( strcmpi(new_email, "*****@*****.**") == 0 )
			ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)\n", ch_server[id].name, account_id, ip);
		else if( !accounts->load_num(accounts, &acc, account_id) )
			ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but account doesn't exist (account: %d, ip: %s).\n", ch_server[id].name, account_id, ip);
		else if( strcmpi(acc.email, actual_email) != 0 )
			ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual e-mail is incorrect (account: %d (%s), actual e-mail: %s, proposed e-mail: %s, ip: %s).\n", ch_server[id].name, account_id, acc.userid, acc.email, actual_email, ip);
		else{
			safestrncpy(acc.email, new_email, 40);
			ShowNotice("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s).\n", ch_server[id].name, account_id, acc.userid, new_email, ip);
			// Save
			accounts->save(accounts, &acc);
		}
	}
	return 1;
}
Example #4
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;
}
Example #5
0
int mapif_parse_NameChangeRequest(int fd)
{
	uint32 account_id, char_id;
	int type;
	char* name;
	int i;

	account_id = RFIFOL(fd,2);
	char_id = RFIFOL(fd,6);
	type = RFIFOB(fd,10);
	name = RFIFOCP(fd,11);

	// Check Authorised letters/symbols in the name
	if (charserv_config.char_config.char_name_option == 1) { // only letters/symbols in char_name_letters are authorised
		for (i = 0; i < NAME_LENGTH && name[i]; i++)
		if (strchr(charserv_config.char_config.char_name_letters, name[i]) == NULL) {
			mapif_namechange_ack(fd, account_id, char_id, type, 0, name);
			return 0;
		}
	} else if (charserv_config.char_config.char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
		for (i = 0; i < NAME_LENGTH && name[i]; i++)
		if (strchr(charserv_config.char_config.char_name_letters, name[i]) != NULL) {
			mapif_namechange_ack(fd, account_id, char_id, type, 0, name);
			return 0;
		}
	}
	//TODO: type holds the type of object to rename.
	//If it were a player, it needs to have the guild information and db information
	//updated here, because changing it on the map won't make it be saved [Skotlex]

	//name allowed.
	mapif_namechange_ack(fd, account_id, char_id, type, 1, name);
	return 0;
}
Example #6
0
/*
 * activate PIN system and set first PIN
 */
int chclif_parse_pincode_setnew( int fd, struct char_session_data* sd ){
	if( RFIFOREST(fd) < 10 )
		return 0;

	if( charserv_config.pincode_config.pincode_enabled==0 || RFIFOL(fd,2) != sd->account_id )
		return 1;
	else {
		char newpin[PINCODE_LENGTH+1];
		memset(newpin,0,PINCODE_LENGTH+1);
		strncpy( newpin, RFIFOCP(fd,6), PINCODE_LENGTH );
		RFIFOSKIP(fd,10);

		char_pincode_decrypt( sd->pincode_seed, newpin );

		if( pincode_allowed(newpin) ){
			chlogif_pincode_notifyLoginPinUpdate( sd->account_id, newpin );
			strncpy( sd->pincode, newpin, strlen( newpin ) );

			chclif_pincode_sendstate( fd, sd, PINCODE_PASSED );	
		}else{
			chclif_pincode_sendstate( fd, sd, PINCODE_ILLEGAL );
		}
	}
	return 1;
}
Example #7
0
void mmo_save_global_accreg(AccountDB* self, int fd, int account_id, int char_id) {
	Sql* sql_handle = ((AccountDB_SQL*)self)->accounts;
	AccountDB_SQL* db = (AccountDB_SQL*)self;
	int count = RFIFOW(fd, 12);

	if (count) {
		int cursor = 14, i;
		char key[32], sval[254];

		for (i = 0; i < count; i++) {
			unsigned int index;
			safestrncpy(key, RFIFOCP(fd, cursor + 1), RFIFOB(fd, cursor));
			cursor += RFIFOB(fd, cursor) + 1;

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

			switch (RFIFOB(fd, cursor++)) {
				// int
				case 0:
					if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%d')", db->global_acc_reg_num_table, account_id, key, index, RFIFOL(fd, cursor)) )
						Sql_ShowDebug(sql_handle);
					cursor += 4;
					break;
				case 1:
					if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", db->global_acc_reg_num_table, account_id, key, index) )
						Sql_ShowDebug(sql_handle);
					break;
				// str
				case 2:
					safestrncpy(sval, RFIFOCP(fd, cursor + 1), RFIFOB(fd, cursor));
					cursor += RFIFOB(fd, cursor) + 1;
					if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", db->global_acc_reg_str_table, account_id, key, index, sval) )
						Sql_ShowDebug(sql_handle);
					break;
				case 3:
					if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", db->global_acc_reg_str_table, account_id, key, index) )
						Sql_ShowDebug(sql_handle);
					break;
				default:
					ShowError("mmo_save_global_accreg: unknown type %d\n",RFIFOB(fd, cursor - 1));
					return;
			}
		}
	}
}
Example #8
0
/**
 * AH 0x2721
 * Retrieve account info from login-server, ask inter-server to tell player
 */
int chlogif_parse_AccInfoAck(int fd) {
	if (RFIFOREST(fd) < 19)
		return 0;
	else {
		int8 type = RFIFOB(fd, 18);
		if (type == 0 || RFIFOREST(fd) < 122+NAME_LENGTH) {
			mapif_accinfo_ack(false, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), 0, -1, 0, 0, NULL, NULL, NULL, NULL, NULL);
			RFIFOSKIP(fd,19);
			return 1;
		}
		type>>=1;
		mapif_accinfo_ack(true, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), type, RFIFOL(fd,19), RFIFOL(fd,23), RFIFOL(fd,27),
			RFIFOCP(fd,31), RFIFOCP(fd,71), RFIFOCP(fd,87), RFIFOCP(fd,111),
			RFIFOCP(fd,122));
		RFIFOSKIP(fd,122+NAME_LENGTH);
	}
	return 1;
}
Example #9
0
/**
 * Receive account data from login-server
 * AH 0x2717 <aid>.L <email>.40B <expiration_time>.L <group_id>.B <birthdate>.11B <pincode>.5B <pincode_change>.L <isvip>.B <char_vip>.B <char_billing>.B
 **/
int chlogif_parse_reqaccdata(int fd, struct char_session_data* sd){
	int u_fd; //user fd
	if (RFIFOREST(fd) < 75)
		return 0;

	// find the authenticated session with this account id
	ARR_FIND( 0, fd_max, u_fd, session[u_fd] && (sd = (struct char_session_data*)session[u_fd]->session_data) && sd->auth && sd->account_id == RFIFOL(fd,2) );
	if( u_fd < fd_max )
	{
		int server_id;
		memcpy(sd->email, RFIFOP(fd,6), 40);
		sd->expiration_time = (time_t)RFIFOL(fd,46);
		sd->group_id = RFIFOB(fd,50);
		sd->char_slots = RFIFOB(fd,51);
		if( sd->char_slots > MAX_CHARS ) {
			ShowError("Account '%d' `character_slots` column is higher than supported MAX_CHARS (%d), update MAX_CHARS in mmo.hpp! capping to MAX_CHARS...\n",sd->account_id,sd->char_slots);
			sd->char_slots = MAX_CHARS;/* cap to maximum */
		} else if ( !sd->char_slots )/* no value aka 0 in sql */
			sd->char_slots = MIN_CHARS;/* cap to minimum */
		safestrncpy(sd->birthdate, RFIFOCP(fd,52), sizeof(sd->birthdate));
		safestrncpy(sd->pincode, RFIFOCP(fd,63), sizeof(sd->pincode));
		sd->pincode_change = (time_t)RFIFOL(fd,68);
		sd->isvip = RFIFOB(fd,72);
		sd->chars_vip = RFIFOB(fd,73);
		sd->chars_billing = RFIFOB(fd,74);
		ARR_FIND( 0, ARRAYLENGTH(map_server), server_id, map_server[server_id].fd > 0 && map_server[server_id].map[0] );
		// continued from char_auth_ok...
		if( server_id == ARRAYLENGTH(map_server) || //server not online, bugreport:2359
			(((charserv_config.max_connect_user == 0 || charserv_config.char_maintenance == 1) ||
			(charserv_config.max_connect_user > 0 && char_count_users() >= charserv_config.max_connect_user)) &&
			sd->group_id < charserv_config.gm_allow_group)) {
			// refuse connection (over populated)
			chclif_reject(u_fd,0);
		} else {
			// send characters to player
			chclif_mmo_char_send(u_fd, sd);
#if PACKETVER_SUPPORTS_PINCODE
			chlogif_pincode_start(u_fd,sd);
#endif
		}
	}
	RFIFOSKIP(fd,75);
	return 1;
}
Example #10
0
/**
 * Receive a account_info request from map-serv
 * @author : [Dekamaster/Nightroad]
 * @param fd : map-serv link
 */
void mapif_parse_accinfo(int fd) {
	int u_fd = RFIFOL(fd,2), u_aid = RFIFOL(fd,6), u_group = RFIFOL(fd,10);
	char type= RFIFOB(fd,14);
	char query[NAME_LENGTH], query_esq[NAME_LENGTH*2+1];
	uint32 account_id = 0;
	char *data;

	safestrncpy(query, RFIFOCP(fd,15), NAME_LENGTH);
	Sql_EscapeString(sql_handle, query_esq, query);

	account_id = atoi(query);

	if (account_id < START_ACCOUNT_NUM) {	// is string
		if ( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name`,`class`,`base_level`,`job_level`,`online` FROM `%s` WHERE `name` LIKE '%s' LIMIT 10", schema_config.char_db, query_esq)
				|| Sql_NumRows(sql_handle) == 0 ) {
			if( Sql_NumRows(sql_handle) == 0 ) {
				inter_to_fd(fd, u_fd, u_aid, (char *)msg_txt(212) ,query);
			} else {
				Sql_ShowDebug(sql_handle);
				inter_to_fd(fd, u_fd, u_aid, (char *)msg_txt(213));
			}
			Sql_FreeResult(sql_handle);
			return;
		} else {
			if( Sql_NumRows(sql_handle) == 1 ) {//we found a perfect match
				Sql_NextRow(sql_handle);
				Sql_GetData(sql_handle, 0, &data, NULL); account_id = atoi(data);
				Sql_FreeResult(sql_handle);
			} else {// more than one, listing... [Dekamaster/Nightroad]
				inter_to_fd(fd, u_fd, u_aid, (char *)msg_txt(214),(int)Sql_NumRows(sql_handle));
				while ( SQL_SUCCESS == Sql_NextRow(sql_handle) ) {
					int class_;
					short base_level, job_level, online;
					char name[NAME_LENGTH];

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

					inter_to_fd(fd, u_fd, u_aid, (char *)msg_txt(215), account_id, name, job_name(class_), base_level, job_level, online?"Online":"Offline");
				}
				Sql_FreeResult(sql_handle);
				return;
			}
		}
	}

	/* it will only get here if we have a single match then ask login-server to fetch the `login` record */
	if (!account_id || chlogif_req_accinfo(fd, u_fd, u_aid, u_group, account_id, type) != 1) {
		inter_to_fd(fd, u_fd, u_aid, (char *)msg_txt(213));
	}
	return;
}
Example #11
0
// Communication from the map server
//-Analysis that only one packet
// Data packet length is set to inter.c that you
// Do NOT go and check the packet length, RFIFOSKIP is done by the caller
// Return :
// 	0 : error
//	1 : ok
int inter_party_parse_frommap(int fd)
{
	RFIFOHEAD(fd);
	switch(RFIFOW(fd,0)) {
	case 0x3020: mapif_parse_CreateParty(fd, RFIFOCP(fd,4), RFIFOB(fd,28), RFIFOB(fd,29), (struct party_member*)RFIFOP(fd,30)); break;
	case 0x3021: mapif_parse_PartyInfo(fd, RFIFOL(fd,2), RFIFOL(fd,6)); break;
	case 0x3022: mapif_parse_PartyAddMember(fd, RFIFOL(fd,4), (struct party_member*)RFIFOP(fd,8)); break;
	case 0x3023: mapif_parse_PartyChangeOption(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOW(fd,10), RFIFOW(fd,12)); break;
	case 0x3024: mapif_parse_PartyLeave(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOCP(fd,14), (enum e_party_member_withdraw)RFIFOB(fd,14+NAME_LENGTH)); break;
	case 0x3025: mapif_parse_PartyChangeMap(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOW(fd,14), RFIFOB(fd,16), RFIFOW(fd,17)); break;
	case 0x3026: mapif_parse_BreakParty(fd, RFIFOL(fd,2)); break;
	case 0x3027: mapif_parse_PartyMessage(fd, RFIFOL(fd,4), RFIFOL(fd,8), RFIFOCP(fd,12), RFIFOW(fd,2)-12); break;
	case 0x3029: mapif_parse_PartyLeaderChange(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;
	case 0x302A: mapif_parse_PartyShareLevel(fd, RFIFOL(fd,2)); break;
	default:
		return 0;
	}
	return 1;
}
Example #12
0
void mapif_parse_Auction_bid(int fd)
{
	uint32 char_id = RFIFOL(fd,4), auction_id = RFIFOL(fd,8);
	int bid = RFIFOL(fd,12);
	struct auction_data *auction;

	if( (auction = (struct auction_data *)idb_get(auction_db_, auction_id)) == NULL || auction->price >= bid || auction->seller_id == char_id )
	{
		mapif_Auction_bid(fd, char_id, bid, 0); // You have failed to bid in the auction
		return;
	}

	if( auction_count(char_id, true) > 4 && bid < auction->buynow && auction->buyer_id != char_id )
	{
		mapif_Auction_bid(fd, char_id, bid, 9); // You cannot place more than 5 bids at a time
		return;
	}

	if( auction->buyer_id > 0 )
	{ // Send Money back to the previous Buyer
		if( auction->buyer_id != char_id )
		{
			mail_sendmail(0, msg_txt(200), auction->buyer_id, auction->buyer_name, msg_txt(201), msg_txt(208), auction->price, NULL, 0);
			mapif_Auction_message(auction->buyer_id, 7); // You have failed to win the auction
		}
		else
			mail_sendmail(0, msg_txt(200), auction->buyer_id, auction->buyer_name, msg_txt(201), msg_txt(209), auction->price, NULL, 0);
	}

	auction->buyer_id = char_id;
	safestrncpy(auction->buyer_name, RFIFOCP(fd,16), NAME_LENGTH);
	auction->price = bid;

	if( bid >= auction->buynow )
	{ // Automatic won the auction
		mapif_Auction_bid(fd, char_id, bid - auction->buynow, 1); // You have successfully bid in the auction

		mail_sendmail(0, msg_txt(200), auction->buyer_id, auction->buyer_name, msg_txt(201), msg_txt(210), 0, &auction->item, 1);
		mapif_Auction_message(char_id, 6); // You have won the auction
		mail_sendmail(0, msg_txt(200), auction->seller_id, auction->seller_name, msg_txt(201), msg_txt(211), auction->buynow, NULL, 0);

		auction_delete(auction);
		return;
	}

	auction_save(auction);

	mapif_Auction_bid(fd, char_id, 0, 1); // You have successfully bid in the auction
}
Example #13
0
/**
 * Request to change PIN Code for an account.
 * @param fd: fd to parse from (char-serv)
 * @return 0 fail (packet does not have enough data), 1 success
 */
int logchrif_parse_updpincode(int fd){
	if( RFIFOREST(fd) < 8 + PINCODE_LENGTH+1 )
		return 0;
	else{
		struct mmo_account acc;
		AccountDB* accounts = login_get_accounts_db();

		if( accounts->load_num(accounts, &acc, RFIFOL(fd,4) ) ){
			strncpy( acc.pincode, RFIFOCP(fd,8), PINCODE_LENGTH+1 );
			acc.pincode_change = time( NULL );
			accounts->save(accounts, &acc);
		}
		RFIFOSKIP(fd,8 + PINCODE_LENGTH+1);
	}
	return 1;
}
Example #14
0
/*
 * Client as anwsered pincode questionning, checking if valid anwser
 */
int chclif_parse_pincode_check( int fd, struct char_session_data* sd ){
	char pin[PINCODE_LENGTH+1];

	if( RFIFOREST(fd) < 10 )
		return 0;
	if( charserv_config.pincode_config.pincode_enabled==0 || RFIFOL(fd,2) != sd->account_id )
		return 1;

	memset(pin,0,PINCODE_LENGTH+1);
	strncpy((char*)pin, RFIFOCP(fd, 6), PINCODE_LENGTH);
	RFIFOSKIP(fd,10);

	char_pincode_decrypt(sd->pincode_seed, pin );
	if( char_pincode_compare( fd, sd, pin ) ){
		chclif_pincode_sendstate( fd, sd, PINCODE_PASSED );
	}
	return 1;
}
Example #15
0
void mapif_parse_Mail_receiver_check( int fd ){
	char name[NAME_LENGTH], esc_name[NAME_LENGTH * 2 + 1];
	uint32 char_id = 0;
	uint16 class_ = 0, base_level = 0;

	safestrncpy( name, RFIFOCP(fd, 6), NAME_LENGTH );

	// Try to find the Dest Char by Name
	Sql_EscapeStringLen( sql_handle, esc_name, name, strnlen( name, NAME_LENGTH ) );

	if( SQL_ERROR == Sql_Query( sql_handle, "SELECT `char_id`,`class`,`base_level` FROM `%s` WHERE `name` = '%s'", schema_config.char_db, esc_name ) ){
		Sql_ShowDebug(sql_handle);
	}else if( SQL_SUCCESS == Sql_NextRow(sql_handle) ){
		char *data;

		Sql_GetData(sql_handle, 0, &data, NULL); char_id = atoi(data);
		Sql_GetData(sql_handle, 1, &data, NULL); class_ = atoi(data);
		Sql_GetData(sql_handle, 2, &data, NULL); base_level = atoi(data);
	}

	Sql_FreeResult(sql_handle);
	mapif_Mail_receiver_send( fd, RFIFOL(fd, 2), char_id, class_, base_level, name );
}
Example #16
0
/**
 * Char-server request to connect to the login-server.
 * This is needed to exchange packets.
 * @param fd: file descriptor to parse from (client)
 * @param sd: client session
 * @param ip: ipv4 address (client)
 * @return 0 packet received too shirt, 1 success
 */
static int logclif_parse_reqcharconnec(int fd, struct login_session_data *sd, char* ip){
	if (RFIFOREST(fd) < 86)
		return 0;
	else {
		int result;
		char server_name[20];
		char message[256];
		uint32 server_ip;
		uint16 server_port;
		uint16 type;
		uint16 new_;

		safestrncpy(sd->userid, RFIFOCP(fd,2), NAME_LENGTH);
		safestrncpy(sd->passwd, RFIFOCP(fd,26), NAME_LENGTH);
		if( login_config.use_md5_passwds )
			MD5_String(sd->passwd, sd->passwd);
		sd->passwdenc = 0;
		server_ip = ntohl(RFIFOL(fd,54));
		server_port = ntohs(RFIFOW(fd,58));
		safestrncpy(server_name, RFIFOCP(fd,60), 20);
		type = RFIFOW(fd,82);
		new_ = RFIFOW(fd,84);
		RFIFOSKIP(fd,86);

		ShowInfo("Connection request of the char-server '%s' @ %u.%u.%u.%u:%u (account: '%s', ip: '%s')\n", server_name, CONVIP(server_ip), server_port, sd->userid, ip);
		sprintf(message, "charserver - %s@%u.%u.%u.%u:%u", server_name, CONVIP(server_ip), server_port);
		login_log(session[fd]->client_addr, sd->userid, 100, message);

		result = login_mmo_auth(sd, true);
		if( runflag == LOGINSERVER_ST_RUNNING &&
			result == -1 &&
			sd->sex == 'S' &&
			sd->account_id < ARRAYLENGTH(ch_server) &&
			!session_isValid(ch_server[sd->account_id].fd) )
		{
			ShowStatus("Connection of the char-server '%s' accepted.\n", server_name);
			safestrncpy(ch_server[sd->account_id].name, server_name, sizeof(ch_server[sd->account_id].name));
			ch_server[sd->account_id].fd = fd;
			ch_server[sd->account_id].ip = server_ip;
			ch_server[sd->account_id].port = server_port;
			ch_server[sd->account_id].users = 0;
			ch_server[sd->account_id].type = type;
			ch_server[sd->account_id].new_ = new_;

			session[fd]->func_parse = logchrif_parse;
			session[fd]->flag.server = 1;
			realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);

			// send connection success
			WFIFOHEAD(fd,3);
			WFIFOW(fd,0) = 0x2711;
			WFIFOB(fd,2) = 0;
			WFIFOSET(fd,3);
		}
		else
		{
			ShowNotice("Connection of the char-server '%s' REFUSED.\n", server_name);
			WFIFOHEAD(fd,3);
			WFIFOW(fd,0) = 0x2711;
			WFIFOB(fd,2) = 3;
			WFIFOSET(fd,3);
		}
	}
	return 1;
}
Example #17
0
/**
 * Received a connection request.
 * @param fd: file descriptor to parse from (client)
 * @param sd: client session
 * @param command: packet type sent
 * @param ip: ipv4 address (client)
 *  S 0064 <version>.L <username>.24B <password>.24B <clienttype>.B
 *  S 0277 <version>.L <username>.24B <password>.24B <clienttype>.B <ip address>.16B <adapter address>.13B
 *  S 02b0 <version>.L <username>.24B <password>.24B <clienttype>.B <ip address>.16B <adapter address>.13B <g_isGravityID>.B
 *  S 01dd <version>.L <username>.24B <password hash>.16B <clienttype>.B
 *  S 01fa <version>.L <username>.24B <password hash>.16B <clienttype>.B <?>.B(index of the connection in the clientinfo file (+10 if the command-line contains "pc"))
 *  S 027c <version>.L <username>.24B <password hash>.16B <clienttype>.B <?>.13B(junk)
 *  S 0825 <packetsize>.W <version>.L <clienttype>.B <userid>.24B <password>.27B <mac>.17B <ip>.15B <token>.(packetsize - 0x5C)B
 * @param fd: fd to parse from (client fd)
 * @return 0 failure, 1 success
 */
static int logclif_parse_reqauth(int fd, struct login_session_data *sd, int command, char* ip){
	size_t packet_len = RFIFOREST(fd);

	if( (command == 0x0064 && packet_len < 55)
	||  (command == 0x0277 && packet_len < 84)
	||  (command == 0x02b0 && packet_len < 85)
	||  (command == 0x01dd && packet_len < 47)
	||  (command == 0x01fa && packet_len < 48)
	||  (command == 0x027c && packet_len < 60)
	||  (command == 0x0825 && (packet_len < 4 || packet_len < RFIFOW(fd, 2))) )
		return 0;
	else {
		int result;
		char username[NAME_LENGTH];
		char password[PASSWD_LENGTH];
		unsigned char passhash[16];
		uint8 clienttype;
		bool israwpass = (command==0x0064 || command==0x0277 || command==0x02b0 || command == 0x0825);

		// Shinryo: For the time being, just use token as password.
		if(command == 0x0825) {
			char *accname = RFIFOCP(fd, 9);
			char *token = RFIFOCP(fd, 0x5C);
			size_t uAccLen = strlen(accname);
			size_t uTokenLen = RFIFOREST(fd) - 0x5C;

			if(uAccLen > NAME_LENGTH - 1 || uAccLen == 0 || uTokenLen > NAME_LENGTH - 1  || uTokenLen == 0)
			{
				logclif_auth_failed(sd, 3);
				return 0;
			}

			safestrncpy(username, accname, uAccLen + 1);
			safestrncpy(password, token, uTokenLen + 1);
			clienttype = RFIFOB(fd, 8);
		}
		else
		{
			safestrncpy(username, RFIFOCP(fd,6), NAME_LENGTH);
			if( israwpass )
			{
				safestrncpy(password, RFIFOCP(fd,30), PASSWD_LENGTH);
				clienttype = RFIFOB(fd,54);
			}
			else
			{
				memcpy(passhash, RFIFOP(fd,30), 16);
				clienttype = RFIFOB(fd,46);
			}
		}
		RFIFOSKIP(fd,RFIFOREST(fd)); // assume no other packet was sent

		sd->clienttype = clienttype;
		safestrncpy(sd->userid, username, NAME_LENGTH);
		if( israwpass )
		{
			ShowStatus("Request for connection of %s (ip: %s)\n", sd->userid, ip);
			safestrncpy(sd->passwd, password, NAME_LENGTH);
			if( login_config.use_md5_passwds )
				MD5_String(sd->passwd, sd->passwd);
			sd->passwdenc = 0;
		}
		else
		{
			ShowStatus("Request for connection (passwdenc mode) of %s (ip: %s)\n", sd->userid, ip);
			bin2hex(sd->passwd, passhash, 16); // raw binary data here!
			sd->passwdenc = PASSWORDENC;
		}

		if( sd->passwdenc != 0 && login_config.use_md5_passwds )
		{
			logclif_auth_failed(sd, 3); // send "rejected from server"
			return 0;
		}

		result = login_mmo_auth(sd, false);

		if( result == -1 )
			logclif_auth_ok(sd);
		else
			logclif_auth_failed(sd, result);
	}
	return 1;
}
Example #18
0
// Wisp/page request to send
int mapif_parse_WisRequest(int fd)
{
	struct WisData* wd;
	char name[NAME_LENGTH];
	char esc_name[NAME_LENGTH*2+1];// escaped name
	char* data;
	size_t len;


	if ( fd <= 0 ) {return 0;} // check if we have a valid fd

	if (RFIFOW(fd,2)-52 >= sizeof(wd->msg)) {
		ShowWarning("inter: Wis message size too long.\n");
		return 0;
	} else if (RFIFOW(fd,2)-52 <= 0) { // normaly, impossible, but who knows...
		ShowError("inter: Wis message doesn't exist.\n");
		return 0;
	}

	safestrncpy(name, RFIFOCP(fd,28), NAME_LENGTH); //Received name may be too large and not contain \0! [Skotlex]

	Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `name` FROM `%s` WHERE `name`='%s'", schema_config.char_db, esc_name) )
		Sql_ShowDebug(sql_handle);

	// search if character exists before to ask all map-servers
	if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
	{
		unsigned char buf[27];
		WBUFW(buf, 0) = 0x3802;
		memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH);
		WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
		chmapif_send(fd, buf, 27);
	}
	else
	{// Character exists. So, ask all map-servers
		// to be sure of the correct name, rewrite it
		Sql_GetData(sql_handle, 0, &data, &len);
		memset(name, 0, NAME_LENGTH);
		memcpy(name, data, zmin(len, NAME_LENGTH));
		// if source is destination, don't ask other servers.
		if( strncmp(RFIFOCP(fd,4), name, NAME_LENGTH) == 0 )
		{
			uint8 buf[27];
			WBUFW(buf, 0) = 0x3802;
			memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH);
			WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
			chmapif_send(fd, buf, 27);
		}
		else
		{
			static int wisid = 0;

			CREATE(wd, struct WisData, 1);

			// Whether the failure of previous wisp/page transmission (timeout)
			check_ttl_wisdata();

			wd->id = ++wisid;
			wd->fd = fd;
			wd->len= RFIFOW(fd,2)-52;
			memcpy(wd->src, RFIFOP(fd, 4), NAME_LENGTH);
			memcpy(wd->dst, RFIFOP(fd,28), NAME_LENGTH);
			memcpy(wd->msg, RFIFOP(fd,52), wd->len);
			wd->tick = gettick();
			idb_put(wis_db, wd->id, wd);
			mapif_wis_message(wd);
		}
	}

	Sql_FreeResult(sql_handle);
	return 0;
}