Exemple #1
0
/**
 * Inform client that auth has failed.
 * @param sd: player session
 * @param result: nb (msg define in conf)
    0 = Unregistered ID
    1 = Incorrect Password
    2 = This ID is expired
    3 = Rejected from Server
    4 = You have been blocked by the GM Team
    5 = Your Game's EXE file is not the latest version
    6 = Your are Prohibited to log in until %s
    7 = Server is jammed due to over populated
    8 = No more accounts may be connected from this company
    9 = MSI_REFUSE_BAN_BY_DBA
    10 = MSI_REFUSE_EMAIL_NOT_CONFIRMED
    11 = MSI_REFUSE_BAN_BY_GM
    12 = MSI_REFUSE_TEMP_BAN_FOR_DBWORK
    13 = MSI_REFUSE_SELF_LOCK
    14 = MSI_REFUSE_NOT_PERMITTED_GROUP
    15 = MSI_REFUSE_NOT_PERMITTED_GROUP
    99 = This ID has been totally erased
    100 = Login information remains at %s
    101 = Account has been locked for a hacking investigation. Please contact the GM Team for more information
    102 = This account has been temporarily prohibited from login due to a bug-related investigation
    103 = This character is being deleted. Login is temporarily unavailable for the time being
    104 = This character is being deleted. Login is temporarily unavailable for the time being
     default = Unknown Error.
 */
static void logclif_auth_failed(struct login_session_data* sd, int result) {
	int fd = sd->fd;
	uint32 ip = session[fd]->client_addr;

	if (login_config.log_login)
	{
		if(result >= 0 && result <= 15)
		    login_log(ip, sd->userid, result, msg_txt(result));
		else if(result >= 99 && result <= 104)
		    login_log(ip, sd->userid, result, msg_txt(result-83)); //-83 offset
		else
		    login_log(ip, sd->userid, result, msg_txt(22)); //unknow error
	}

	if( (result == 0 || result == 1) && login_config.dynamic_pass_failure_ban )
		ipban_log(ip); // log failed password attempt

//#if PACKETVER >= 20120000 /* not sure when this started */
	if( sd->version >= date2version(20120000) ){ /* not sure when this started */
		WFIFOHEAD(fd,26);
		WFIFOW(fd,0) = 0x83e;
		WFIFOL(fd,2) = result;
		if( result != 6 )
			memset(WFIFOP(fd,6), '\0', 20);
		else { // 6 = Your are Prohibited to log in until %s
			struct mmo_account acc;
			AccountDB* accounts = login_get_accounts_db();
			time_t unban_time = ( accounts->load_str(accounts, &acc, sd->userid) ) ? acc.unban_time : 0;
			timestamp2string(WFIFOCP(fd,6), 20, unban_time, login_config.date_format);
		}
		WFIFOSET(fd,26);
	}
//#else	
	else {
		WFIFOHEAD(fd,23);
		WFIFOW(fd,0) = 0x6a;
		WFIFOB(fd,2) = (uint8)result;
		if( result != 6 )
			memset(WFIFOP(fd,3), '\0', 20);
		else { // 6 = Your are Prohibited to log in until %s
			struct mmo_account acc;
			AccountDB* accounts = login_get_accounts_db();
			time_t unban_time = ( accounts->load_str(accounts, &acc, sd->userid) ) ? acc.unban_time : 0;
			timestamp2string(WFIFOCP(fd,3), 20, unban_time, login_config.date_format);
		}
		WFIFOSET(fd,23);
	}
//#endif	
}
Exemple #2
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;
}
Exemple #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;
}
Exemple #4
0
/**
 * Request account_reg2 for a character.
 * @param fd: fd to parse from (char-serv)
 * @return 0 not enough info transmitted, 1 success
 */
int logchrif_parse_req_global_accreg(int fd){
	if (RFIFOREST(fd) < 10)
		return 0;
	else{
		AccountDB* accounts = login_get_accounts_db();
		uint32 account_id = RFIFOL(fd,2);
		uint32 char_id = RFIFOL(fd,6);
		RFIFOSKIP(fd,10);

		mmo_send_global_accreg(accounts,fd,account_id,char_id);
	}
	return 1;
}
Exemple #5
0
/**
 * Received a vip data reqest from char
 * type is the query to perform
 *  0x1 : Select info and update old_groupid
 *  0x2 : VIP duration is changed by atcommand or script
 *  0x8 : First request on player login
 * @param fd link to charserv
 * @return 0 missing data, 1 succeeded
 */
int logchrif_parse_reqvipdata(int fd) {
#ifdef VIP_ENABLE
	if( RFIFOREST(fd) < 15 )
		return 0;
	else { //request vip info
		struct mmo_account acc;
		AccountDB* accounts = login_get_accounts_db();
		int aid = RFIFOL(fd,2);
		int8 flag = RFIFOB(fd,6);
		int32 timediff = RFIFOL(fd,7);
		int mapfd = RFIFOL(fd,11);
		RFIFOSKIP(fd,15);
		
		if( accounts->load_num(accounts, &acc, aid ) ) {
			time_t now = time(NULL);
			time_t vip_time = acc.vip_time;
			bool isvip = false;

			if( acc.group_id > login_config.vip_sys.group ) { //Don't change group if it's higher.
				logchrif_sendvipdata(fd,acc,0x2|((flag&0x8)?0x4:0),mapfd);
				return 1;
			}
			if( flag&2 ) {
				if(!vip_time)
					vip_time = now; //new entry
				vip_time += timediff; // set new duration
			}
			if( now < vip_time ) { //isvip
				if(acc.group_id != login_config.vip_sys.group) //only upd this if we're not vip already
					acc.old_group = acc.group_id;
				acc.group_id = login_config.vip_sys.group;
				acc.char_slots = login_config.char_per_account + login_config.vip_sys.char_increase;
				isvip = true;
			} else { //expired or @vip -xx
				vip_time = 0;
				if(acc.group_id == login_config.vip_sys.group) //prevent alteration in case account wasn't registered as vip yet
					acc.group_id = acc.old_group;
				acc.old_group = 0;
				acc.char_slots = login_config.char_per_account;
			}
			acc.vip_time = vip_time;
			accounts->save(accounts,&acc);
			if( flag&1 )
				logchrif_sendvipdata(fd,acc,((isvip)?0x1:0)|((flag&0x8)?0x4:0),mapfd);
		}
	}
#endif
	return 1;
}
Exemple #6
0
/**
 * Transmit account data to char_server
 * S 2717 aid.W email.40B exp_time.L group_id.B char_slot.B birthdate.11B pincode.5B pincode_change.L
 *  isvip.1B char_vip.1B max_billing.1B (tot 75)  
 * @return -1 : account not found, 1:sucess
 */
int logchrif_send_accdata(int fd, uint32 aid) {
	struct mmo_account acc;
	time_t expiration_time = 0;
	char email[40] = "";
	int group_id = 0;
	char birthdate[10+1] = "";
	char pincode[PINCODE_LENGTH+1];
	char isvip = false;
	uint8 char_slots = MIN_CHARS, char_vip = 0, char_billing = 0;
	AccountDB* accounts = login_get_accounts_db();

	memset(pincode,0,PINCODE_LENGTH+1);
	if( !accounts->load_num(accounts, &acc, aid) )
		return -1;
	else {
		safestrncpy(email, acc.email, sizeof(email));
		expiration_time = acc.expiration_time;
		group_id = acc.group_id;

		safestrncpy(birthdate, acc.birthdate, sizeof(birthdate));
		safestrncpy(pincode, acc.pincode, sizeof(pincode));
#ifdef VIP_ENABLE
		char_vip = login_config.vip_sys.char_increase;
		if( acc.vip_time > time(NULL) ) {
			isvip = true;
			char_slots = login_config.char_per_account + char_vip;
		} else
			char_slots = login_config.char_per_account;
		char_billing = MAX_CHAR_BILLING; //TODO create a config for this
#endif
	}

	WFIFOHEAD(fd,75);
	WFIFOW(fd,0) = 0x2717;
	WFIFOL(fd,2) = aid;
	safestrncpy(WFIFOCP(fd,6), email, 40);
	WFIFOL(fd,46) = (uint32)expiration_time;
	WFIFOB(fd,50) = (unsigned char)group_id;
	WFIFOB(fd,51) = char_slots;
	safestrncpy(WFIFOCP(fd,52), birthdate, 10+1);
	safestrncpy(WFIFOCP(fd,63), pincode, 4+1 );
	WFIFOL(fd,68) = (uint32)acc.pincode_change;
	WFIFOB(fd,72) = isvip;
	WFIFOB(fd,73) = char_vip;
	WFIFOB(fd,74) = char_billing;
	WFIFOSET(fd,75);
	return 1;
}
Exemple #7
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;
}
Exemple #8
0
/**
 * We receive account_reg2 from a char-server, and we send them to other char-servers.
 * @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_upd_global_accreg(int fd, int id, char* ip){
	if( RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2) )
		return 0;
	else{
		struct mmo_account acc;
		AccountDB* accounts = login_get_accounts_db();
		uint32 account_id = RFIFOL(fd,4);

		if( !accounts->load_num(accounts, &acc, account_id) )
			ShowStatus("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d not found, ip: %s).\n", ch_server[id].name, account_id, ip);
		else
			mmo_save_global_accreg(accounts,fd,account_id,RFIFOL(fd, 8));
		RFIFOSKIP(fd,RFIFOW(fd,2));
	}
	return 1;
}
Exemple #9
0
/**
* IA 0x2720
* Get account info that asked by inter/char-server
*/
int logchrif_parse_accinfo(int fd) {
	if( RFIFOREST(fd) < 23 )
		return 0;
	else {
		int map_fd = RFIFOL(fd, 2), u_fd = RFIFOL(fd, 6), u_aid = RFIFOL(fd, 10), account_id = RFIFOL(fd, 14);
		int8 type = RFIFOB(fd, 18);
		AccountDB* accounts = login_get_accounts_db();
		struct mmo_account acc;
		RFIFOSKIP(fd,19);

		// Send back the result to char-server
		if (accounts->load_num(accounts, &acc, account_id)) {
			int len = 122 + NAME_LENGTH;
			//ShowInfo("Found account info for %d, requested by %d\n", account_id, u_aid);
			WFIFOHEAD(fd, len);
			WFIFOW(fd, 0) = 0x2721;
			WFIFOL(fd, 2) = map_fd;
			WFIFOL(fd, 6) = u_fd;
			WFIFOL(fd, 10) = u_aid;
			WFIFOL(fd, 14) = account_id;
			WFIFOB(fd, 18) = (1<<type); // success
			WFIFOL(fd, 19) = acc.group_id;
			WFIFOL(fd, 23) = acc.logincount;
			WFIFOL(fd, 27) = acc.state;
			safestrncpy(WFIFOCP(fd, 31), acc.email, 40);
			safestrncpy(WFIFOCP(fd, 71), acc.last_ip, 16);
			safestrncpy(WFIFOCP(fd, 87), acc.lastlogin, 24);
			safestrncpy(WFIFOCP(fd, 111), acc.birthdate, 11);
			safestrncpy(WFIFOCP(fd, 122), acc.userid, NAME_LENGTH);
			WFIFOSET(fd, len);
		}
		else {
			//ShowInfo("Cannot found account info for %d, requested by %d\n", account_id, u_aid);
			WFIFOHEAD(fd, 19);
			WFIFOW(fd, 0) = 0x2721;
			WFIFOL(fd, 2) = map_fd;
			WFIFOL(fd, 6) = u_fd;
			WFIFOL(fd, 10) = u_aid;
			WFIFOL(fd, 14) = account_id;
			WFIFOB(fd, 18) = 0; // failed
			WFIFOSET(fd, 19);
		}
	}
	return 1;
}
Exemple #10
0
/**
 * Receiving a ban request from map-server via char-server.
 * @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
 * TODO check logchrif_parse_requpdaccstate for possible merge
 */
int logchrif_parse_reqbanacc(int fd, int id, char* ip){
	if (RFIFOREST(fd) < 10)
		return 0;
	else{
		struct mmo_account acc;
		AccountDB* accounts = login_get_accounts_db();

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

		if( !accounts->load_num(accounts, &acc, account_id) )
			ShowNotice("Char-server '%s': Error of ban request (account: %d not found, ip: %s).\n", ch_server[id].name, account_id, ip);
		else{
			time_t timestamp;
			if (acc.unban_time == 0 || acc.unban_time < time(NULL))
				timestamp = time(NULL); // new ban
			else
				timestamp = acc.unban_time; // add to existing ban
			timestamp += timediff;
			if (timestamp == -1)
				ShowNotice("Char-server '%s': Error of ban request (account: %d, invalid date, ip: %s).\n", ch_server[id].name, account_id, ip);
			else if( timestamp <= time(NULL) || timestamp == 0 )
				ShowNotice("Char-server '%s': Error of ban request (account: %d, new date unbans the account, ip: %s).\n", ch_server[id].name, account_id, ip);
			else{
				uint8 buf[11];
				char tmpstr[24];
				timestamp2string(tmpstr, sizeof(tmpstr), timestamp, login_config.date_format);
				ShowNotice("Char-server '%s': Ban request (account: %d, new final date of banishment: %d (%s), ip: %s).\n", ch_server[id].name, account_id, timestamp, tmpstr, ip);

				acc.unban_time = timestamp;

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

				WBUFW(buf,0) = 0x2731;
				WBUFL(buf,2) = account_id;
				WBUFB(buf,6) = 1; // 0: change of status, 1: ban
				WBUFL(buf,7) = (uint32)timestamp; // status or final date of a banishment
				logchrif_sendallwos(-1, buf, 11);
			}
		}
	}
	return 1;
}
Exemple #11
0
/**
 * PIN Code was incorrectly entered too many times.
 * @param fd: fd to parse from (char-serv)
 * @return 0 fail (packet does not have enough data), 1 success (continue parsing)
 */
int logchrif_parse_pincode_authfail(int fd){
	if( RFIFOREST(fd) < 6 )
		return 0;
	else{
		struct mmo_account acc;
		AccountDB* accounts = login_get_accounts_db();
		if( accounts->load_num(accounts, &acc, RFIFOL(fd,2) ) ){
			struct online_login_data* ld;

			ld = (struct online_login_data*)idb_get(online_db,acc.account_id);

			if( ld == NULL )
				return 0;

			login_log( host2ip(acc.last_ip), acc.userid, 100, "PIN Code check failed" );
		}
		login_remove_online_user(acc.account_id);
		RFIFOSKIP(fd,6);
	}
	return 1;
}
Exemple #12
0
/**
 * Receiving an unban request from map-server via char-server.
 * @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_requnbanacc(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 UnBan request (account: %d not found, ip: %s).\n", ch_server[id].name, account_id, ip);
		else if( acc.unban_time == 0 )
			ShowNotice("Char-server '%s': Error of UnBan request (account: %d, no change for unban date, ip: %s).\n", ch_server[id].name, account_id, ip);
		else{
			ShowNotice("Char-server '%s': UnBan request (account: %d, ip: %s).\n", ch_server[id].name, account_id, ip);
			acc.unban_time = 0;
			accounts->save(accounts, &acc);
		}
	}
	return 1;
}
Exemple #13
0
/**
 * Receiving an account state update request from a map-server (relayed via char-server).
 * @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
 * TODO seems pretty damn close to logchrif_parse_reqbanacc
 */
int logchrif_parse_requpdaccstate(int fd, int id, char* ip){
	if (RFIFOREST(fd) < 10)
		return 0;
	else{
		struct mmo_account acc;

		uint32 account_id = RFIFOL(fd,2);
		unsigned int state = RFIFOL(fd,6);
		AccountDB* accounts = login_get_accounts_db();

		RFIFOSKIP(fd,10);

		if( !accounts->load_num(accounts, &acc, account_id) )
			ShowNotice("Char-server '%s': Error of Status change (account: %d not found, suggested status %d, ip: %s).\n", ch_server[id].name, account_id, state, ip);
		else if( acc.state == state )
			ShowNotice("Char-server '%s':  Error of Status change - actual status is already the good status (account: %d, status %d, ip: %s).\n", ch_server[id].name, account_id, state, ip);
		else{
			ShowNotice("Char-server '%s': Status change (account: %d, new status %d, ip: %s).\n", ch_server[id].name, account_id, state, ip);

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

			// notify other servers
			if (state != 0){
				uint8 buf[11];
				WBUFW(buf,0) = 0x2731;
				WBUFL(buf,2) = account_id;
				WBUFB(buf,6) = 0; // 0: change of state, 1: ban
				WBUFL(buf,7) = state; // status or final date of a banishment
				logchrif_sendallwos(-1, buf, 11);
			}
		}
	}
	return 1;
}