feat(Common/IPLocation): replace ip2nation by ip2location (#5653)
This commit is contained in:
@@ -1,28 +0,0 @@
|
|||||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
|
||||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
|
||||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
|
||||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
|
||||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
|
||||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
|
||||||
DROP TABLE IF EXISTS `ip2nation`;
|
|
||||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
|
||||||
/*!40101 SET character_set_client = UTF8MB4 */;
|
|
||||||
CREATE TABLE `ip2nation`
|
|
||||||
(
|
|
||||||
`ip` INT unsigned NOT NULL DEFAULT 0,
|
|
||||||
`country` char(2) NOT NULL DEFAULT '',
|
|
||||||
KEY `ip` (`ip`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4;
|
|
||||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
|
||||||
|
|
||||||
LOCK TABLES `ip2nation` WRITE;
|
|
||||||
/*!40000 ALTER TABLE `ip2nation` DISABLE KEYS */;
|
|
||||||
/*!40000 ALTER TABLE `ip2nation` ENABLE KEYS */;
|
|
||||||
UNLOCK TABLES;
|
|
||||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
|
||||||
|
|
||||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
|
||||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
|
||||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
|
||||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
|
||||||
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
|
||||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
|
||||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
|
||||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
|
||||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
|
||||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
|
||||||
DROP TABLE IF EXISTS `ip2nationCountries`;
|
|
||||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
|
||||||
/*!40101 SET character_set_client = UTF8MB4 */;
|
|
||||||
CREATE TABLE `ip2nationCountries`
|
|
||||||
(
|
|
||||||
`code` varchar(4) NOT NULL DEFAULT '',
|
|
||||||
`iso_code_2` varchar(2) NOT NULL DEFAULT '',
|
|
||||||
`iso_code_3` varchar(3) DEFAULT '',
|
|
||||||
`iso_country` varchar(255) NOT NULL DEFAULT '',
|
|
||||||
`country` varchar(255) NOT NULL DEFAULT '',
|
|
||||||
`lat` float NOT NULL DEFAULT 0,
|
|
||||||
`lon` float NOT NULL DEFAULT 0,
|
|
||||||
PRIMARY KEY (`code`),
|
|
||||||
KEY `code` (`code`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4;
|
|
||||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
|
||||||
|
|
||||||
LOCK TABLES `ip2nationCountries` WRITE;
|
|
||||||
/*!40000 ALTER TABLE `ip2nationCountries` DISABLE KEYS */;
|
|
||||||
/*!40000 ALTER TABLE `ip2nationCountries` ENABLE KEYS */;
|
|
||||||
UNLOCK TABLES;
|
|
||||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
|
||||||
|
|
||||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
|
||||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
|
||||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
|
||||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
INSERT INTO `version_db_auth` (`sql_rev`) VALUES ('1620146306002634000');
|
||||||
|
|
||||||
|
--
|
||||||
|
DROP TABLE IF EXISTS `ip2nation`;
|
||||||
|
DROP TABLE IF EXISTS `ip2nationCountries`;
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||||
|
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "IPLocation.h"
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Config.h"
|
||||||
|
#include "Errors.h"
|
||||||
|
#include "IpAddress.h"
|
||||||
|
#include "Log.h"
|
||||||
|
#include "StringConvert.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
IpLocationStore::IpLocationStore()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
IpLocationStore::~IpLocationStore()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void IpLocationStore::Load()
|
||||||
|
{
|
||||||
|
_ipLocationStore.clear();
|
||||||
|
LOG_INFO("server.loading", "Loading IP Location Database...");
|
||||||
|
|
||||||
|
std::string databaseFilePath = sConfigMgr->GetOption<std::string>("IPLocationFile", "");
|
||||||
|
if (databaseFilePath.empty())
|
||||||
|
{
|
||||||
|
LOG_INFO("server.loading", " ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if file exists
|
||||||
|
std::ifstream databaseFile(databaseFilePath);
|
||||||
|
if (!databaseFile)
|
||||||
|
{
|
||||||
|
LOG_ERROR("server.loading", "IPLocation: No ip database file exists (%s).", databaseFilePath.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!databaseFile.is_open())
|
||||||
|
{
|
||||||
|
LOG_ERROR("server.loading", "IPLocation: Ip database file (%s) can not be opened.", databaseFilePath.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ipFrom;
|
||||||
|
std::string ipTo;
|
||||||
|
std::string countryCode;
|
||||||
|
std::string countryName;
|
||||||
|
|
||||||
|
while (databaseFile.good())
|
||||||
|
{
|
||||||
|
// Read lines
|
||||||
|
if (!std::getline(databaseFile, ipFrom, ','))
|
||||||
|
break;
|
||||||
|
if (!std::getline(databaseFile, ipTo, ','))
|
||||||
|
break;
|
||||||
|
if (!std::getline(databaseFile, countryCode, ','))
|
||||||
|
break;
|
||||||
|
if (!std::getline(databaseFile, countryName, '\n'))
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Remove new lines and return
|
||||||
|
countryName.erase(std::remove(countryName.begin(), countryName.end(), '\r'), countryName.end());
|
||||||
|
countryName.erase(std::remove(countryName.begin(), countryName.end(), '\n'), countryName.end());
|
||||||
|
|
||||||
|
// Remove quotation marks
|
||||||
|
ipFrom.erase(std::remove(ipFrom.begin(), ipFrom.end(), '"'), ipFrom.end());
|
||||||
|
ipTo.erase(std::remove(ipTo.begin(), ipTo.end(), '"'), ipTo.end());
|
||||||
|
countryCode.erase(std::remove(countryCode.begin(), countryCode.end(), '"'), countryCode.end());
|
||||||
|
countryName.erase(std::remove(countryName.begin(), countryName.end(), '"'), countryName.end());
|
||||||
|
|
||||||
|
// Convert country code to lowercase
|
||||||
|
std::transform(countryCode.begin(), countryCode.end(), countryCode.begin(), ::tolower);
|
||||||
|
|
||||||
|
auto IpFrom = Acore::StringTo<uint32>(ipFrom);
|
||||||
|
auto IpTo = Acore::StringTo<uint32>(ipTo);
|
||||||
|
|
||||||
|
if (!IpFrom || !IpTo)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_ipLocationStore.emplace_back(*IpFrom, *IpTo, std::move(countryCode), std::move(countryName));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(_ipLocationStore.begin(), _ipLocationStore.end(), [](IpLocationRecord const& a, IpLocationRecord const& b) { return a.IpFrom < b.IpFrom; });
|
||||||
|
ASSERT(std::is_sorted(_ipLocationStore.begin(), _ipLocationStore.end(), [](IpLocationRecord const& a, IpLocationRecord const& b) { return a.IpFrom < b.IpTo; }),
|
||||||
|
"Overlapping IP ranges detected in database file");
|
||||||
|
|
||||||
|
databaseFile.close();
|
||||||
|
|
||||||
|
LOG_INFO("server.loading", ">> Loaded %u ip location entries.", static_cast<uint32>(_ipLocationStore.size()));
|
||||||
|
LOG_INFO("server.loading", " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
IpLocationRecord const* IpLocationStore::GetLocationRecord(std::string const& ipAddress) const
|
||||||
|
{
|
||||||
|
uint32 ip = Acore::Net::address_to_uint(Acore::Net::make_address_v4(ipAddress));
|
||||||
|
auto itr = std::upper_bound(_ipLocationStore.begin(), _ipLocationStore.end(), ip, [](uint32 ip, IpLocationRecord const& loc) { return ip < loc.IpTo; });
|
||||||
|
if (itr == _ipLocationStore.end())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ip < itr->IpFrom)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &(*itr);
|
||||||
|
}
|
||||||
|
|
||||||
|
IpLocationStore* IpLocationStore::instance()
|
||||||
|
{
|
||||||
|
static IpLocationStore instance;
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||||
|
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Define.h"
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct IpLocationRecord
|
||||||
|
{
|
||||||
|
IpLocationRecord() :
|
||||||
|
IpFrom(0), IpTo(0) { }
|
||||||
|
IpLocationRecord(uint32 ipFrom, uint32 ipTo, std::string countryCode, std::string countryName) :
|
||||||
|
IpFrom(ipFrom), IpTo(ipTo), CountryCode(std::move(countryCode)), CountryName(std::move(countryName)) { }
|
||||||
|
|
||||||
|
uint32 IpFrom;
|
||||||
|
uint32 IpTo;
|
||||||
|
std::string CountryCode;
|
||||||
|
std::string CountryName;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AC_COMMON_API IpLocationStore
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IpLocationStore();
|
||||||
|
~IpLocationStore();
|
||||||
|
static IpLocationStore* instance();
|
||||||
|
|
||||||
|
void Load();
|
||||||
|
IpLocationRecord const* GetLocationRecord(std::string const& ipAddress) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<IpLocationRecord> _ipLocationStore;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define sIPLocation IpLocationStore::instance()
|
||||||
@@ -12,29 +12,29 @@
|
|||||||
* authentication server
|
* authentication server
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "AppenderDB.h"
|
||||||
#include "Banner.h"
|
#include "Banner.h"
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "AppenderDB.h"
|
|
||||||
#include "DatabaseEnv.h"
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Log.h"
|
#include "DatabaseEnv.h"
|
||||||
#include "GitRevision.h"
|
|
||||||
#include "Util.h"
|
|
||||||
#include "SignalHandler.h"
|
|
||||||
#include "RealmList.h"
|
|
||||||
#include "RealmAcceptor.h"
|
|
||||||
#include "DatabaseLoader.h"
|
#include "DatabaseLoader.h"
|
||||||
|
#include "GitRevision.h"
|
||||||
|
#include "IPLocation.h"
|
||||||
|
#include "Log.h"
|
||||||
|
#include "RealmAcceptor.h"
|
||||||
|
#include "RealmList.h"
|
||||||
#include "SecretMgr.h"
|
#include "SecretMgr.h"
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
|
#include "SignalHandler.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "ProcessPriority.h"
|
#include "ProcessPriority.h"
|
||||||
#include <ace/Dev_Poll_Reactor.h>
|
|
||||||
#include <ace/TP_Reactor.h>
|
|
||||||
#include <ace/ACE.h>
|
#include <ace/ACE.h>
|
||||||
|
#include <ace/Dev_Poll_Reactor.h>
|
||||||
#include <ace/Sig_Handler.h>
|
#include <ace/Sig_Handler.h>
|
||||||
|
#include <ace/TP_Reactor.h>
|
||||||
#include <boost/version.hpp>
|
#include <boost/version.hpp>
|
||||||
#include <openssl/opensslv.h>
|
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
|
#include <openssl/opensslv.h>
|
||||||
|
|
||||||
#ifndef _ACORE_REALM_CONFIG
|
#ifndef _ACORE_REALM_CONFIG
|
||||||
#define _ACORE_REALM_CONFIG "authserver.conf"
|
#define _ACORE_REALM_CONFIG "authserver.conf"
|
||||||
@@ -128,6 +128,9 @@ extern int main(int argc, char** argv)
|
|||||||
|
|
||||||
sSecretMgr->Initialize();
|
sSecretMgr->Initialize();
|
||||||
|
|
||||||
|
// Load IP Location Database
|
||||||
|
sIPLocation->Load();
|
||||||
|
|
||||||
// Get the list of realms for the server
|
// Get the list of realms for the server
|
||||||
sRealmList->Initialize(sConfigMgr->GetOption<int32>("RealmsStateUpdateDelay", 20));
|
sRealmList->Initialize(sConfigMgr->GetOption<int32>("RealmsStateUpdateDelay", 20));
|
||||||
if (sRealmList->GetRealms().empty())
|
if (sRealmList->GetRealms().empty())
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "CryptoHash.h"
|
#include "CryptoHash.h"
|
||||||
#include "CryptoRandom.h"
|
#include "CryptoRandom.h"
|
||||||
#include "DatabaseEnv.h"
|
#include "DatabaseEnv.h"
|
||||||
|
#include "IPLocation.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "RealmList.h"
|
#include "RealmList.h"
|
||||||
#include "SecretMgr.h"
|
#include "SecretMgr.h"
|
||||||
@@ -419,34 +420,23 @@ bool AuthSocket::_HandleLogonChallenge()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_DEBUG("network", "[AuthChallenge] Account '%s' is not locked to ip", _accountInfo.Login.c_str());
|
if (IpLocationRecord const* location = sIPLocation->GetLocationRecord(ipAddress))
|
||||||
|
_ipCountry = location->CountryCode;
|
||||||
|
|
||||||
|
LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is not locked to ip", _accountInfo.Login.c_str());
|
||||||
if (_accountInfo.LockCountry.empty() || _accountInfo.LockCountry == "00")
|
if (_accountInfo.LockCountry.empty() || _accountInfo.LockCountry == "00")
|
||||||
|
LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is not locked to country", _accountInfo.Login.c_str());
|
||||||
|
else if (!_ipCountry.empty())
|
||||||
{
|
{
|
||||||
LOG_DEBUG("network", "[AuthChallenge] Account '%s' is not locked to country", _accountInfo.Login.c_str());
|
LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is locked to country: '%s' Player country is '%s'", _accountInfo.Login.c_str(), _accountInfo.LockCountry.c_str(), _ipCountry.c_str());
|
||||||
}
|
if (_ipCountry != _accountInfo.LockCountry)
|
||||||
else if (!_accountInfo.LockCountry.empty())
|
|
||||||
{
|
{
|
||||||
uint32 ip = inet_addr(ipAddress.c_str());
|
|
||||||
EndianConvertReverse(ip);
|
|
||||||
|
|
||||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY);
|
|
||||||
stmt->setUInt32(0, ip);
|
|
||||||
|
|
||||||
if (PreparedQueryResult sessionCountryQuery = LoginDatabase.Query(stmt))
|
|
||||||
{
|
|
||||||
std::string loginCountry = (*sessionCountryQuery)[0].GetString();
|
|
||||||
LOG_DEBUG("network", "[AuthChallenge] Account '%s' is locked to country: '%s' Player country is '%s'", _accountInfo.Login.c_str(), _accountInfo.LockCountry.c_str(), loginCountry.c_str());
|
|
||||||
if (loginCountry != _accountInfo.LockCountry)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("network", "[AuthChallenge] Account country differs.");
|
|
||||||
pkt << uint8(WOW_FAIL_UNLOCKABLE_LOCK);
|
pkt << uint8(WOW_FAIL_UNLOCKABLE_LOCK);
|
||||||
SendAuthPacket();
|
SendAuthPacket();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If the account is banned, reject the logon attempt
|
// If the account is banned, reject the logon attempt
|
||||||
if (_accountInfo.IsBanned)
|
if (_accountInfo.IsBanned)
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ private:
|
|||||||
// between enUS and enGB, which is important for the patch system
|
// between enUS and enGB, which is important for the patch system
|
||||||
std::string _localizationName;
|
std::string _localizationName;
|
||||||
std::string _os;
|
std::string _os;
|
||||||
|
std::string _ipCountry;
|
||||||
uint16 _build;
|
uint16 _build;
|
||||||
uint8 _expversion;
|
uint8 _expversion;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -134,6 +134,15 @@ WrongPass.BanType = 0
|
|||||||
|
|
||||||
WrongPass.Logging = 0
|
WrongPass.Logging = 0
|
||||||
|
|
||||||
|
#
|
||||||
|
# IPLocationFile
|
||||||
|
# Description: The path to your IP2Location database CSV file.
|
||||||
|
# Example: "C:/acore/IP2LOCATION-LITE-DB1.CSV"
|
||||||
|
# "/home/acore/IP2LOCATION-LITE-DB1.CSV"
|
||||||
|
# Default: "" - (Disabled)
|
||||||
|
|
||||||
|
IPLocationFile = ""
|
||||||
|
|
||||||
#
|
#
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ void LoginDatabaseConnection::DoPrepareStatements()
|
|||||||
PrepareStatement(LOGIN_DEL_ACCOUNT_BANNED, "DELETE FROM account_banned WHERE id = ?", CONNECTION_ASYNC);
|
PrepareStatement(LOGIN_DEL_ACCOUNT_BANNED, "DELETE FROM account_banned WHERE id = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(LOGIN_UPD_LOGON, "UPDATE account SET salt = ?, verifier = ? WHERE id = ?", CONNECTION_ASYNC);
|
PrepareStatement(LOGIN_UPD_LOGON, "UPDATE account SET salt = ?, verifier = ? WHERE id = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(LOGIN_UPD_LOGONPROOF, "UPDATE account SET session_key = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?", CONNECTION_SYNCH);
|
PrepareStatement(LOGIN_UPD_LOGONPROOF, "UPDATE account SET session_key = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?", CONNECTION_SYNCH);
|
||||||
PrepareStatement(LOGIN_SEL_LOGON_COUNTRY, "SELECT country FROM ip2nation WHERE ip < ? ORDER BY ip DESC LIMIT 0,1", CONNECTION_SYNCH);
|
|
||||||
PrepareStatement(LOGIN_UPD_FAILEDLOGINS, "UPDATE account SET failed_logins = failed_logins + 1 WHERE username = ?", CONNECTION_ASYNC);
|
PrepareStatement(LOGIN_UPD_FAILEDLOGINS, "UPDATE account SET failed_logins = failed_logins + 1 WHERE username = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(LOGIN_SEL_FAILEDLOGINS, "SELECT id, failed_logins FROM account WHERE username = ?", CONNECTION_SYNCH);
|
PrepareStatement(LOGIN_SEL_FAILEDLOGINS, "SELECT id, failed_logins FROM account WHERE username = ?", CONNECTION_SYNCH);
|
||||||
PrepareStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH);
|
PrepareStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH);
|
||||||
@@ -56,7 +55,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
|
|||||||
PrepareStatement(LOGIN_INS_REALM_CHARACTERS_INIT, "INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist, account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL", CONNECTION_ASYNC);
|
PrepareStatement(LOGIN_INS_REALM_CHARACTERS_INIT, "INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist, account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL", CONNECTION_ASYNC);
|
||||||
PrepareStatement(LOGIN_UPD_EXPANSION, "UPDATE account SET expansion = ? WHERE id = ?", CONNECTION_ASYNC);
|
PrepareStatement(LOGIN_UPD_EXPANSION, "UPDATE account SET expansion = ? WHERE id = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(LOGIN_UPD_ACCOUNT_LOCK, "UPDATE account SET locked = ? WHERE id = ?", CONNECTION_ASYNC);
|
PrepareStatement(LOGIN_UPD_ACCOUNT_LOCK, "UPDATE account SET locked = ? WHERE id = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(LOGIN_UPD_ACCOUNT_LOCK_CONTRY, "UPDATE account SET lock_country = ? WHERE id = ?", CONNECTION_ASYNC);
|
PrepareStatement(LOGIN_UPD_ACCOUNT_LOCK_COUNTRY, "UPDATE account SET lock_country = ? WHERE id = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(LOGIN_UPD_USERNAME, "UPDATE account SET username = ? WHERE id = ?", CONNECTION_ASYNC);
|
PrepareStatement(LOGIN_UPD_USERNAME, "UPDATE account SET username = ? WHERE id = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(LOGIN_UPD_MUTE_TIME, "UPDATE account SET mutetime = ? , mutereason = ? , muteby = ? WHERE id = ?", CONNECTION_ASYNC);
|
PrepareStatement(LOGIN_UPD_MUTE_TIME, "UPDATE account SET mutetime = ? , mutereason = ? , muteby = ? WHERE id = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(LOGIN_UPD_MUTE_TIME_LOGIN, "UPDATE account SET mutetime = ? WHERE id = ?", CONNECTION_ASYNC);
|
PrepareStatement(LOGIN_UPD_MUTE_TIME_LOGIN, "UPDATE account SET mutetime = ? WHERE id = ?", CONNECTION_ASYNC);
|
||||||
@@ -87,7 +86,6 @@ void LoginDatabaseConnection::DoPrepareStatements()
|
|||||||
PrepareStatement(LOGIN_SEL_LAST_IP, "SELECT last_ip FROM account WHERE id = ?", CONNECTION_SYNCH);
|
PrepareStatement(LOGIN_SEL_LAST_IP, "SELECT last_ip FROM account WHERE id = ?", CONNECTION_SYNCH);
|
||||||
PrepareStatement(LOGIN_SEL_REALMLIST_SECURITY_LEVEL, "SELECT allowedSecurityLevel from realmlist WHERE id = ?", CONNECTION_SYNCH);
|
PrepareStatement(LOGIN_SEL_REALMLIST_SECURITY_LEVEL, "SELECT allowedSecurityLevel from realmlist WHERE id = ?", CONNECTION_SYNCH);
|
||||||
PrepareStatement(LOGIN_DEL_ACCOUNT, "DELETE FROM account WHERE id = ?", CONNECTION_ASYNC);
|
PrepareStatement(LOGIN_DEL_ACCOUNT, "DELETE FROM account WHERE id = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(LOGIN_SEL_IP2NATION_COUNTRY, "SELECT c.country FROM ip2nationCountries c, ip2nation i WHERE i.ip < ? AND c.code = i.country ORDER BY i.ip DESC LIMIT 0,1", CONNECTION_SYNCH);
|
|
||||||
PrepareStatement(LOGIN_SEL_AUTOBROADCAST, "SELECT id, weight, text FROM autobroadcast WHERE realmid = ? OR realmid = -1", CONNECTION_SYNCH);
|
PrepareStatement(LOGIN_SEL_AUTOBROADCAST, "SELECT id, weight, text FROM autobroadcast WHERE realmid = ? OR realmid = -1", CONNECTION_SYNCH);
|
||||||
PrepareStatement(LOGIN_INS_ACCOUNT_MUTE, "INSERT INTO account_muted VALUES (?, UNIX_TIMESTAMP(), ?, ?, ?)", CONNECTION_ASYNC);
|
PrepareStatement(LOGIN_INS_ACCOUNT_MUTE, "INSERT INTO account_muted VALUES (?, UNIX_TIMESTAMP(), ?, ?, ?)", CONNECTION_ASYNC);
|
||||||
PrepareStatement(LOGIN_SEL_ACCOUNT_MUTE_INFO, "SELECT mutedate, mutetime, mutereason, mutedby FROM account_muted WHERE guid = ? ORDER BY mutedate ASC", CONNECTION_SYNCH);
|
PrepareStatement(LOGIN_SEL_ACCOUNT_MUTE_INFO, "SELECT mutedate, mutetime, mutereason, mutedby FROM account_muted WHERE guid = ? ORDER BY mutedate ASC", CONNECTION_SYNCH);
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ enum LoginDatabaseStatements
|
|||||||
LOGIN_UPD_LOGONPROOF,
|
LOGIN_UPD_LOGONPROOF,
|
||||||
LOGIN_SEL_LOGONCHALLENGE,
|
LOGIN_SEL_LOGONCHALLENGE,
|
||||||
LOGIN_SEL_RECONNECTCHALLENGE,
|
LOGIN_SEL_RECONNECTCHALLENGE,
|
||||||
LOGIN_SEL_LOGON_COUNTRY,
|
|
||||||
LOGIN_UPD_FAILEDLOGINS,
|
LOGIN_UPD_FAILEDLOGINS,
|
||||||
LOGIN_SEL_FAILEDLOGINS,
|
LOGIN_SEL_FAILEDLOGINS,
|
||||||
LOGIN_SEL_ACCOUNT_ID_BY_NAME,
|
LOGIN_SEL_ACCOUNT_ID_BY_NAME,
|
||||||
@@ -69,7 +68,7 @@ enum LoginDatabaseStatements
|
|||||||
LOGIN_INS_REALM_CHARACTERS_INIT,
|
LOGIN_INS_REALM_CHARACTERS_INIT,
|
||||||
LOGIN_UPD_EXPANSION,
|
LOGIN_UPD_EXPANSION,
|
||||||
LOGIN_UPD_ACCOUNT_LOCK,
|
LOGIN_UPD_ACCOUNT_LOCK,
|
||||||
LOGIN_UPD_ACCOUNT_LOCK_CONTRY,
|
LOGIN_UPD_ACCOUNT_LOCK_COUNTRY,
|
||||||
LOGIN_UPD_USERNAME,
|
LOGIN_UPD_USERNAME,
|
||||||
LOGIN_UPD_MUTE_TIME,
|
LOGIN_UPD_MUTE_TIME,
|
||||||
LOGIN_UPD_MUTE_TIME_LOGIN,
|
LOGIN_UPD_MUTE_TIME_LOGIN,
|
||||||
@@ -98,7 +97,6 @@ enum LoginDatabaseStatements
|
|||||||
LOGIN_SEL_ACCOUNT_WHOIS,
|
LOGIN_SEL_ACCOUNT_WHOIS,
|
||||||
LOGIN_SEL_REALMLIST_SECURITY_LEVEL,
|
LOGIN_SEL_REALMLIST_SECURITY_LEVEL,
|
||||||
LOGIN_DEL_ACCOUNT,
|
LOGIN_DEL_ACCOUNT,
|
||||||
LOGIN_SEL_IP2NATION_COUNTRY,
|
|
||||||
LOGIN_SEL_AUTOBROADCAST,
|
LOGIN_SEL_AUTOBROADCAST,
|
||||||
LOGIN_SEL_LAST_ATTEMPT_IP,
|
LOGIN_SEL_LAST_ATTEMPT_IP,
|
||||||
LOGIN_SEL_LAST_IP,
|
LOGIN_SEL_LAST_IP,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "CryptoHash.h"
|
#include "CryptoHash.h"
|
||||||
#include "CryptoRandom.h"
|
#include "CryptoRandom.h"
|
||||||
#include "DatabaseEnv.h"
|
#include "DatabaseEnv.h"
|
||||||
|
#include "IPLocation.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Opcodes.h"
|
#include "Opcodes.h"
|
||||||
#include "PacketLog.h"
|
#include "PacketLog.h"
|
||||||
@@ -25,13 +26,13 @@
|
|||||||
#include "WorldSocket.h"
|
#include "WorldSocket.h"
|
||||||
#include "WorldSocketMgr.h"
|
#include "WorldSocketMgr.h"
|
||||||
#include <ace/Message_Block.h>
|
#include <ace/Message_Block.h>
|
||||||
|
#include <ace/OS_NS_string.h>
|
||||||
|
#include <ace/OS_NS_unistd.h>
|
||||||
|
#include <ace/Reactor.h>
|
||||||
#include <ace/os_include/arpa/os_inet.h>
|
#include <ace/os_include/arpa/os_inet.h>
|
||||||
#include <ace/os_include/netinet/os_tcp.h>
|
#include <ace/os_include/netinet/os_tcp.h>
|
||||||
#include <ace/os_include/sys/os_socket.h>
|
#include <ace/os_include/sys/os_socket.h>
|
||||||
#include <ace/os_include/sys/os_types.h>
|
#include <ace/os_include/sys/os_types.h>
|
||||||
#include <ace/OS_NS_string.h>
|
|
||||||
#include <ace/OS_NS_unistd.h>
|
|
||||||
#include <ace/Reactor.h>
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#ifdef ELUNA
|
#ifdef ELUNA
|
||||||
@@ -921,8 +922,8 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if (IpLocationRecord const* location = sIPLocation->GetLocationRecord(address))
|
if (IpLocationRecord const* location = sIPLocation->GetLocationRecord(address))
|
||||||
_ipCountry = location->CountryCode;*/
|
_ipCountry = location->CountryCode;
|
||||||
|
|
||||||
///- Re-check ip locking (same check as in auth).
|
///- Re-check ip locking (same check as in auth).
|
||||||
if (account.IsLockedToIP)
|
if (account.IsLockedToIP)
|
||||||
@@ -938,18 +939,18 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//else if (!account.LockCountry.empty() && account.LockCountry != "00" && !_ipCountry.empty())
|
else if (!account.LockCountry.empty() && account.LockCountry != "00" && !_ipCountry.empty())
|
||||||
//{
|
{
|
||||||
// if (account.LockCountry != _ipCountry)
|
if (account.LockCountry != _ipCountry)
|
||||||
// {
|
{
|
||||||
// packet.Initialize(SMSG_AUTH_RESPONSE, 1);
|
packet.Initialize(SMSG_AUTH_RESPONSE, 1);
|
||||||
// packet << uint8(AUTH_REJECT);
|
packet << uint8(AUTH_REJECT);
|
||||||
// LOG_DEBUG("network", "WorldSocket::HandleAuthSession: Sent Auth Response (Account country differs. Original country: %s, new country: %s).", account.LockCountry.c_str(), _ipCountry.c_str());
|
LOG_DEBUG("network", "WorldSocket::HandleAuthSession: Sent Auth Response (Account country differs. Original country: %s, new country: %s).", account.LockCountry.c_str(), _ipCountry.c_str());
|
||||||
// // We could log on hook only instead of an additional db log, however action logger is config based. Better keep DB logging as well
|
// We could log on hook only instead of an additional db log, however action logger is config based. Better keep DB logging as well
|
||||||
// sScriptMgr->OnFailedAccountLogin(account.Id);
|
sScriptMgr->OnFailedAccountLogin(account.Id);
|
||||||
// return -1;
|
return -1;
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
|
|
||||||
if (account.IsBanned)
|
if (account.IsBanned)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -191,6 +191,8 @@ private:
|
|||||||
bool m_OutActive;
|
bool m_OutActive;
|
||||||
|
|
||||||
std::array<uint8, 4> m_Seed;
|
std::array<uint8, 4> m_Seed;
|
||||||
|
|
||||||
|
std::string _ipCountry;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _WORLDSOCKET_H */
|
#endif /* _WORLDSOCKET_H */
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
#include "GuildMgr.h"
|
#include "GuildMgr.h"
|
||||||
#include "InstanceSaveMgr.h"
|
#include "InstanceSaveMgr.h"
|
||||||
#include "ItemEnchantmentMgr.h"
|
#include "ItemEnchantmentMgr.h"
|
||||||
|
#include "IPLocation.h"
|
||||||
#include "Language.h"
|
#include "Language.h"
|
||||||
#include "LFGMgr.h"
|
#include "LFGMgr.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
@@ -1503,6 +1504,9 @@ void World::SetInitialWorldSettings()
|
|||||||
LoadDBCStores(m_dataPath);
|
LoadDBCStores(m_dataPath);
|
||||||
DetectDBCLang();
|
DetectDBCLang();
|
||||||
|
|
||||||
|
// Load IP Location Database
|
||||||
|
sIPLocation->Load();
|
||||||
|
|
||||||
std::vector<uint32> mapIds;
|
std::vector<uint32> mapIds;
|
||||||
for (auto const& map : sMapStore)
|
for (auto const& map : sMapStore)
|
||||||
mapIds.emplace_back(map->MapID);
|
mapIds.emplace_back(map->MapID);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ EndScriptData */
|
|||||||
#include "Base32.h"
|
#include "Base32.h"
|
||||||
#include "Chat.h"
|
#include "Chat.h"
|
||||||
#include "CryptoGenerics.h"
|
#include "CryptoGenerics.h"
|
||||||
|
#include "IPLocation.h"
|
||||||
#include "Language.h"
|
#include "Language.h"
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
#include "Realm.h"
|
#include "Realm.h"
|
||||||
@@ -23,8 +24,8 @@ EndScriptData */
|
|||||||
#include "SecretMgr.h"
|
#include "SecretMgr.h"
|
||||||
#include "StringConvert.h"
|
#include "StringConvert.h"
|
||||||
#include "TOTP.h"
|
#include "TOTP.h"
|
||||||
#include <unordered_map>
|
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
class account_commandscript : public CommandScript
|
class account_commandscript : public CommandScript
|
||||||
{
|
{
|
||||||
@@ -53,6 +54,11 @@ public:
|
|||||||
{ "remove", SEC_PLAYER, false, &HandleAccount2FARemoveCommand, "" },
|
{ "remove", SEC_PLAYER, false, &HandleAccount2FARemoveCommand, "" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static std::vector<ChatCommand> accountRemoveCommandTable
|
||||||
|
{
|
||||||
|
{ "country", SEC_ADMINISTRATOR, true, &HandleAccountRemoveLockCountryCommand, "" }
|
||||||
|
};
|
||||||
|
|
||||||
static std::vector<ChatCommand> accountCommandTable =
|
static std::vector<ChatCommand> accountCommandTable =
|
||||||
{
|
{
|
||||||
{ "2fa", SEC_PLAYER, true, nullptr, "", account2faCommandTable },
|
{ "2fa", SEC_PLAYER, true, nullptr, "", account2faCommandTable },
|
||||||
@@ -63,6 +69,7 @@ public:
|
|||||||
{ "lock", SEC_PLAYER, false, nullptr, "", accountLockCommandTable },
|
{ "lock", SEC_PLAYER, false, nullptr, "", accountLockCommandTable },
|
||||||
{ "set", SEC_ADMINISTRATOR, true, nullptr, "", accountSetCommandTable },
|
{ "set", SEC_ADMINISTRATOR, true, nullptr, "", accountSetCommandTable },
|
||||||
{ "password", SEC_PLAYER, false, &HandleAccountPasswordCommand, "" },
|
{ "password", SEC_PLAYER, false, &HandleAccountPasswordCommand, "" },
|
||||||
|
{ "remove", SEC_ADMINISTRATOR, true, nullptr, "", accountRemoveCommandTable },
|
||||||
{ "", SEC_PLAYER, false, &HandleAccountCommand, "" }
|
{ "", SEC_PLAYER, false, &HandleAccountCommand, "" }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -412,6 +419,45 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool HandleAccountRemoveLockCountryCommand(ChatHandler* handler, char const* args)
|
||||||
|
{
|
||||||
|
if (!*args)
|
||||||
|
{
|
||||||
|
handler->SendSysMessage(LANG_CMD_SYNTAX);
|
||||||
|
handler->SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
///- %Parse the command line arguments
|
||||||
|
char* _accountName = strtok((char*)args, " ");
|
||||||
|
if (!_accountName)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::string accountName = _accountName;
|
||||||
|
if (!Utf8ToUpperOnlyLatin(accountName))
|
||||||
|
{
|
||||||
|
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str());
|
||||||
|
handler->SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 accountId = AccountMgr::GetId(accountName);
|
||||||
|
if (!accountId)
|
||||||
|
{
|
||||||
|
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str());
|
||||||
|
handler->SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_LOCK_COUNTRY);
|
||||||
|
stmt->setString(0, "00");
|
||||||
|
stmt->setUInt32(1, accountId);
|
||||||
|
LoginDatabase.Execute(stmt);
|
||||||
|
handler->PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool HandleAccountLockCountryCommand(ChatHandler* handler, char const* args)
|
static bool HandleAccountLockCountryCommand(ChatHandler* handler, char const* args)
|
||||||
{
|
{
|
||||||
if (!*args)
|
if (!*args)
|
||||||
@@ -427,30 +473,24 @@ public:
|
|||||||
{
|
{
|
||||||
if (param == "on")
|
if (param == "on")
|
||||||
{
|
{
|
||||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY);
|
if (IpLocationRecord const* location = sIPLocation->GetLocationRecord(handler->GetSession()->GetRemoteAddress()))
|
||||||
uint32 ip = inet_addr(handler->GetSession()->GetRemoteAddress().c_str());
|
|
||||||
EndianConvertReverse(ip);
|
|
||||||
stmt->setUInt32(0, ip);
|
|
||||||
PreparedQueryResult result = LoginDatabase.Query(stmt);
|
|
||||||
if (result)
|
|
||||||
{
|
{
|
||||||
Field* fields = result->Fetch();
|
auto* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_LOCK_COUNTRY);
|
||||||
std::string country = fields[0].GetString();
|
stmt->setString(0, location->CountryCode);
|
||||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_LOCK_CONTRY);
|
|
||||||
stmt->setString(0, country);
|
|
||||||
stmt->setUInt32(1, handler->GetSession()->GetAccountId());
|
stmt->setUInt32(1, handler->GetSession()->GetAccountId());
|
||||||
LoginDatabase.Execute(stmt);
|
LoginDatabase.Execute(stmt);
|
||||||
handler->PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED);
|
handler->PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
handler->PSendSysMessage("[IP2NATION] Table empty");
|
handler->PSendSysMessage("No IP2Location information - account not locked");
|
||||||
;//LOG_DEBUG("network", "[IP2NATION] Table empty");
|
handler->SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (param == "off")
|
else if (param == "off")
|
||||||
{
|
{
|
||||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_LOCK_CONTRY);
|
auto* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_LOCK_COUNTRY);
|
||||||
stmt->setString(0, "00");
|
stmt->setString(0, "00");
|
||||||
stmt->setUInt32(1, handler->GetSession()->GetAccountId());
|
stmt->setUInt32(1, handler->GetSession()->GetAccountId());
|
||||||
LoginDatabase.Execute(stmt);
|
LoginDatabase.Execute(stmt);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "GroupMgr.h"
|
#include "GroupMgr.h"
|
||||||
#include "GuildMgr.h"
|
#include "GuildMgr.h"
|
||||||
#include "InstanceSaveMgr.h"
|
#include "InstanceSaveMgr.h"
|
||||||
|
#include "IPLocation.h"
|
||||||
#include "Language.h"
|
#include "Language.h"
|
||||||
#include "LFG.h"
|
#include "LFG.h"
|
||||||
#include "MapManager.h"
|
#include "MapManager.h"
|
||||||
@@ -1928,29 +1929,11 @@ public:
|
|||||||
lastIp = fields[4].GetString();
|
lastIp = fields[4].GetString();
|
||||||
lastLogin = fields[5].GetString();
|
lastLogin = fields[5].GetString();
|
||||||
|
|
||||||
/** if (IpLocationRecord const* location = sIPLocation->GetLocationRecord(lastIp))
|
if (IpLocationRecord const* location = sIPLocation->GetLocationRecord(lastIp))
|
||||||
{
|
{
|
||||||
lastIp.append(" (");
|
lastIp.append(" (");
|
||||||
lastIp.append(location->CountryName);
|
lastIp.append(location->CountryName);
|
||||||
lastIp.append(")");
|
lastIp.append(")");
|
||||||
} **/
|
|
||||||
|
|
||||||
uint32 ip = inet_addr(lastIp.c_str());
|
|
||||||
#if ACORE_ENDIAN == BIGENDIAN
|
|
||||||
EndianConvertReverse(ip);
|
|
||||||
#endif
|
|
||||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP2NATION_COUNTRY);
|
|
||||||
|
|
||||||
stmt->setUInt32(0, ip);
|
|
||||||
|
|
||||||
PreparedQueryResult result2 = LoginDatabase.Query(stmt);
|
|
||||||
|
|
||||||
if (result2)
|
|
||||||
{
|
|
||||||
Field* fields2 = result2->Fetch();
|
|
||||||
lastIp.append(" (");
|
|
||||||
lastIp.append(fields2[0].GetString());
|
|
||||||
lastIp.append(")");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -157,6 +157,16 @@ WorldServerPort = 8085
|
|||||||
|
|
||||||
BindIP = "0.0.0.0"
|
BindIP = "0.0.0.0"
|
||||||
|
|
||||||
|
#
|
||||||
|
# IPLocationFile
|
||||||
|
# Description: The path to your IP2Location database CSV file.
|
||||||
|
# Example: "C:/acore/IP2LOCATION-LITE-DB1.CSV"
|
||||||
|
# "/home/acore/IP2LOCATION-LITE-DB1.CSV"
|
||||||
|
# Default: "" - (Disabled)
|
||||||
|
#
|
||||||
|
|
||||||
|
IPLocationFile = ""
|
||||||
|
|
||||||
#
|
#
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user