package net.nulll.uso.iPAVGeoGrabber;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import net.nulll.uso.iPAddressViewer.LogItem;
import net.nulll.uso.iPAddressViewer.Msg;
import net.nulll.uso.iPAddressViewer.iPAddressViewer;
import net.nulll.uso.iPAddressViewer.Uso;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
public final class iPAVGeoGrabber extends JavaPlugin{
static HashMap<String, GeoData> geoDataCache = new HashMap<String, GeoData>();
private final JavaPlugin plugin = this;
static List<DataSource> dataSources = new ArrayList<DataSource>();
static YamlConfiguration geoStats = new YamlConfiguration();
static HashMap<String,String> countryCodeMap = new HashMap<String,String>();
@Override
public void onEnable(){
//Load file that contains past data source statistics
geoStats = Uso.loadYaml(iPAddressViewer.staticPlugin.getDataFolder() + "/geoSourceStats.ipav");
//Create a list of supported data sources, along with their limits
dataSources = new ArrayList<DataSource>();
dataSources.add(new DataSource("ipTracker", "http://www.ip-tracker.org/locator/ip-lookup.php?ip=x.x.x.x", -1, 24*60*60*1000));
dataSources.add(new DataSource("whatismyipaddress", "http://whatismyipaddress.com/ip/x.x.x.x", 1, 5*60*1000));
dataSources.add(new DataSource("ipinfo", "http://ipinfo.io/x.x.x.x/geo", 1000, 24*60*60*1000));
dataSources.add(new DataSource("hackertarget", "http://api.hackertarget.com/geoip/?q=x.x.x.x", 100, 24*60*60*24));
//Populate a map of country codes in order to translate them later if needed
countryCodeMap.put("BD", "Bangladesh");
countryCodeMap.put("BE", "Belgium");
countryCodeMap.put("BF", "Burkina Faso");
countryCodeMap.put("BG", "Bulgaria");
countryCodeMap.put("BA", "Bosnia and Herzegovina");
countryCodeMap.put("BB", "Barbados");
countryCodeMap.put("WF", "Wallis and Futuna");
countryCodeMap.put("BL", "Saint Barthelemy");
countryCodeMap.put("BM", "Bermuda");
countryCodeMap.put("BN", "Brunei");
countryCodeMap.put("BO", "Bolivia");
countryCodeMap.put("BH", "Bahrain");
countryCodeMap.put("BI", "Burundi");
countryCodeMap.put("BJ", "Benin");
countryCodeMap.put("BT", "Bhutan");
countryCodeMap.put("JM", "Jamaica");
countryCodeMap.put("BV", "Bouvet Island");
countryCodeMap.put("BW", "Botswana");
countryCodeMap.put("WS", "Samoa");
countryCodeMap.put("BQ", "Bonaire, Saint Eustatius and Saba ");
countryCodeMap.put("BR", "Brazil");
countryCodeMap.put("BS", "Bahamas");
countryCodeMap.put("JE", "Jersey");
countryCodeMap.put("BY", "Belarus");
countryCodeMap.put("BZ", "Belize");
countryCodeMap.put("RU", "Russia");
countryCodeMap.put("RW", "Rwanda");
countryCodeMap.put("RS", "Serbia");
countryCodeMap.put("TL", "East Timor");
countryCodeMap.put("RE", "Reunion");
countryCodeMap.put("TM", "Turkmenistan");
countryCodeMap.put("TJ", "Tajikistan");
countryCodeMap.put("RO", "Romania");
countryCodeMap.put("TK", "Tokelau");
countryCodeMap.put("GW", "Guinea-Bissau");
countryCodeMap.put("GU", "Guam");
countryCodeMap.put("GT", "Guatemala");
countryCodeMap.put("GS", "South Georgia and the South Sandwich Islands");
countryCodeMap.put("GR", "Greece");
countryCodeMap.put("GQ", "Equatorial Guinea");
countryCodeMap.put("GP", "Guadeloupe");
countryCodeMap.put("JP", "Japan");
countryCodeMap.put("GY", "Guyana");
countryCodeMap.put("GG", "Guernsey");
countryCodeMap.put("GF", "French Guiana");
countryCodeMap.put("GE", "Georgia");
countryCodeMap.put("GD", "Grenada");
countryCodeMap.put("GB", "United Kingdom");
countryCodeMap.put("GA", "Gabon");
countryCodeMap.put("SV", "El Salvador");
countryCodeMap.put("GN", "Guinea");
countryCodeMap.put("GM", "Gambia");
countryCodeMap.put("GL", "Greenland");
countryCodeMap.put("GI", "Gibraltar");
countryCodeMap.put("GH", "Ghana");
countryCodeMap.put("OM", "Oman");
countryCodeMap.put("TN", "Tunisia");
countryCodeMap.put("JO", "Jordan");
countryCodeMap.put("HR", "Croatia");
countryCodeMap.put("HT", "Haiti");
countryCodeMap.put("HU", "Hungary");
countryCodeMap.put("HK", "Hong Kong");
countryCodeMap.put("HN", "Honduras");
countryCodeMap.put("HM", "Heard Island and McDonald Islands");
countryCodeMap.put("VE", "Venezuela");
countryCodeMap.put("PR", "Puerto Rico");
countryCodeMap.put("PS", "Palestinian Territory");
countryCodeMap.put("PW", "Palau");
countryCodeMap.put("PT", "Portugal");
countryCodeMap.put("SJ", "Svalbard and Jan Mayen");
countryCodeMap.put("PY", "Paraguay");
countryCodeMap.put("IQ", "Iraq");
countryCodeMap.put("PA", "Panama");
countryCodeMap.put("PF", "French Polynesia");
countryCodeMap.put("PG", "Papua New Guinea");
countryCodeMap.put("PE", "Peru");
countryCodeMap.put("PK", "Pakistan");
countryCodeMap.put("PH", "Philippines");
countryCodeMap.put("PN", "Pitcairn");
countryCodeMap.put("PL", "Poland");
countryCodeMap.put("PM", "Saint Pierre and Miquelon");
countryCodeMap.put("ZM", "Zambia");
countryCodeMap.put("EH", "Western Sahara");
countryCodeMap.put("EE", "Estonia");
countryCodeMap.put("EG", "Egypt");
countryCodeMap.put("ZA", "South Africa");
countryCodeMap.put("EC", "Ecuador");
countryCodeMap.put("IT", "Italy");
countryCodeMap.put("VN", "Vietnam");
countryCodeMap.put("SB", "Solomon Islands");
countryCodeMap.put("ET", "Ethiopia");
countryCodeMap.put("SO", "Somalia");
countryCodeMap.put("ZW", "Zimbabwe");
countryCodeMap.put("SA", "Saudi Arabia");
countryCodeMap.put("ES", "Spain");
countryCodeMap.put("ER", "Eritrea");
countryCodeMap.put("ME", "Montenegro");
countryCodeMap.put("MD", "Moldova");
countryCodeMap.put("MG", "Madagascar");
countryCodeMap.put("MF", "Saint Martin");
countryCodeMap.put("MA", "Morocco");
countryCodeMap.put("MC", "Monaco");
countryCodeMap.put("UZ", "Uzbekistan");
countryCodeMap.put("MM", "Myanmar");
countryCodeMap.put("ML", "Mali");
countryCodeMap.put("MO", "Macao");
countryCodeMap.put("MN", "Mongolia");
countryCodeMap.put("MH", "Marshall Islands");
countryCodeMap.put("MK", "Macedonia");
countryCodeMap.put("MU", "Mauritius");
countryCodeMap.put("MT", "Malta");
countryCodeMap.put("MW", "Malawi");
countryCodeMap.put("MV", "Maldives");
countryCodeMap.put("MQ", "Martinique");
countryCodeMap.put("MP", "Northern Mariana Islands");
countryCodeMap.put("MS", "Montserrat");
countryCodeMap.put("MR", "Mauritania");
countryCodeMap.put("IM", "Isle of Man");
countryCodeMap.put("UG", "Uganda");
countryCodeMap.put("TZ", "Tanzania");
countryCodeMap.put("MY", "Malaysia");
countryCodeMap.put("MX", "Mexico");
countryCodeMap.put("IL", "Israel");
countryCodeMap.put("FR", "France");
countryCodeMap.put("IO", "British Indian Ocean Territory");
countryCodeMap.put("SH", "Saint Helena");
countryCodeMap.put("FI", "Finland");
countryCodeMap.put("FJ", "Fiji");
countryCodeMap.put("FK", "Falkland Islands");
countryCodeMap.put("FM", "Micronesia");
countryCodeMap.put("FO", "Faroe Islands");
countryCodeMap.put("NI", "Nicaragua");
countryCodeMap.put("NL", "Netherlands");
countryCodeMap.put("NO", "Norway");
countryCodeMap.put("NA", "Namibia");
countryCodeMap.put("VU", "Vanuatu");
countryCodeMap.put("NC", "New Caledonia");
countryCodeMap.put("NE", "Niger");
countryCodeMap.put("NF", "Norfolk Island");
countryCodeMap.put("NG", "Nigeria");
countryCodeMap.put("NZ", "New Zealand");
countryCodeMap.put("NP", "Nepal");
countryCodeMap.put("NR", "Nauru");
countryCodeMap.put("NU", "Niue");
countryCodeMap.put("CK", "Cook Islands");
countryCodeMap.put("XK", "Kosovo");
countryCodeMap.put("CI", "Ivory Coast");
countryCodeMap.put("CH", "Switzerland");
countryCodeMap.put("CO", "Colombia");
countryCodeMap.put("CN", "China");
countryCodeMap.put("CM", "Cameroon");
countryCodeMap.put("CL", "Chile");
countryCodeMap.put("CC", "Cocos Islands");
countryCodeMap.put("CA", "Canada");
countryCodeMap.put("CAN", "Canada");
countryCodeMap.put("CG", "Republic of the Congo");
countryCodeMap.put("CF", "Central African Republic");
countryCodeMap.put("CD", "Democratic Republic of the Congo");
countryCodeMap.put("CZ", "Czech Republic");
countryCodeMap.put("CY", "Cyprus");
countryCodeMap.put("CX", "Christmas Island");
countryCodeMap.put("CR", "Costa Rica");
countryCodeMap.put("CW", "Curacao");
countryCodeMap.put("CV", "Cape Verde");
countryCodeMap.put("CU", "Cuba");
countryCodeMap.put("SZ", "Swaziland");
countryCodeMap.put("SY", "Syria");
countryCodeMap.put("SX", "Sint Maarten");
countryCodeMap.put("KG", "Kyrgyzstan");
countryCodeMap.put("KE", "Kenya");
countryCodeMap.put("SS", "South Sudan");
countryCodeMap.put("SR", "Suriname");
countryCodeMap.put("KI", "Kiribati");
countryCodeMap.put("KH", "Cambodia");
countryCodeMap.put("KN", "Saint Kitts and Nevis");
countryCodeMap.put("KM", "Comoros");
countryCodeMap.put("ST", "Sao Tome and Principe");
countryCodeMap.put("SK", "Slovakia");
countryCodeMap.put("KR", "South Korea");
countryCodeMap.put("SI", "Slovenia");
countryCodeMap.put("KP", "North Korea");
countryCodeMap.put("KW", "Kuwait");
countryCodeMap.put("SN", "Senegal");
countryCodeMap.put("SM", "San Marino");
countryCodeMap.put("SL", "Sierra Leone");
countryCodeMap.put("SC", "Seychelles");
countryCodeMap.put("KZ", "Kazakhstan");
countryCodeMap.put("KY", "Cayman Islands");
countryCodeMap.put("SG", "Singapore");
countryCodeMap.put("SE", "Sweden");
countryCodeMap.put("SD", "Sudan");
countryCodeMap.put("DO", "Dominican Republic");
countryCodeMap.put("DM", "Dominica");
countryCodeMap.put("DJ", "Djibouti");
countryCodeMap.put("DK", "Denmark");
countryCodeMap.put("VG", "British Virgin Islands");
countryCodeMap.put("DE", "Germany");
countryCodeMap.put("YE", "Yemen");
countryCodeMap.put("DZ", "Algeria");
countryCodeMap.put("US", "United States");
countryCodeMap.put("USA", "United States");
countryCodeMap.put("UY", "Uruguay");
countryCodeMap.put("YT", "Mayotte");
countryCodeMap.put("UM", "United States Minor Outlying Islands");
countryCodeMap.put("LB", "Lebanon");
countryCodeMap.put("LC", "Saint Lucia");
countryCodeMap.put("LA", "Laos");
countryCodeMap.put("TV", "Tuvalu");
countryCodeMap.put("TW", "Taiwan");
countryCodeMap.put("TT", "Trinidad and Tobago");
countryCodeMap.put("TR", "Turkey");
countryCodeMap.put("LK", "Sri Lanka");
countryCodeMap.put("LI", "Liechtenstein");
countryCodeMap.put("LV", "Latvia");
countryCodeMap.put("TO", "Tonga");
countryCodeMap.put("LT", "Lithuania");
countryCodeMap.put("LU", "Luxembourg");
countryCodeMap.put("LR", "Liberia");
countryCodeMap.put("LS", "Lesotho");
countryCodeMap.put("TH", "Thailand");
countryCodeMap.put("TF", "French Southern Territories");
countryCodeMap.put("TG", "Togo");
countryCodeMap.put("TD", "Chad");
countryCodeMap.put("TC", "Turks and Caicos Islands");
countryCodeMap.put("LY", "Libya");
countryCodeMap.put("VA", "Vatican");
countryCodeMap.put("VC", "Saint Vincent and the Grenadines");
countryCodeMap.put("AE", "United Arab Emirates");
countryCodeMap.put("AD", "Andorra");
countryCodeMap.put("AG", "Antigua and Barbuda");
countryCodeMap.put("AF", "Afghanistan");
countryCodeMap.put("AI", "Anguilla");
countryCodeMap.put("VI", "U.S. Virgin Islands");
countryCodeMap.put("IS", "Iceland");
countryCodeMap.put("IR", "Iran");
countryCodeMap.put("AM", "Armenia");
countryCodeMap.put("AL", "Albania");
countryCodeMap.put("AO", "Angola");
countryCodeMap.put("AQ", "Antarctica");
countryCodeMap.put("AS", "American Samoa");
countryCodeMap.put("AR", "Argentina");
countryCodeMap.put("AU", "Australia");
countryCodeMap.put("AT", "Austria");
countryCodeMap.put("AW", "Aruba");
countryCodeMap.put("IN", "India");
countryCodeMap.put("AX", "Aland Islands");
countryCodeMap.put("AZ", "Azerbaijan");
countryCodeMap.put("IE", "Ireland");
countryCodeMap.put("ID", "Indonesia");
countryCodeMap.put("UA", "Ukraine");
countryCodeMap.put("QA", "Qatar");
countryCodeMap.put("MZ", "Mozambique");
}
@Override
public void onDisable() {
Bukkit.getScheduler().cancelTasks(plugin);
}
public static void queryForGeoData(LogItem logItem){
long decimalAddress = addressToLong(logItem.getAddress());
//Test to see if the IP address is reserved and not valid for lookup.
if(logItem.getAddress().startsWith("0.") ||
logItem.getAddress().startsWith("10.") ||
logItem.getAddress().startsWith("127.") ||
logItem.getAddress().startsWith("169.254.") ||
logItem.getAddress().startsWith("192.0.0.") ||
logItem.getAddress().startsWith("192.0.2.") ||
logItem.getAddress().startsWith("192.88.99.") ||
logItem.getAddress().startsWith("192.168.") ||
logItem.getAddress().startsWith("198.51.100.") ||
logItem.getAddress().startsWith("203.0.113.") ||
(decimalAddress >= addressToLong("100.64.0.0") && decimalAddress <= addressToLong("100.127.255.255")) ||
(decimalAddress >= addressToLong("172.16.0.0") && decimalAddress <= addressToLong("172.31.255.255")) ||
(decimalAddress >= addressToLong("198.18.0.0") && decimalAddress <= addressToLong("198.19.255.255")) ||
(decimalAddress >= addressToLong("224.0.0.0") && decimalAddress <= addressToLong("239.255.255.255")) ||
(decimalAddress >= addressToLong("240.0.0.0") && decimalAddress <= addressToLong("255.255.255.255"))
){
Msg.msgC(logItem.getAddress() + " is a private address and can't be geographically located.");
//Tell iPAV to display the user connection info (even though a geo location wasn't found to add to it)
iPAddressViewer.forwardGeoData(logItem);
return;
}
//Check to see if the address was already looked up recently (after the last /reload or server startup)
GeoData geoData = geoDataCache.get(logItem.getAddress());
//If it hasn't been successfully queried yet, look it up. Else, use the previous location data
if(geoData==null){
geoData = new GeoData(logItem, logItem.getAddress());
//Add the newly acquired location data to the cache if it was successful
if(geoData.geoDataFound()){
geoDataCache.put(logItem.getAddress(), geoData);
}
}else{
//Give the iPAV log the location data from the cache
logItem.applyGeoData(geoData.city, geoData.state, geoData.country);
//Tell iPAV to display the user connection info
iPAddressViewer.forwardGeoData(logItem);
}
}
//Convert a standard IPv4 address to a long integer to simplify address-range testing
static long addressToLong(String address){
int[] array = new int[4];
array[0] = Integer.valueOf(address.split("\\.")[0]).intValue();
array[1] = Integer.valueOf(address.split("\\.")[1]).intValue();
array[2] = Integer.valueOf(address.split("\\.")[2]).intValue();
array[3] = Integer.valueOf(address.split("\\.")[3]).intValue();
return array[0]*256*256*256 + array[1]*256*256 + array[2]*256 + array[3];
}
}