From 0c6fe1941fcd7fe8ba905201cb879b0dd822f7a3 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Sat, 23 Jun 2018 02:21:59 +0200 Subject: [PATCH] rename files --- sql/base/auth_database.sql | 55 +------- sql/updates/auth/4.3.4/2018_06_23_00_auth.sql | 3 + ...orld_from_335_was_2018_06_17_00_world.sql} | 0 ...orld_from_335_was_2018_06_17_01_world.sql} | 0 ...orld_from_335_was_2018_06_17_03_world.sql} | 0 ...orld_from_335_was_2018_06_17_04_world.sql} | 0 ...orld_from_335_was_2018_06_17_05_world.sql} | 0 ..._from_335_was_2018_06_21_00_world_335.sql} | 2 + ...orld_from_335_was_2018_06_21_01_world.sql} | 0 ..._from_335_was_2018_06_21_02_world_335.sql} | 2 + src/common/IPLocation/IPLocation.cpp | 126 ++++++++++++++++++ src/common/IPLocation/IPLocation.h | 44 ++++++ src/server/authserver/Main.cpp | 4 + src/server/authserver/Server/AuthSession.cpp | 8 +- src/server/authserver/authserver.conf.dist | 10 ++ .../Database/Implementation/LoginDatabase.cpp | 6 +- .../Database/Implementation/LoginDatabase.h | 2 - src/server/game/Server/WorldSocket.cpp | 8 +- src/server/game/World/World.cpp | 4 + src/server/scripts/Commands/cs_account.cpp | 18 +-- .../scripts/Commands/cs_battlenet_account.cpp | 18 +-- src/server/scripts/Commands/cs_misc.cpp | 12 +- src/server/worldserver/worldserver.conf.dist | 10 ++ 23 files changed, 231 insertions(+), 101 deletions(-) create mode 100644 sql/updates/auth/4.3.4/2018_06_23_00_auth.sql rename sql/updates/world/{3.3.5/2018_06_17_00_world.sql => 4.3.4/2018_06_23_00_world_from_335_was_2018_06_17_00_world.sql} (100%) rename sql/updates/world/{3.3.5/2018_06_17_01_world.sql => 4.3.4/2018_06_23_01_world_from_335_was_2018_06_17_01_world.sql} (100%) rename sql/updates/world/{3.3.5/2018_06_17_03_world.sql => 4.3.4/2018_06_23_02_world_from_335_was_2018_06_17_03_world.sql} (100%) rename sql/updates/world/{3.3.5/2018_06_17_04_world.sql => 4.3.4/2018_06_23_03_world_from_335_was_2018_06_17_04_world.sql} (100%) rename sql/updates/world/{3.3.5/2018_06_17_05_world.sql => 4.3.4/2018_06_23_04_world_from_335_was_2018_06_17_05_world.sql} (100%) rename sql/updates/world/{3.3.5/2018_06_21_00_world_335.sql => 4.3.4/2018_06_23_05_world_from_335_was_2018_06_21_00_world_335.sql} (99%) rename sql/updates/world/{3.3.5/2018_06_21_01_world.sql => 4.3.4/2018_06_23_06_world_from_335_was_2018_06_21_01_world.sql} (100%) rename sql/updates/world/{3.3.5/2018_06_21_02_world_335.sql => 4.3.4/2018_06_23_07_world_from_335_was_2018_06_21_02_world_335.sql} (99%) create mode 100644 src/common/IPLocation/IPLocation.cpp create mode 100644 src/common/IPLocation/IPLocation.h 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 = "." + # ###################################################################################################