예제 #1
0
int chlogif_parse_askkick(int fd, struct char_session_data* sd){
	if (RFIFOREST(fd) < 6)
		return 0;
	else {
		DBMap*  online_char_db = char_get_onlinedb();
		DBMap*  auth_db = char_get_authdb();
		int aid = RFIFOL(fd,2);
		struct online_char_data* character = (struct online_char_data*)idb_get(online_char_db, aid);
		RFIFOSKIP(fd,6);
		if( character != NULL )
		{// account is already marked as online!
			if( character->server > -1 )
			{	//Kick it from the map server it is on.
				mapif_disconnectplayer(map_server[character->server].fd, character->account_id, character->char_id, 2);
				if (character->waiting_disconnect == INVALID_TIMER)
					character->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, char_chardb_waiting_disconnect, character->account_id, 0);
			}
			else
			{// Manual kick from char server.
				struct char_session_data *tsd;
				int i;
				ARR_FIND( 0, fd_max, i, session[i] && (tsd = (struct char_session_data*)session[i]->session_data) && tsd->account_id == aid );
				if( i < fd_max )
				{
					chclif_send_auth_result(i,2);  //Send "Someone has already logged in with this id"
					set_eof(i);
				}
				else // still moving to the map-server
					char_set_char_offline(-1, aid);
			}
		}
		idb_remove(auth_db, aid);// reject auth attempts from map-server
	}
	return 1;
}
예제 #2
0
/**
 * Map-serv sent us all his users info, (aid and cid) so we can update online_char_db
 * @param fd: wich fd to parse from
 * @param id: wich map_serv id
 * @return : 0 not enough data received, 1 success
 */
int chmapif_parse_regmapuser(int fd, int id){
	if (RFIFOREST(fd) < 6 || RFIFOREST(fd) < RFIFOW(fd,2))
		return 0;
	{
		//TODO: When data mismatches memory, update guild/party online/offline states.
		DBMap* online_char_db = char_get_onlinedb();
		int i;

		map_server[id].users = RFIFOW(fd,4);
		online_char_db->foreach(online_char_db,char_db_setoffline,id); //Set all chars from this server as 'unknown'
		for(i = 0; i < map_server[id].users; i++) {
			int aid = RFIFOL(fd,6+i*8);
			int cid = RFIFOL(fd,6+i*8+4);
			struct online_char_data* character = idb_ensure(online_char_db, aid, char_create_online_data);
			if( character->server > -1 && character->server != id )
			{
				ShowNotice("Set map user: Character (%d:%d) marked on map server %d, but map server %d claims to have (%d:%d) online!\n",
					character->account_id, character->char_id, character->server, id, aid, cid);
				mapif_disconnectplayer(map_server[character->server].fd, character->account_id, character->char_id, 2);
			}
			character->server = id;
			character->char_id = cid;
		}
		//If any chars remain in -2, they will be cleaned in the cleanup timer.
		RFIFOSKIP(fd,RFIFOW(fd,2));
	}
	return 1;
}
예제 #3
0
void chlogif_pincode_start(int fd, struct char_session_data* sd){
	if( charserv_config.pincode_config.pincode_enabled ){
		//ShowInfo("Asking to start pincode to AID: %d\n", sd->account_id);
		// PIN code system enabled
		if( sd->pincode[0] == '\0' ){
			// No PIN code has been set yet
			if( charserv_config.pincode_config.pincode_force ){
				chclif_pincode_sendstate( fd, sd, PINCODE_NEW );
			}else{
				chclif_pincode_sendstate( fd, sd, PINCODE_PASSED );
			}
		}else{
			if( !(charserv_config.pincode_config.pincode_changetime)
			|| ( sd->pincode_change + charserv_config.pincode_config.pincode_changetime ) > time(NULL) ){
				DBMap*  online_char_db = char_get_onlinedb();
				struct online_char_data* node = (struct online_char_data*)idb_get( online_char_db, sd->account_id );

				if( node != NULL && node->pincode_success ){
					// User has already passed the check
					chclif_pincode_sendstate( fd, sd, PINCODE_PASSED );
				}else{
					// Ask user for his PIN code
					chclif_pincode_sendstate( fd, sd, PINCODE_ASK );
				}
			}else{
				// User hasnt changed his PIN code too long
				chclif_pincode_sendstate( fd, sd, PINCODE_EXPIRED );
			}
		}
	}else{
		// PIN code system disabled
		//ShowInfo("Pincode is disabled.\n");
		chclif_pincode_sendstate( fd, sd, PINCODE_OK );
	}
}
예제 #4
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);
	}
예제 #5
0
파일: int_mail.cpp 프로젝트: AlmasB/rathena
int mail_timer_sub( int limit, enum mail_inbox_type type ){
	struct{
		int mail_id;
		int char_id;
		int account_id;
	}mails[MAIL_MAX_INBOX];
	int i, map_fd;
	char* data;
	struct online_char_data* character;

	if( limit <= 0 ){
		return 0;
	}

	memset(mails, 0, sizeof(mails));

	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `id`,`char_id`,`account_id` FROM `%s` `m` INNER JOIN `%s` `c` ON `c`.`char_id`=`m`.`dest_id` WHERE `type` = '%d' AND `time` <= UNIX_TIMESTAMP( NOW() - INTERVAL %d DAY ) ORDER BY `id` LIMIT %d", schema_config.mail_db, schema_config.char_db, type, limit, MAIL_MAX_INBOX + 1) ){
		Sql_ShowDebug(sql_handle);
		return 0;
	}

	if( Sql_NumRows(sql_handle) <= 0 ){
		return 0;
	}

	for( i = 0; i < MAIL_MAX_INBOX && SQL_SUCCESS == Sql_NextRow(sql_handle); i++ ){
		Sql_GetData(sql_handle, 0, &data, NULL); mails[i].mail_id = atoi(data);
		Sql_GetData(sql_handle, 1, &data, NULL); mails[i].char_id = atoi(data);
		Sql_GetData(sql_handle, 2, &data, NULL); mails[i].account_id = atoi(data);
	}

	Sql_FreeResult(sql_handle);

	for( i = 0; i < MAIL_MAX_INBOX; i++ ){
		if( mails[i].mail_id == 0 ){
			break;
		}

		// Check for online players
		if( ( character = (struct online_char_data*)idb_get(char_get_onlinedb(), mails[i].account_id) ) != NULL && character->server >= 0 ){
			map_fd = map_server[character->server].fd;
		}else{
			map_fd = 0;
		}

		if( type == MAIL_INBOX_NORMAL ){
			mapif_Mail_return( 0, mails[i].char_id, mails[i].mail_id );
			mapif_Mail_delete( map_fd, mails[i].char_id, mails[i].mail_id, true );
		}else if( type == MAIL_INBOX_RETURNED ){
			mapif_Mail_delete( map_fd, mails[i].char_id, mails[i].mail_id, false );
		}else{
			// Should not happen
			continue;
		}
	}

	return 0;
}
예제 #6
0
/**
 * Player Requesting char-select from map_serv
 * @param fd: wich fd to parse from
 * @return : 0 not enough data received, 1 success
 */
int chmapif_parse_authok(int fd){
	if( RFIFOREST(fd) < 19 )
		return 0;
	else{
		uint32 account_id = RFIFOL(fd,2);
		uint32 login_id1 = RFIFOL(fd,6);
		uint32 login_id2 = RFIFOL(fd,10);
		uint32 ip = RFIFOL(fd,14);
		int version = RFIFOB(fd,18);
		RFIFOSKIP(fd,19);

		if( runflag != CHARSERVER_ST_RUNNING ){
			WFIFOHEAD(fd,7);
			WFIFOW(fd,0) = 0x2b03;
			WFIFOL(fd,2) = account_id;
			WFIFOB(fd,6) = 0;// not ok
			WFIFOSET(fd,7);
		}else{
			struct auth_node* node;
			DBMap*  auth_db = char_get_authdb();
			DBMap* online_char_db = char_get_onlinedb();

			// create temporary auth entry
			CREATE(node, struct auth_node, 1);
			node->account_id = account_id;
			node->char_id = 0;
			node->login_id1 = login_id1;
			node->login_id2 = login_id2;
			//node->sex = 0;
			node->ip = ntohl(ip);
			node->version = version; //upd version for mapserv
			//node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server)
			//node->gmlevel = 0;
			idb_put(auth_db, account_id, node);

			//Set char to "@ char select" in online db [Kevin]
			char_set_charselect(account_id);
			{
				struct online_char_data* character = (struct online_char_data*)idb_get(online_char_db, account_id);
				if( character != NULL ){
					character->pincode_success = true;
				}
			}

			WFIFOHEAD(fd,7);
			WFIFOW(fd,0) = 0x2b03;
			WFIFOL(fd,2) = account_id;
			WFIFOB(fd,6) = 1;// ok
			WFIFOSET(fd,7);
		}
	}
	return 1;
}
예제 #7
0
/**
 * Timered function to send all account_id connected to login-serv
 * @param tid : Timer id
 * @param tick : Scheduled tick
 * @param id : GID linked to that timered call
 * @param data : data transmited for delayed function
 * @return 
 */
int chlogif_send_acc_tologin(int tid, unsigned int tick, int id, intptr_t data) {
	if ( chlogif_isconnected() ){
		DBMap*  online_char_db = char_get_onlinedb();
		// send account list to login server
		int users = online_char_db->size(online_char_db);
		int i = 0;

		WFIFOHEAD(login_fd,8+users*4);
		WFIFOW(login_fd,0) = 0x272d;
		online_char_db->foreach(online_char_db, chlogif_send_acc_tologin_sub, &i, users);
		WFIFOW(login_fd,2) = 8+ i*4;
		WFIFOL(login_fd,4) = i;
		WFIFOSET(login_fd,WFIFOW(login_fd,2));
		return 1;
	}
	return 0;
}
예제 #8
0
/**
 * Map-serv request to save mmo_char_status in sql
 * Receive character data from map-server for saving
 * @param fd: wich fd to parse from
 * @param id: wich map_serv id
 * @return : 0 not enough data received, 1 success
 */
int chmapif_parse_reqsavechar(int fd, int id){
	if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
		return 0;
	{
		int aid = RFIFOL(fd,4), cid = RFIFOL(fd,8), size = RFIFOW(fd,2);
		struct online_char_data* character;
		DBMap* online_char_db = char_get_onlinedb();

		if (size - 13 != sizeof(struct mmo_charstatus))
		{
			ShowError("parse_from_map (save-char): Size mismatch! %d != %d\n", size-13, sizeof(struct mmo_charstatus));
			RFIFOSKIP(fd,size);
			return 1;
		}
		//Check account only if this ain't final save. Final-save goes through because of the char-map reconnect
		if (RFIFOB(fd,12) || RFIFOB(fd,13) || (
			(character = (struct online_char_data*)idb_get(online_char_db, aid)) != NULL &&
			character->char_id == cid))
		{
			struct mmo_charstatus char_dat;
			memcpy(&char_dat, RFIFOP(fd,13), sizeof(struct mmo_charstatus));
			char_mmo_char_tosql(cid, &char_dat);
		} else {	//This may be valid on char-server reconnection, when re-sending characters that already logged off.
			ShowError("parse_from_map (save-char): Received data for non-existant/offline character (%d:%d).\n", aid, cid);
			char_set_char_online(id, cid, aid);
		}

		if (RFIFOB(fd,12))
		{	//Flag, set character offline after saving. [Skotlex]
			char_set_char_offline(cid, aid);
			WFIFOHEAD(fd,10);
			WFIFOW(fd,0) = 0x2b21; //Save ack only needed on final save.
			WFIFOL(fd,2) = aid;
			WFIFOL(fd,6) = cid;
			WFIFOSET(fd,10);
		}
		RFIFOSKIP(fd,size);
	}
	return 1;
}