1 /*
2 	OpenLieroX
3 
4 	reader for IpToCountry database
5 
6 	code under LGPL
7 	by Albert Zeyer and Dark Charlie
8 */
9 
10 
11 #include "IpToCountryDB.h"
12 #include "GfxPrimitives.h"
13 #include "Unicode.h"
14 #include "GeoIPDatabase.h"
15 #include "Networking.h"
16 
17 const char *IP_TO_COUNTRY_FILE = "GeoIP.dat";
18 
IpToCountryDB(const std::string & dbfile)19 IpToCountryDB::IpToCountryDB(const std::string& dbfile) : m_database(NULL) { LoadDBFile(dbfile); }
20 
LoadDBFile(const std::string & dbfile)21 void IpToCountryDB::LoadDBFile(const std::string& dbfile)
22 {
23 	if (m_database)  {
24 		delete m_database;
25 		m_database = NULL;
26 	}
27 
28 	// Test: database
29 	m_database = new GeoIPDatabase();
30 	if (!m_database->load(dbfile))
31 		errors << "Error when loading GeoIP database" << endl;
32 }
33 
GetInfoAboutIP(const std::string & address)34 IpInfo IpToCountryDB::GetInfoAboutIP(const std::string& address)
35 {
36 	IpInfo res;
37 	if (!m_database || !m_database->loaded())
38 		return res;
39 
40 	// Home
41 	if (address.find("127.0.0.1") == 0)  {
42 		res.countryName = "Home";
43 		res.city = "Home City";
44 		res.region = "Home Region";
45 		res.continent = "Earth";
46 		return res;
47 	}
48 
49 	// LAN
50 	if (address.find("10.0.") == 0 || address.find("192.168.") == 0)  {
51 		res.countryName = "Local Area Network";
52 		res.city = "Local City";
53 		res.region = "Local Area Network";
54 		return res;
55 	}
56 
57 	// IPv6
58 	if (IsNetAddrV6(address))  {
59 		res.countryName = "IPv6 Network";
60 		res.countryCode = "v6";
61 		res.city = "IPv6 Network";
62 		res.region = "IPv6 Network";
63 		return res;
64 	}
65 
66 	GeoRecord rec = m_database->lookup(address);
67 	if (rec.countryCode == "--" || rec.countryCode == "UN")  // Unknown
68 		return res;
69 
70 	res = rec;
71 
72 	return res;
73 }
74 
GetCountryFlag(const std::string & shortcut)75 SmartPointer<SDL_Surface> IpToCountryDB::GetCountryFlag(const std::string& shortcut)
76 {
77 	return LoadGameImage("data/flags/" + shortcut + ".png", true);
78 }
79 
80 ////////////////////
81 // Calculate distance (in kilometers) between the two places
GetDistance(const IpInfo & place1,const IpInfo & place2)82 float IpToCountryDB::GetDistance(const IpInfo &place1, const IpInfo &place2)
83 {
84 	// Use Haversine formula
85 	static const double earth_radius = 6371.0;
86 	double dlat = DEG2RAD(place2.latitude - place1.latitude);
87 	double dlong = DEG2RAD(place2.longitude - place1.longitude);
88 	double a = SQR(sin(dlat/2)) + cos(DEG2RAD(place1.latitude)) * cos(DEG2RAD(place2.latitude)) * SQR(sin(dlong/2));
89 	double c = 2 * atan2(sqrt(a), sqrt(1 - a));
90 	return (float)(earth_radius * c);
91 }
92 
~IpToCountryDB()93 IpToCountryDB::~IpToCountryDB()
94 {
95 	if (m_database)  {
96 		delete m_database;
97 		m_database = NULL;
98 	}
99 }
100