rem: out << progress_bar(s.progress, 49);
add: out << progress_bar(s.progress, 49, progress_bar_color);
context: int main(int argc, char* argv[]){	using namespace libtorrent;	if (argc < 2)	{		std::cerr << "usage: ./client_test torrent-files ...\n"			"to stop the client, press q.\n";		return 1;	}	namespace fs = boost::filesystem;	fs::path::default_name_check(fs::no_check);		http_settings settings;//	settings.proxy_ip = "192.168.0.1";//	settings.proxy_port = 80;//	settings.proxy_login = "hyd";//	settings.proxy_password = "foobar";	settings.user_agent = "client_test";	std::deque<std::string> events;	try	{		std::vector<torrent_handle> handles;		session ses;		ses.listen_on(std::make_pair(6880, 6889));//		ses.set_upload_rate_limit(512 * 1024);		ses.set_http_settings(settings);		ses.set_severity_level(alert::debug);//		ses.set_severity_level(alert::info);		// look for ipfilter.dat		// poor man's parser		// reads emule ipfilter files.		// with the following format:		// 		// <first-ip> - <last-ip> , <access> , <comment>		// 		// first-ip is an ip address that defines the first		// address of the range		// last-ip is the last ip address in the range		// access is a number specifying the access control		// for this ip-range. Right now values > 127 = allowed		// and numbers <= 127 = blocked		// the rest of the line is ignored		//		// In the original spec ranges may not overlap, but		// here ranges may overlap, and it is the last added		// rule that has precedence for addresses that may fall		// into more than one range.		std::ifstream in("ipfilter.dat");		ip_filter filter;		while (in.good())		{			char line[300];			in.getline(line, 300);			int len = in.gcount();			if (len <= 0) continue;			if (line[0] == '#') continue;			int a, b, c, d;			char dummy;			in >> a >> dummy >> b >> dummy >> c >> dummy >> d >> dummy;			address start(a, b, c, d, 0);			in >> a >> dummy >> b >> dummy >> c >> dummy >> d >> dummy;			address last(a, b, c, d, 0);			int flags;			in >> flags;			if (flags <= 127) flags = ip_filter::blocked;			else flags = 0;			if (in.fail()) break;			filter.add_rule(start, last, flags);		}			ses.set_ip_filter(filter);			for (int i = 0; i < argc-1; ++i)		{			try			{				boost::filesystem::path save_path("./");				if (std::string(argv[i+1]).substr(0, 7) == "http://")				{					sha1_hash info_hash = boost::lexical_cast<sha1_hash>(argv[i+2]);					handles.push_back(ses.add_torrent(argv[i+1], info_hash, save_path));					handles.back().set_max_connections(60);					handles.back().set_max_uploads(-1);//					handles.back().set_ratio(1.1f);					++i;					continue;				}				std::ifstream in(argv[i+1], std::ios_base::binary);				in.unsetf(std::ios_base::skipws);				entry e = bdecode(std::istream_iterator<char>(in), std::istream_iterator<char>());				torrent_info t(e);				t.print(std::cout);				entry resume_data;				try				{					std::stringstream s;					s << t.name() << ".fastresume";					boost::filesystem::ifstream resume_file(save_path / s.str(), std::ios_base::binary);					resume_file.unsetf(std::ios_base::skipws);					resume_data = bdecode(						std::istream_iterator<char>(resume_file)						, std::istream_iterator<char>());				}				catch (invalid_encoding&) {}				catch (boost::filesystem::filesystem_error&) {}				handles.push_back(ses.add_torrent(e, save_path, resume_data, true, 64 * 1024));				handles.back().set_max_connections(60);				handles.back().set_max_uploads(-1);//				handles.back().set_ratio(1.02f);			}			catch (std::exception& e)			{				std::cout << e.what() << "\n";			}		}		if (handles.empty()) return 1;		std::vector<peer_info> peers;		std::vector<partial_piece_info> queue;		bool print_peers = false;		bool print_log = false;		bool print_downloads = false;		for (;;)		{			char c;			if (sleep_and_input(&c))			{				if (c == 'q')				{					for (std::vector<torrent_handle>::iterator i = handles.begin();						i != handles.end(); ++i)					{						torrent_handle h = *i;						if (!h.get_torrent_info().is_valid()) continue;						h.pause();						entry data = h.write_resume_data();						std::stringstream s;						s << h.get_torrent_info().name() << ".fastresume";						boost::filesystem::ofstream out(h.save_path() / s.str(), std::ios_base::binary);						out.unsetf(std::ios_base::skipws);						bencode(std::ostream_iterator<char>(out), data);						ses.remove_torrent(*i);					}					break;				}				if(c == 'r')				{					// force reannounce on all torrents					std::for_each(						handles.begin()						, handles.end()						, boost::bind(&torrent_handle::force_reannounce, _1));				}				if(c == 'p')				{					// pause all torrents					std::for_each(						handles.begin()						, handles.end()						, boost::bind(&torrent_handle::pause, _1));				}				if(c == 'u')				{					// unpause all torrents					std::for_each(						handles.begin()						, handles.end()						, boost::bind(&torrent_handle::resume, _1));				}				if (c == 'i') print_peers = !print_peers;				if (c == 'l') print_log = !print_log;				if (c == 'd') print_downloads = !print_downloads;			}			// loop through the alert queue to see if anything has happened.			std::auto_ptr<alert> a;			a = ses.pop_alert();			while (a.get())			{				if (torrent_finished_alert* p = dynamic_cast<torrent_finished_alert*>(a.get()))				{					// limit the bandwidth for all seeding torrents					p->handle.set_max_connections(10);					//p->handle.set_max_uploads(5);					//p->handle.set_upload_limit(10000);					// all finished downloades are					// moved into this directory					//p->handle.move_storage("finished");					events.push_back(						p->handle.get_torrent_info().name() + ": " + a->msg());				}				else if (peer_error_alert* p = dynamic_cast<peer_error_alert*>(a.get()))				{					events.push_back(identify_client(p->id) + ": " + a->msg());				}				else if (invalid_request_alert* p = dynamic_cast<invalid_request_alert*>(a.get()))				{					events.push_back(identify_client(p->id) + ": " + a->msg());				}				else				{					events.push_back(a->msg());				}				if (events.size() >= 10) events.pop_front();				a = ses.pop_alert();			}			std::stringstream out;			for (std::vector<torrent_handle>::iterator i = handles.begin();				i != handles.end(); ++i)			{				if (!i->is_valid())				{					handles.erase(i);					--i;					continue;				}				out << "name: ";				if (i->has_metadata()) out << i->get_torrent_info().name();				else out << "-";				out << "\n";				torrent_status s = i->status();				if (s.state != torrent_status::seeding)				{					switch(s.state)					{						case torrent_status::queued_for_checking:							out << "queued ";							break;						case torrent_status::checking_files:							out << "checking ";							break;						case torrent_status::connecting_to_tracker:							out << "connecting to tracker ";							break;						case torrent_status::downloading_metadata:							out << "downloading metadata ";							break;						case torrent_status::downloading:							out << "downloading ";							break;						case torrent_status::finished:							out << "finished ";							break;						case torrent_status::seeding:							out << "seeding ";							break;					};				}				i->get_peer_info(peers);				if (s.state != torrent_status::seeding)				{					out.precision(4);					out.width(5);					out.fill(' ');					out << (s.progress*100) << "% ";					out << progress_bar(s.progress, 49);					out << "\n";					out << "total downloaded: " << s.total_done << " Bytes\n";					out	<< "peers: " << s.num_peers << " "						<< "seeds: " << s.num_seeds << " "						<< "distributed copies: " << s.distributed_copies << "\n";				}				out << "download: " << add_suffix(s.download_rate) << "/s "					<< "(" << add_suffix(s.total_download) << ") "					<< "upload: " << add_suffix(s.upload_rate) << "/s "					<< "(" << add_suffix(s.total_upload) << ") "					<< "ratio: " << ratio(s.total_payload_download, s.total_payload_upload) << "\n";				if (s.state != torrent_status::seeding)				{					out << "info-hash: " << i->info_hash() << "\n";					boost::posix_time::time_duration t = s.next_announce;					out << "next announce: " << boost::posix_time::to_simple_string(t) << "\n";					out << "tracker: " << s.current_tracker << "\n";				}				out << "___________________________________\n";				if (print_peers && !peers.empty())				{					print_peer_info(out, peers);					out << "___________________________________\n";				}				if (print_downloads && s.state != torrent_status::seeding)				{					i->get_download_queue(queue);					for (std::vector<partial_piece_info>::iterator i = queue.begin();						i != queue.end(); ++i)					{						out.width(4);						out.fill(' ');						out << i->piece_index << ": [";						for (int j = 0; j < i->blocks_in_piece; ++j)						{							if (i->finished_blocks[j]) out << "#";							else if (i->requested_blocks[j]) out << "+";							else out << "-";						}						out << "]\n";					}					out << "___________________________________\n";				}			}			if (print_log)			{				for (std::deque<std::string>::iterator i = events.begin();					i != events.end();					++i)				{					out << *i << "\n";				}			}			clear();			set_cursor(0, 0);			puts(out.str().c_str());//			std::cout << out.str();//			std::cout.flush();		}	}	catch (std::exception& e)	{  		std::cout << e.what() << "\n";	}	return 0;}