예제 #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
/**
 * 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);
	}
예제 #3
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;
}
예제 #4
0
int chlogif_parse_ackchangesex(int fd, struct char_session_data* sd)
{
	if (RFIFOREST(fd) < 7)
		return 0;
	else {
		unsigned char buf[7];
		int acc = RFIFOL(fd,2);
		int sex = RFIFOB(fd,6);
		RFIFOSKIP(fd,7);

		if (acc > 0) { // TODO: Is this even possible?
			unsigned char i;
			int char_id = 0, class_ = 0, guild_id = 0;
			DBMap* auth_db = char_get_authdb();
			struct auth_node* node = (struct auth_node*)idb_get(auth_db, acc);
			SqlStmt *stmt;

			if (node != NULL)
				node->sex = sex;

			// get characters
			stmt = SqlStmt_Malloc(sql_handle);
			if (SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `char_id`, `class`, `guild_id` FROM `%s` WHERE `account_id` = '%d'", schema_config.char_db, acc) || SqlStmt_Execute(stmt)) {
				SqlStmt_ShowDebug(stmt);
				SqlStmt_Free(stmt);
			}

			SqlStmt_BindColumn(stmt, 0, SQLDT_INT,   &char_id,  0, NULL, NULL);
			SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &class_,   0, NULL, NULL);
			SqlStmt_BindColumn(stmt, 2, SQLDT_INT,   &guild_id, 0, NULL, NULL);

			for (i = 0; i < MAX_CHARS && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i) {
				chlogif_parse_change_sex_sub(sex, acc, char_id, class_, guild_id);
			}
			SqlStmt_Free(stmt);
		}

		// notify all mapservers about this change
		WBUFW(buf,0) = 0x2b0d;
		WBUFL(buf,2) = acc;
		WBUFB(buf,6) = sex;
		chmapif_sendall(buf, 7);
	}
	return 1;
}
예제 #5
0
int chlogif_parse_ackchangesex(int fd, struct char_session_data* sd){
	if (RFIFOREST(fd) < 7)
		return 0;
	{
		unsigned char buf[7];

		int acc = RFIFOL(fd,2);
		int sex = RFIFOB(fd,6);
		RFIFOSKIP(fd,7);

		if( acc > 0 )
		{// TODO: Is this even possible?
			uint32 char_id[MAX_CHARS];
			int class_[MAX_CHARS];
			int guild_id[MAX_CHARS];
			unsigned char num, i;
			char* data;
			DBMap*  auth_db = char_get_authdb();

			struct auth_node* node = (struct auth_node*)idb_get(auth_db, acc);
			if( node != NULL )
				node->sex = sex;

			// get characters
			if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`class`,`guild_id` FROM `%s` WHERE `account_id` = '%d'", schema_config.char_db, acc) )
				Sql_ShowDebug(sql_handle);
			for( i = 0; i < MAX_CHARS && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
			{
				Sql_GetData(sql_handle, 0, &data, NULL); char_id[i] = atoi(data);
				Sql_GetData(sql_handle, 1, &data, NULL); class_[i] = atoi(data);
				Sql_GetData(sql_handle, 2, &data, NULL); guild_id[i] = atoi(data);
			}
			num = i;
			for( i = 0; i < num; ++i )
			{
				if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER ||
					class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY ||
					class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER ||
					class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER ||
					class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T ||
					class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER ||
					class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO )
				{
					// job modification
					if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER )
						class_[i] = (sex ? JOB_BARD : JOB_DANCER);
					else if( class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY )
						class_[i] = (sex ? JOB_CLOWN : JOB_GYPSY);
					else if( class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER )
						class_[i] = (sex ? JOB_BABY_BARD : JOB_BABY_DANCER);
					else if( class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER )
						class_[i] = (sex ? JOB_MINSTREL : JOB_WANDERER);
					else if( class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T )
						class_[i] = (sex ? JOB_MINSTREL_T : JOB_WANDERER_T);
					else if( class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER )
						class_[i] = (sex ? JOB_BABY_MINSTREL : JOB_BABY_WANDERER);
					else if( class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO )
						class_[i] = (sex ? JOB_KAGEROU : JOB_OBORO);
				}

				if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d', `weapon`='0', `shield`='0', `head_top`='0', `head_mid`='0', `head_bottom`='0' WHERE `char_id`='%d'", schema_config.char_db, class_[i], char_id[i]) )
					Sql_ShowDebug(sql_handle);

				if( guild_id[i] )// If there is a guild, update the guild_member data [Skotlex]
					inter_guild_sex_changed(guild_id[i], acc, char_id[i], sex);
			}
			Sql_FreeResult(sql_handle);

			// disconnect player if online on char-server
			char_disconnect_player(acc);
		}

		// notify all mapservers about this change
		WBUFW(buf,0) = 0x2b0d;
		WBUFL(buf,2) = acc;
		WBUFB(buf,6) = sex;
		chmapif_sendall(buf, 7);
	}
	return 1;
}