diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql
index c5f18b9f930..f83596f3e8e 100644
--- a/sql/base/auth_database.sql
+++ b/sql/base/auth_database.sql
@@ -324,58 +324,6 @@ INSERT INTO `battlenet_modules` VALUES
/*!40000 ALTER TABLE `battlenet_modules` ENABLE KEYS */;
UNLOCK TABLES;
---
--- Table structure for table `ip2nation`
---
-
-DROP TABLE IF EXISTS `ip2nation`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `ip2nation` (
- `ip` int(11) unsigned NOT NULL DEFAULT '0',
- `country` char(2) NOT NULL DEFAULT '',
- KEY `ip` (`ip`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `ip2nation`
---
-
-LOCK TABLES `ip2nation` WRITE;
-/*!40000 ALTER TABLE `ip2nation` DISABLE KEYS */;
-/*!40000 ALTER TABLE `ip2nation` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `ip2nationCountries`
---
-
-DROP TABLE IF EXISTS `ip2nationCountries`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-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=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `ip2nationCountries`
---
-
-LOCK TABLES `ip2nationCountries` WRITE;
-/*!40000 ALTER TABLE `ip2nationCountries` DISABLE KEYS */;
-/*!40000 ALTER TABLE `ip2nationCountries` ENABLE KEYS */;
-UNLOCK TABLES;
-
--
-- Table structure for table `ip_banned`
--
@@ -2011,7 +1959,8 @@ INSERT INTO `updates` VALUES
('2018_03_28_00_auth.sql','45A7C896BDF00B1C319C9F889893D3B95E45EF0A','ARCHIVED','2018-03-28 01:40:04',0),
('2018_04_15_00_auth.sql','2293BAA1DA754CFD780838FE99EDB98FD7C041E0','ARCHIVED','2018-04-15 01:40:04',0),
('2018_05_15_00_auth.sql','9076B44013D5BE1E92A06BDE7CE4F9B6663272CC','ARCHIVED','2018-05-15 01:40:04',0),
-('2018_06_15_00_auth.sql','28E2E814F529190BC9423E2A220970F60307DD22','ARCHIVED','2018-06-15 01:40:04',0);
+('2018_06_15_00_auth.sql','28E2E814F529190BC9423E2A220970F60307DD22','ARCHIVED','2018-06-15 01:40:04',0),
+('2018_06_23_00_auth.sql','BE35312C386A127D047E5A7CE0D14DB41D905F8E','ARCHIVED','2018-06-23 01:40:04',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/sql/updates/auth/4.3.4/2018_06_23_00_auth.sql b/sql/updates/auth/4.3.4/2018_06_23_00_auth.sql
new file mode 100644
index 00000000000..3bbe03f8c19
--- /dev/null
+++ b/sql/updates/auth/4.3.4/2018_06_23_00_auth.sql
@@ -0,0 +1,3 @@
+--
+DROP TABLE IF EXISTS `ip2nation`;
+DROP TABLE IF EXISTS `ip2nationCountries`;
diff --git a/sql/updates/world/3.3.5/2018_06_17_00_world.sql b/sql/updates/world/4.3.4/2018_06_23_00_world_from_335_was_2018_06_17_00_world.sql
similarity index 100%
rename from sql/updates/world/3.3.5/2018_06_17_00_world.sql
rename to sql/updates/world/4.3.4/2018_06_23_00_world_from_335_was_2018_06_17_00_world.sql
diff --git a/sql/updates/world/3.3.5/2018_06_17_01_world.sql b/sql/updates/world/4.3.4/2018_06_23_01_world_from_335_was_2018_06_17_01_world.sql
similarity index 100%
rename from sql/updates/world/3.3.5/2018_06_17_01_world.sql
rename to sql/updates/world/4.3.4/2018_06_23_01_world_from_335_was_2018_06_17_01_world.sql
diff --git a/sql/updates/world/3.3.5/2018_06_17_03_world.sql b/sql/updates/world/4.3.4/2018_06_23_02_world_from_335_was_2018_06_17_03_world.sql
similarity index 100%
rename from sql/updates/world/3.3.5/2018_06_17_03_world.sql
rename to sql/updates/world/4.3.4/2018_06_23_02_world_from_335_was_2018_06_17_03_world.sql
diff --git a/sql/updates/world/3.3.5/2018_06_17_04_world.sql b/sql/updates/world/4.3.4/2018_06_23_03_world_from_335_was_2018_06_17_04_world.sql
similarity index 100%
rename from sql/updates/world/3.3.5/2018_06_17_04_world.sql
rename to sql/updates/world/4.3.4/2018_06_23_03_world_from_335_was_2018_06_17_04_world.sql
diff --git a/sql/updates/world/3.3.5/2018_06_17_05_world.sql b/sql/updates/world/4.3.4/2018_06_23_04_world_from_335_was_2018_06_17_05_world.sql
similarity index 100%
rename from sql/updates/world/3.3.5/2018_06_17_05_world.sql
rename to sql/updates/world/4.3.4/2018_06_23_04_world_from_335_was_2018_06_17_05_world.sql
diff --git a/sql/updates/world/3.3.5/2018_06_21_00_world_335.sql b/sql/updates/world/4.3.4/2018_06_23_05_world_from_335_was_2018_06_21_00_world_335.sql
similarity index 99%
rename from sql/updates/world/3.3.5/2018_06_21_00_world_335.sql
rename to sql/updates/world/4.3.4/2018_06_23_05_world_from_335_was_2018_06_21_00_world_335.sql
index 77387c7572b..ce120fd306c 100644
--- a/sql/updates/world/3.3.5/2018_06_21_00_world_335.sql
+++ b/sql/updates/world/4.3.4/2018_06_23_05_world_from_335_was_2018_06_21_00_world_335.sql
@@ -1,3 +1,4 @@
+/*
--
UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID` IN
(118, -- Quest "The Price of Shoes"
@@ -153,3 +154,4 @@ INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `Emot
(2358,1,1,0,0,0,0,0,0,0);
UPDATE `quest_request_items` SET `EmoteOnIncomplete`=6, `EmoteOnComplete`=6 WHERE `ID`=2358;
UPDATE `quest_offer_reward` SET `Emote1`=21, `Emote2`=1 WHERE `ID`=2358;
+*/
diff --git a/sql/updates/world/3.3.5/2018_06_21_01_world.sql b/sql/updates/world/4.3.4/2018_06_23_06_world_from_335_was_2018_06_21_01_world.sql
similarity index 100%
rename from sql/updates/world/3.3.5/2018_06_21_01_world.sql
rename to sql/updates/world/4.3.4/2018_06_23_06_world_from_335_was_2018_06_21_01_world.sql
diff --git a/sql/updates/world/3.3.5/2018_06_21_02_world_335.sql b/sql/updates/world/4.3.4/2018_06_23_07_world_from_335_was_2018_06_21_02_world_335.sql
similarity index 99%
rename from sql/updates/world/3.3.5/2018_06_21_02_world_335.sql
rename to sql/updates/world/4.3.4/2018_06_23_07_world_from_335_was_2018_06_21_02_world_335.sql
index 8e4915c5970..ea4e498ec58 100644
--- a/sql/updates/world/3.3.5/2018_06_21_02_world_335.sql
+++ b/sql/updates/world/4.3.4/2018_06_23_07_world_from_335_was_2018_06_21_02_world_335.sql
@@ -1,3 +1,4 @@
+/*
-- Rift Spawn
DELETE FROM `smart_scripts` WHERE `entryorguid`=6492 AND `source_type`=0;
DELETE FROM `smart_scripts` WHERE `entryorguid`=649200 AND `source_type`=9;
@@ -25,3 +26,4 @@ DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceEntry`=64
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=9082 AND `ConditionTypeOrReference`=1;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13,1,9082,0,0,1,0,9032,0,0,0,0,0,"","Create Containment Coffer can only be casted if target has aura 'Self Stun - 30 seconds'");
+*/
diff --git a/src/common/IPLocation/IPLocation.cpp b/src/common/IPLocation/IPLocation.cpp
new file mode 100644
index 00000000000..e4f7509f4b6
--- /dev/null
+++ b/src/common/IPLocation/IPLocation.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2008-2018 TrinityCore
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#include "IPLocation.h"
+#include "Config.h"
+#include "IpAddress.h"
+#include "Log.h"
+#include
+#include
+
+IpLocationStore::IpLocationStore()
+{
+}
+
+IpLocationStore::~IpLocationStore()
+{
+}
+
+void IpLocationStore::Load()
+{
+ std::string value = sConfigMgr->GetStringDefault("IPLocationFile", ".");
+ if (value.empty())
+ return;
+
+ _ipLocationStore.clear();
+ TC_LOG_INFO("server.loading", "Loading IP Location Database...");
+
+ // Default folder
+ if (!value.compare("."))
+ value.append("/IP2LOCATION-LITE-DB1.CSV");
+
+ // Check file name
+ if (value.find("IP2LOCATION-LITE-DB1.CSV") == std::string::npos)
+ {
+ TC_LOG_ERROR("server.loading", "IPLocation:: File name is not valid, must be IP2LOCATION-LITE-DB1.CSV");
+ return;
+ }
+
+ // Check if file exists
+ std::ifstream ipfile(value);
+ if (!ipfile)
+ {
+ TC_LOG_ERROR("server.loading", "IPLocation:: No database file exists.");
+ return;
+ }
+
+ if (!ipfile.is_open())
+ {
+ TC_LOG_ERROR("server.loading", "IPLocation:: The file can not be opened.");
+ return;
+ }
+
+ std::string ip_from;
+ std::string ip_to;
+ std::string country_code;
+ std::string country_name;
+
+ while (ipfile.good())
+ {
+ // Read lines
+ std::getline(ipfile, ip_from, ',');
+ std::getline(ipfile, ip_to, ',');
+ std::getline(ipfile, country_code, ',');
+ std::getline(ipfile, country_name, '\n');
+
+ // Remove new lines and return
+ country_name.erase(std::remove(country_name.begin(), country_name.end(), '\r'), country_name.end());
+ country_name.erase(std::remove(country_name.begin(), country_name.end(), '\n'), country_name.end());
+
+ // Remove quotation marks
+ ip_from.erase(std::remove(ip_from.begin(), ip_from.end(), '"'), ip_from.end());
+ ip_to.erase(std::remove(ip_to.begin(), ip_to.end(), '"'), ip_to.end());
+ country_code.erase(std::remove(country_code.begin(), country_code.end(), '"'), country_code.end());
+ country_name.erase(std::remove(country_name.begin(), country_name.end(), '"'), country_name.end());
+
+ // Convert country code to lowercase
+ std::transform(country_code.begin(), country_code.end(), country_code.begin(), ::tolower);
+
+ IpLocationRecord data;
+ data.ip_from = (uint32)atoull(ip_from.c_str());
+ data.ip_to = (uint32)atoull(ip_to.c_str());
+ data.country_code = country_code;
+ data.country_name = country_name;
+
+ _ipLocationStore.push_back(data);
+ }
+
+ std::sort(_ipLocationStore.begin(), _ipLocationStore.end(), [](IpLocationRecord const& a, IpLocationRecord const& b) { return a.ip_from < b.ip_from; });
+
+ ipfile.close();
+
+ TC_LOG_INFO("server.loading", ">> Loaded %u entries.", uint32(_ipLocationStore.size()));
+}
+
+IpLocationRecord* IpLocationStore::GetData(std::string const& ipAddress)
+{
+ if (_ipLocationStore.empty())
+ return nullptr;
+
+ uint32 ip = Trinity::Net::address_to_uint(Trinity::Net::make_address_v4(ipAddress));
+ auto itr = std::upper_bound(_ipLocationStore.begin(), _ipLocationStore.end(), ip, [](uint32 ip, IpLocationRecord const& loc) { return loc.ip_to >= ip; });
+ ASSERT(&(*itr));
+
+ return &(*itr);
+}
+
+IpLocationStore* IpLocationStore::instance()
+{
+ static IpLocationStore instance;
+ return &instance;
+}
+
diff --git a/src/common/IPLocation/IPLocation.h b/src/common/IPLocation/IPLocation.h
new file mode 100644
index 00000000000..2e078a9ce4d
--- /dev/null
+++ b/src/common/IPLocation/IPLocation.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008-2018 TrinityCore
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#include "Define.h"
+#include
+
+struct IpLocationRecord
+{
+ uint32 ip_from;
+ uint32 ip_to;
+ std::string country_code;
+ std::string country_name;
+};
+
+class TC_COMMON_API IpLocationStore
+{
+ public:
+ IpLocationStore();
+ ~IpLocationStore();
+ static IpLocationStore* instance();
+
+ void Load();
+ IpLocationRecord* GetData(std::string const& ipAddress);
+
+ private:
+ std::vector _ipLocationStore;
+};
+
+#define sIPLocation IpLocationStore::instance()
+
diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp
index 3417f522481..772a8657745 100644
--- a/src/server/authserver/Main.cpp
+++ b/src/server/authserver/Main.cpp
@@ -33,6 +33,7 @@
#include "GitRevision.h"
#include "GruntRealmList.h"
#include "IoContext.h"
+#include "IPLocation.h"
#include "MySQLThreading.h"
#include "ProcessPriority.h"
#include "Util.h"
@@ -137,6 +138,9 @@ int main(int argc, char** argv)
if (!StartDB())
return 1;
+ // Load IP Location Database
+ sIPLocation->Load();
+
std::shared_ptr dbHandle(nullptr, [](void*) { StopDB(); });
std::shared_ptr ioContext = std::make_shared();
diff --git a/src/server/authserver/Server/AuthSession.cpp b/src/server/authserver/Server/AuthSession.cpp
index 1ebfaa50372..7113c7e05bf 100644
--- a/src/server/authserver/Server/AuthSession.cpp
+++ b/src/server/authserver/Server/AuthSession.cpp
@@ -22,6 +22,7 @@
#include "Config.h"
#include "DatabaseEnv.h"
#include "Errors.h"
+#include "IPLocation.h"
#include "GruntRealmList.h"
#include "Log.h"
#include "Realm.h"
@@ -171,7 +172,6 @@ void AuthSession::Start()
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_INFO);
stmt->setString(0, ip_address);
- stmt->setUInt32(1, inet_addr(ip_address.c_str()));
_queryProcessor.AddQuery(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&AuthSession::CheckIpCallback, this, std::placeholders::_1)));
}
@@ -197,9 +197,6 @@ void AuthSession::CheckIpCallback(PreparedQueryResult result)
if (fields[0].GetUInt64() != 0)
banned = true;
- if (!fields[1].GetString().empty())
- _ipCountry = fields[1].GetString();
-
} while (result->NextRow());
if (banned)
@@ -346,6 +343,9 @@ void AuthSession::LogonChallengeCallback(PreparedQueryResult result)
}
else
{
+ if (IpLocationRecord* location = sIPLocation->GetData(ipAddress))
+ _ipCountry = location->country_code;
+
TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is not locked to ip", _accountInfo.Login.c_str());
if (_accountInfo.LockCountry.empty() || _accountInfo.LockCountry == "00")
TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is not locked to country", _accountInfo.Login.c_str());
diff --git a/src/server/authserver/authserver.conf.dist b/src/server/authserver/authserver.conf.dist
index 1d3b48839a8..a6e3d4b8f92 100644
--- a/src/server/authserver/authserver.conf.dist
+++ b/src/server/authserver/authserver.conf.dist
@@ -157,6 +157,16 @@ SourceDirectory = ""
MySQLExecutable = ""
+#
+# IPLocationFile
+# Description: The path to your IP2Location database CSV file.
+# Example: "C:/Trinity/IP2Location.csv"
+# "/home/trinity/IP2Location.csv"
+# Default: "." - (Current core directory)
+# "" - (Disabled)
+
+IPLocationFile = "."
+
#
###################################################################################################
diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp
index 139f1388fe7..4345064c2d1 100644
--- a/src/server/database/Database/Implementation/LoginDatabase.cpp
+++ b/src/server/database/Database/Implementation/LoginDatabase.cpp
@@ -26,9 +26,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_SEL_REALMLIST, "SELECT id, name, address, localAddress, localSubnetMask, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild, Region, Battlegroup FROM realmlist WHERE flag <> 3 ORDER BY name", CONNECTION_SYNCH);
PrepareStatement(LOGIN_DEL_EXPIRED_IP_BANS, "DELETE FROM ip_banned WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS, "UPDATE account_banned SET active = 0 WHERE active = 1 AND unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC);
- PrepareStatement(LOGIN_SEL_IP_INFO, "(SELECT unbandate > UNIX_TIMESTAMP() OR unbandate = bandate AS banned, NULL as country FROM ip_banned WHERE ip = ?) "
- "UNION "
- "(SELECT NULL AS banned, country FROM ip2nation WHERE INET_NTOA(ip) = ?)", CONNECTION_ASYNC);
+ PrepareStatement(LOGIN_SEL_IP_INFO, "SELECT unbandate > UNIX_TIMESTAMP() OR unbandate = bandate AS banned, NULL as country FROM ip_banned WHERE ip = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_INS_IP_AUTO_BANNED, "INSERT INTO ip_banned (ip, bandate, unbandate, bannedby, banreason) VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity Auth', 'Failed login autoban')", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_IP_BANNED_ALL, "SELECT ip, bandate, unbandate, bannedby, banreason FROM ip_banned WHERE (bandate = unbandate OR unbandate > UNIX_TIMESTAMP()) ORDER BY unbandate", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_IP_BANNED_BY_IP, "SELECT ip, bandate, unbandate, bannedby, banreason FROM ip_banned WHERE (bandate = unbandate OR unbandate > UNIX_TIMESTAMP()) AND ip LIKE CONCAT('%%', ?, '%%') ORDER BY unbandate", CONNECTION_SYNCH);
@@ -44,7 +42,6 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_SEL_RECONNECTCHALLENGE, "SELECT a.id, UPPER(a.username), a.locked, a.lock_country, a.last_ip, a.failed_logins, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, "
"ab.unbandate = ab.bandate, aa.gmlevel, a.sessionKey "
"FROM account a LEFT JOIN account_access aa ON a.id = aa.id LEFT JOIN account_banned ab ON ab.id = a.id AND ab.active = 1 WHERE a.username = ?", CONNECTION_ASYNC);
- 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_SEL_ACCOUNT_ID_BY_NAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_NAME, "SELECT id, username FROM account WHERE username = ?", CONNECTION_SYNCH);
@@ -103,7 +100,6 @@ void LoginDatabaseConnection::DoPrepareStatements()
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_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_GET_EMAIL_BY_ID, "SELECT email FROM account WHERE id = ?", CONNECTION_SYNCH);
// 0: uint32, 1: uint32, 2: uint8, 3: uint32, 4: string // Complete name: "Login_Insert_AccountLoginDeLete_IP_Logging"
diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h
index f5503684d74..c332b6808c2 100644
--- a/src/server/database/Database/Implementation/LoginDatabase.h
+++ b/src/server/database/Database/Implementation/LoginDatabase.h
@@ -41,7 +41,6 @@ enum LoginDatabaseStatements : uint32
LOGIN_UPD_LOGONPROOF,
LOGIN_SEL_LOGONCHALLENGE,
LOGIN_SEL_RECONNECTCHALLENGE,
- LOGIN_SEL_LOGON_COUNTRY,
LOGIN_UPD_FAILEDLOGINS,
LOGIN_SEL_ACCOUNT_ID_BY_NAME,
LOGIN_SEL_ACCOUNT_LIST_BY_NAME,
@@ -95,7 +94,6 @@ enum LoginDatabaseStatements : uint32
LOGIN_SEL_ACCOUNT_WHOIS,
LOGIN_SEL_REALMLIST_SECURITY_LEVEL,
LOGIN_DEL_ACCOUNT,
- LOGIN_SEL_IP2NATION_COUNTRY,
LOGIN_SEL_AUTOBROADCAST,
LOGIN_SEL_LAST_ATTEMPT_IP,
LOGIN_SEL_LAST_IP,
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index b0ecd463493..d4377d9d6f2 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -20,6 +20,7 @@
#include "BattlenetAccountMgr.h"
#include "BigNumber.h"
#include "DatabaseEnv.h"
+#include "IPLocation.h"
#include "Opcodes.h"
#include "PacketLog.h"
#include "QueryCallback.h"
@@ -60,7 +61,6 @@ void WorldSocket::Start()
std::string ip_address = GetRemoteIpAddress().to_string();
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_INFO);
stmt->setString(0, ip_address);
- stmt->setUInt32(1, inet_addr(ip_address.c_str()));
_queryProcessor.AddQuery(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSocket::CheckIpCallback, this, std::placeholders::_1)));
}
@@ -76,9 +76,6 @@ void WorldSocket::CheckIpCallback(PreparedQueryResult result)
if (fields[0].GetUInt64() != 0)
banned = true;
- if (!fields[1].GetString().empty())
- _ipCountry = fields[1].GetString();
-
} while (result->NextRow());
if (banned)
@@ -614,6 +611,9 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr authSes
return;
}
+ if (IpLocationRecord* location = sIPLocation->GetData(address))
+ _ipCountry = location->country_code;
+
///- Re-check ip locking (same check as in auth).
if (account.BattleNet.IsLockedToIP) // if ip is locked
{
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 4183ef209e8..ead85b9c6cb 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -51,6 +51,7 @@
#include "GuildFinderMgr.h"
#include "GuildMgr.h"
#include "InstanceSaveMgr.h"
+#include "IPLocation.h"
#include "Language.h"
#include "LFGMgr.h"
#include "Log.h"
@@ -1516,6 +1517,9 @@ void World::SetInitialWorldSettings()
// Load M2 fly by cameras
LoadM2Cameras(m_dataPath);
+ // Load IP Location Database
+ sIPLocation->Load();
+
std::unordered_map> mapData;
for (MapEntry const* mapEntry : sMapStore)
{
diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp
index 03929ded169..051c8f8fb0d 100644
--- a/src/server/scripts/Commands/cs_account.cpp
+++ b/src/server/scripts/Commands/cs_account.cpp
@@ -26,6 +26,7 @@ EndScriptData */
#include "Chat.h"
#include "DatabaseEnv.h"
#include "IpAddress.h"
+#include "IPLocation.h"
#include "Language.h"
#include "Log.h"
#include "Player.h"
@@ -290,25 +291,18 @@ public:
{
if (param == "on")
{
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY);
- uint32 ip = Trinity::Net::address_to_uint(Trinity::Net::make_address_v4(handler->GetSession()->GetRemoteAddress()));
- EndianConvertReverse(ip);
- stmt->setUInt32(0, ip);
- PreparedQueryResult result = LoginDatabase.Query(stmt);
- if (result)
+ if (IpLocationRecord* location = sIPLocation->GetData(handler->GetSession()->GetRemoteAddress()))
{
- Field* fields = result->Fetch();
- std::string country = fields[0].GetString();
- stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_LOCK_CONTRY);
- stmt->setString(0, country);
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_LOCK_CONTRY);
+ stmt->setString(0, location->country_code);
stmt->setUInt32(1, handler->GetSession()->GetAccountId());
LoginDatabase.Execute(stmt);
handler->PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED);
}
else
{
- handler->PSendSysMessage("[IP2NATION] Table empty");
- TC_LOG_DEBUG("server.authserver", "[IP2NATION] Table empty");
+ handler->PSendSysMessage("IP2Location] No information");
+ TC_LOG_DEBUG("server.authserver", "IP2Location] No information");
}
}
else if (param == "off")
diff --git a/src/server/scripts/Commands/cs_battlenet_account.cpp b/src/server/scripts/Commands/cs_battlenet_account.cpp
index 5b1a25a0b7b..500c294cde6 100644
--- a/src/server/scripts/Commands/cs_battlenet_account.cpp
+++ b/src/server/scripts/Commands/cs_battlenet_account.cpp
@@ -21,6 +21,7 @@
#include "Chat.h"
#include "DatabaseEnv.h"
#include "IpAddress.h"
+#include "IPLocation.h"
#include "Language.h"
#include "Log.h"
#include "Player.h"
@@ -128,25 +129,18 @@ public:
{
if (param == "on")
{
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY);
- uint32 ip = Trinity::Net::address_to_uint(Trinity::Net::make_address_v4(handler->GetSession()->GetRemoteAddress()));
- EndianConvertReverse(ip);
- stmt->setUInt32(0, ip);
- PreparedQueryResult result = LoginDatabase.Query(stmt);
- if (result)
+ if (IpLocationRecord* location = sIPLocation->GetData(handler->GetSession()->GetRemoteAddress()))
{
- Field* fields = result->Fetch();
- std::string country = fields[0].GetString();
- stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_ACCOUNT_LOCK_CONTRY);
- stmt->setString(0, country);
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_ACCOUNT_LOCK_CONTRY);
+ stmt->setString(0, location->country_code);
stmt->setUInt32(1, handler->GetSession()->GetBattlenetAccountId());
LoginDatabase.Execute(stmt);
handler->PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED);
}
else
{
- handler->PSendSysMessage("[IP2NATION] Table empty");
- TC_LOG_DEBUG("server.authserver", "[IP2NATION] Table empty");
+ handler->PSendSysMessage("IP2Location] No information");
+ TC_LOG_DEBUG("server.authserver", "IP2Location] No information");
}
}
else if (param == "off")
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index a388ef3b716..2503931d435 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -28,6 +28,7 @@
#include "GroupMgr.h"
#include "InstanceSaveMgr.h"
#include "IpAddress.h"
+#include "IPLocation.h"
#include "Item.h"
#include "Language.h"
#include "LFG.h"
@@ -1697,17 +1698,10 @@ public:
lastIp = fields[4].GetString();
lastLogin = fields[5].GetString();
- uint32 ip = Trinity::Net::address_to_uint(Trinity::Net::make_address_v4(lastIp));
- EndianConvertReverse(ip);
-
- // If ip2nation table is populated, it displays the country
- stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP2NATION_COUNTRY);
- stmt->setUInt32(0, ip);
- if (PreparedQueryResult result2 = LoginDatabase.Query(stmt))
+ if (IpLocationRecord* location = sIPLocation->GetData(lastIp))
{
- Field* fields2 = result2->Fetch();
lastIp.append(" (");
- lastIp.append(fields2[0].GetString());
+ lastIp.append(location->country_name);
lastIp.append(")");
}
}
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 00415506e2e..e6681eea64b 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -208,6 +208,16 @@ SourceDirectory = ""
MySQLExecutable = ""
+#
+# IPLocationFile
+# Description: The path to your IP2Location database CSV file.
+# Example: "C:/Trinity/IP2Location.csv"
+# "/home/trinity/IP2Location.csv"
+# Default: "." - (Current core directory)
+# "" - (Disabled)
+
+IPLocationFile = "."
+
#
###################################################################################################