Merge pull request #198 from Arkshine/fix/geoip_country-return-on-fail-lookup

Fix various compatibility issue with geoip module
This commit is contained in:
Vincent Herbet 2015-02-07 17:51:49 +01:00
commit 3e6d806ce2
4 changed files with 95 additions and 68 deletions

View File

@ -44,7 +44,7 @@ void OnGeoipCommand()
{ {
if (!HandleDB.filename) if (!HandleDB.filename)
{ {
printf("\n Database is not loaded.\n"); MF_PrintSrvConsole("\n Database is not loaded.\n");
return; return;
} }
@ -62,20 +62,20 @@ void OnGeoipCommand()
strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S UTC", gmtime((const time_t *)&HandleDB.metadata.build_epoch)); strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S UTC", gmtime((const time_t *)&HandleDB.metadata.build_epoch));
fprintf(stdout, meta_dump, fprintf(stdout, meta_dump,
HandleDB.metadata.node_count, HandleDB.metadata.node_count,
HandleDB.metadata.record_size, HandleDB.metadata.record_size,
HandleDB.metadata.ip_version, HandleDB.metadata.ip_version,
HandleDB.metadata.binary_format_major_version, HandleDB.metadata.binary_format_major_version,
HandleDB.metadata.binary_format_minor_version, HandleDB.metadata.binary_format_minor_version,
HandleDB.metadata.build_epoch, HandleDB.metadata.build_epoch,
date, date,
HandleDB.metadata.database_type); HandleDB.metadata.database_type);
for (size_t i = 0; i < HandleDB.metadata.languages.count; ++i) for (size_t i = 0; i < HandleDB.metadata.languages.count; ++i)
{ {
fprintf(stdout, "%s", HandleDB.metadata.languages.names[i]); fprintf(stdout, "%s", HandleDB.metadata.languages.names[i]);
if (i <HandleDB.metadata.languages.count - 1) if (i < HandleDB.metadata.languages.count - 1)
{ {
fprintf(stdout, " "); fprintf(stdout, " ");
} }
@ -84,11 +84,11 @@ void OnGeoipCommand()
fprintf(stdout, "\n"); fprintf(stdout, "\n");
fprintf(stdout, " Description:\n"); fprintf(stdout, " Description:\n");
for (size_t i = 0; i < HandleDB.metadata.description.count; ++i) for (size_t i = 0; i < HandleDB.metadata.description.count; ++i)
{ {
fprintf(stdout, " %s: %s\n", fprintf(stdout, " %s: %s\n",
HandleDB.metadata.description.descriptions[i]->language, HandleDB.metadata.description.descriptions[i]->language,
HandleDB.metadata.description.descriptions[i]->description); HandleDB.metadata.description.descriptions[i]->description);
} }
fprintf(stdout, "\n"); fprintf(stdout, "\n");
} }
@ -96,7 +96,7 @@ void OnGeoipCommand()
{ {
if (!HandleDB.filename) if (!HandleDB.filename)
{ {
printf("\n Database is not loaded.\n\n"); MF_PrintSrvConsole("\n Database is not loaded.\n\n");
return; return;
} }
@ -104,10 +104,10 @@ void OnGeoipCommand()
if (num_args < 3) if (num_args < 3)
{ {
printf("\n An IP address must be provided.\n\n"); MF_PrintSrvConsole("\n An IP address must be provided.\n\n");
return; return;
} }
char *ip = stripPort((char *)CMD_ARGV(2)); char *ip = stripPort((char *)CMD_ARGV(2));
int gai_error = 0; int gai_error = 0;
@ -117,16 +117,16 @@ void OnGeoipCommand()
if (gai_error != 0 || mmdb_error != MMDB_SUCCESS || !result.found_entry) if (gai_error != 0 || mmdb_error != MMDB_SUCCESS || !result.found_entry)
{ {
printf("\n Either look up failed or no found result.\n\n"); MF_PrintSrvConsole("\n Either look up failed or no found result.\n\n");
return; return;
} }
MMDB_entry_data_list_s *entry_data_list = NULL; MMDB_entry_data_list_s *entry_data_list = NULL;
int status = -1; int status = -1;
if ((status = MMDB_get_entry_data_list(&result.entry, &entry_data_list)) != MMDB_SUCCESS || entry_data_list == NULL) if ((status = MMDB_get_entry_data_list(&result.entry, &entry_data_list)) != MMDB_SUCCESS || entry_data_list == NULL)
{ {
printf("\n Could not retrieve data list - %s.\n\n", MMDB_strerror(status)); MF_PrintSrvConsole("\n Could not retrieve data list - %s.\n\n", MMDB_strerror(status));
return; return;
} }
@ -158,13 +158,13 @@ void OnGeoipCommand()
} }
else else
{ {
printf("\n"); MF_PrintSrvConsole("\n");
printf(" Usage: geoip <command> [argument]\n"); MF_PrintSrvConsole(" Usage: geoip <command> [argument]\n");
printf(" Commands:\n"); MF_PrintSrvConsole(" Commands:\n");
printf(" version - display geoip database metadata\n"); MF_PrintSrvConsole(" version - display geoip database metadata\n");
printf(" dump <ip> [output file] - dump all data from an IP address formatted in a JSON-ish fashion.\n"); MF_PrintSrvConsole(" dump <ip> [output file] - dump all data from an IP address formatted in a JSON-ish fashion.\n");
printf(" An output file is mod-based and if not provided, it will print in the console.\n"); MF_PrintSrvConsole(" An output file is mod-based and if not provided, it will print in the console.\n");
printf("\n"); MF_PrintSrvConsole("\n");
} }
} }
@ -177,7 +177,7 @@ bool loadDatabase()
const char *databases[] = const char *databases[] =
{ {
"City", "City",
"Country" // Is the default shipped database with AMXX. "Country" // Is the default shipped database with AMXX.
}; };
@ -192,8 +192,8 @@ bool loadDatabase()
// MF_BuildPathname not used because backslash // MF_BuildPathname not used because backslash
// makes CreateFileMapping failing under windows. // makes CreateFileMapping failing under windows.
UTIL_Format(file, sizeof(file)-1, "%s/%s/GeoLite2-%s.mmdb", modName, dataDir, databases[i]); UTIL_Format(file, sizeof(file) - 1, "%s/%s/GeoLite2-%s.mmdb", modName, dataDir, databases[i]);
status = MMDB_open(file, MMDB_MODE_MMAP, &HandleDB); status = MMDB_open(file, MMDB_MODE_MMAP, &HandleDB);
if (status == MMDB_SUCCESS) if (status == MMDB_SUCCESS)
@ -218,9 +218,9 @@ bool loadDatabase()
} }
MF_Log("Database info: %s %i.%i", MF_Log("Database info: %s %i.%i",
HandleDB.metadata.description.descriptions[0]->description, HandleDB.metadata.description.descriptions[0]->description,
HandleDB.metadata.binary_format_major_version, HandleDB.metadata.binary_format_major_version,
HandleDB.metadata.binary_format_minor_version); HandleDB.metadata.binary_format_minor_version);
// Retrieve supported languages. // Retrieve supported languages.
for (size_t i = 0; i < HandleDB.metadata.languages.count; i++) for (size_t i = 0; i < HandleDB.metadata.languages.count; i++)

View File

@ -100,12 +100,30 @@ static cell AMX_NATIVE_CALL amx_geoip_code3_ex(AMX *amx, cell *params)
return 1; return 1;
} }
// native geoip_country(const ip[], result[], len, id = -1); // native geoip_country(const ip[], result[], len = 45);
// Deprecated.
static cell AMX_NATIVE_CALL amx_geoip_country(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_geoip_country(AMX *amx, cell *params)
{ {
int length; int length;
char *ip = stripPort(MF_GetAmxString(amx, params[1], 0, &length)); char *ip = stripPort(MF_GetAmxString(amx, params[1], 0, &length));
const char *path[] = { "country", "names", "en", NULL };
const char *country = lookupString(ip, path, &length);
if (!country)
{
return MF_SetAmxString(amx, params[2], "error", params[3]);
}
return MF_SetAmxStringUTF8Char(amx, params[2], country, length, params[3] + 1);
}
// native geoip_country_ex(const ip[], result[], len, id = -1);
static cell AMX_NATIVE_CALL amx_geoip_country_ex(AMX *amx, cell *params)
{
int length;
char *ip = stripPort(MF_GetAmxString(amx, params[1], 0, &length));
int id = -1; int id = -1;
if (*params / sizeof(cell) >= 4) if (*params / sizeof(cell) >= 4)
{ {
@ -115,12 +133,7 @@ static cell AMX_NATIVE_CALL amx_geoip_country(AMX *amx, cell *params)
const char *path[] = { "country", "names", getLang(id), NULL }; const char *path[] = { "country", "names", getLang(id), NULL };
const char *country = lookupString(ip, path, &length); const char *country = lookupString(ip, path, &length);
if (!country) return MF_SetAmxStringUTF8Char(amx, params[2], country ? country : "", length, params[3] + 1);
{
return 0;
}
return MF_SetAmxStringUTF8Char(amx, params[2], country, length, params[3] + 1);
} }
// native geoip_city(const ip[], result[], len, id = -1); // native geoip_city(const ip[], result[], len, id = -1);
@ -152,7 +165,7 @@ static cell AMX_NATIVE_CALL amx_geoip_region_code(AMX *amx, cell *params)
finalLength = length + 1; // + 1 for dash. finalLength = length + 1; // + 1 for dash.
UTIL_Format(code, finalLength + 1, "%s-", countryCode); // + EOS. UTIL_Format(code, finalLength + 1, "%s-", countryCode); // + EOS.
const char *pathRegion[] = { "subdivisions", "0", "iso_code", NULL }; // First result. const char *pathRegion[] = { "subdivisions", "0", "iso_code", NULL }; // First result.
const char *regionCode = lookupString(ip, pathRegion, &length); const char *regionCode = lookupString(ip, pathRegion, &length);
if (regionCode) if (regionCode)
@ -259,22 +272,23 @@ static cell AMX_NATIVE_CALL amx_geoip_continent_name(AMX *amx, cell *params)
AMX_NATIVE_INFO GeoipNatives[] = AMX_NATIVE_INFO GeoipNatives[] =
{ {
{ "geoip_code2", amx_geoip_code2 }, { "geoip_code2" , amx_geoip_code2 }, // Deprecated
{ "geoip_code3", amx_geoip_code3 }, { "geoip_code3" , amx_geoip_code3 }, // Deprecated
{ "geoip_code2_ex", amx_geoip_code2_ex }, { "geoip_code2_ex" , amx_geoip_code2_ex },
{ "geoip_code3_ex", amx_geoip_code3_ex }, { "geoip_code3_ex" , amx_geoip_code3_ex },
{ "geoip_country", amx_geoip_country }, { "geoip_country" , amx_geoip_country }, // Deprecated
{ "geoip_city" , amx_geoip_city }, { "geoip_country_ex" , amx_geoip_country_ex },
{ "geoip_city" , amx_geoip_city },
{ "geoip_region_code", amx_geoip_region_code }, { "geoip_region_code" , amx_geoip_region_code },
{ "geoip_region_name", amx_geoip_region_name }, { "geoip_region_name" , amx_geoip_region_name },
{ "geoip_timezone" , amx_geoip_timezone }, { "geoip_timezone" , amx_geoip_timezone },
{ "geoip_latitude" , amx_geoip_latitude }, { "geoip_latitude" , amx_geoip_latitude },
{ "geoip_longitude", amx_geoip_longitude }, { "geoip_longitude" , amx_geoip_longitude },
{ "geoip_distance" , amx_geoip_distance }, { "geoip_distance" , amx_geoip_distance },
{ "geoip_continent_code", amx_geoip_continent_code }, { "geoip_continent_code", amx_geoip_continent_code },
{ "geoip_continent_name", amx_geoip_continent_name }, { "geoip_continent_name", amx_geoip_continent_name },

View File

@ -136,17 +136,17 @@ bool lookupByIp(const char *ip, const char **path, MMDB_entry_data_s *result)
while (path[i] && strcmp(path[i++], "names")); while (path[i] && strcmp(path[i++], "names"));
// No localized entry or we use already default language. // No localized entry or we use already default language.
if (!path[i] || !strcmp(path[i], "en")) if (!path[i] || !strcmp(path[i], "en"))
{ {
return false; return false;
} }
// Overwrite user's language. // Overwrite user's language.
path[i] = "en"; path[i] = "en";
// Try again. // Try again.
gai_error = mmdb_error = 0; gai_error = mmdb_error = 0;
MMDB_aget_value(&lookup.entry, &entry_data, path); MMDB_aget_value(&lookup.entry, &entry_data, path);
if (!entry_data.has_data) if (!entry_data.has_data)
{ {
@ -170,7 +170,7 @@ const char *lookupString(const char *ip, const char **path, int *length)
} }
// Let's avoid a crash in case we go over the buffer size. // Let's avoid a crash in case we go over the buffer size.
size_t maxLength = ke::Min((size_t)result.data_size, sizeof(buffer)-1); size_t maxLength = ke::Min((size_t)result.data_size, sizeof(buffer) - 1);
// Strings from database are not null terminated. // Strings from database are not null terminated.
memcpy(buffer, result.utf8_string, maxLength); memcpy(buffer, result.utf8_string, maxLength);
@ -221,10 +221,10 @@ int getContinentId(const char *code)
case 'N': index = CONTINENT_ANTARCTICA; break; case 'N': index = CONTINENT_ANTARCTICA; break;
case 'S': index = CONTINENT_ASIA; break; case 'S': index = CONTINENT_ASIA; break;
} }
break; break;
} }
case 'E': index = CONTINENT_EUROPE; break; case 'E': index = CONTINENT_EUROPE; break;
case 'O': index = CONTINENT_OCEANIA; break; case 'O': index = CONTINENT_OCEANIA; break;
case 'N': index = CONTINENT_NORTH_AMERICA; break; case 'N': index = CONTINENT_NORTH_AMERICA; break;
@ -241,10 +241,10 @@ const char *getLang(int playerIndex)
static cvar_t *amxmodx_cl_langs = NULL; static cvar_t *amxmodx_cl_langs = NULL;
if (!amxmodx_language) if (!amxmodx_language)
amxmodx_language = CVAR_GET_POINTER("amx_language"); amxmodx_language = CVAR_GET_POINTER("amx_language");
if (!amxmodx_cl_langs) if (!amxmodx_cl_langs)
amxmodx_cl_langs = CVAR_GET_POINTER("amx_client_languages"); amxmodx_cl_langs = CVAR_GET_POINTER("amx_client_languages");
if (playerIndex >= 0 && amxmodx_cl_langs && amxmodx_language) if (playerIndex >= 0 && amxmodx_cl_langs && amxmodx_language)
{ {

View File

@ -52,7 +52,8 @@ native bool:geoip_code2_ex(const ip[], result[3]);
native bool:geoip_code3_ex(const ip[], result[4]); native bool:geoip_code3_ex(const ip[], result[4]);
/** /**
* Lookup the two character country code for a given IP address. * Lookup the two character country code for a given IP address. Sets the buffer to "error" on
* an unsuccessful lookup.
* *
* @deprecated This native will overflow the buffer by one cell on an unknown ip lookup! * @deprecated This native will overflow the buffer by one cell on an unknown ip lookup!
* Use geoip_code2_ex instead. * Use geoip_code2_ex instead.
@ -60,13 +61,14 @@ native bool:geoip_code3_ex(const ip[], result[4]);
* @param ip The IP address to lookup. * @param ip The IP address to lookup.
* @param result The result buffer. * @param result The result buffer.
* *
* @return 1 on a successful lookup, 0 otherwise. * @return The result length.
*/ */
#pragma deprecated Use geoip_code2_ex() instead. #pragma deprecated Use geoip_code2_ex() instead.
native geoip_code2(const ip[], ccode[3]); native geoip_code2(const ip[], ccode[3]);
/** /**
* Lookup the three character country code for a given IP address. * Lookup the three character country code for a given IP address. Sets the buffer to "error" on
* an unsuccessful lookup.
* *
* @deprecated This native will overflow the buffer by one cell on an unknown ip lookup! * @deprecated This native will overflow the buffer by one cell on an unknown ip lookup!
* Use geoip_code3_ex instead. * Use geoip_code3_ex instead.
@ -74,9 +76,9 @@ native geoip_code2(const ip[], ccode[3]);
* @param ip The IP address to lookup. * @param ip The IP address to lookup.
* @param result The result buffer. * @param result The result buffer.
* *
* @return 1 on a successful lookup, 0 otherwise. * @return The result length.
*/ */
#pragma deprecated Use geoip_code3() instead. #pragma deprecated Use geoip_code3_ex() instead.
native geoip_code3(const ip[], result[4]); native geoip_code3(const ip[], result[4]);
/** /**
@ -86,6 +88,18 @@ native geoip_code3(const ip[], result[4]);
* @param ip The IP address to lookup. * @param ip The IP address to lookup.
* @param result The result of the geoip lookup. * @param result The result of the geoip lookup.
* @param len The maximum length of the result buffer. * @param len The maximum length of the result buffer.
*
* @return The result length.
*/
#pragma deprecated Use geoip_country_ex() instead.
native geoip_country(const ip[], result[], len = 45);
/**
* Lookup the full country name for the given IP address.
*
* @param ip The IP address to lookup.
* @param result The result of the geoip lookup.
* @param len The maximum length of the result buffer.
* @param id An optional player's index in order to return the result * @param id An optional player's index in order to return the result
* in the player's language, if supported. * in the player's language, if supported.
* -1: the default language, which is english. * -1: the default language, which is english.
@ -94,8 +108,7 @@ native geoip_code3(const ip[], result[4]);
* *
* @return The result length on successful lookup, 0 otherwise. * @return The result length on successful lookup, 0 otherwise.
*/ */
native geoip_country(const ip[], result[], len = 45, id = -1); native geoip_country_ex(const ip[], result[], len, id = -1);
/** /**
* Look up the full city name for the given IP address. * Look up the full city name for the given IP address.