diff --git a/.travis.yml b/.travis.yml index dec72667e62..4380eeea7bb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ before_install: - sudo apt-get -qq update - sudo apt-get -qq install build-essential libtool gcc-4.8 g++-4.8 make cmake openssl - sudo apt-get -qq install libssl-dev libmysqlclient-dev libmysql++-dev libreadline6-dev zlib1g-dev libbz2-dev libzmq3-dev - - sudo apt-get -qq install libboost1.55-dev libboost-thread1.55-dev libboost-system1.55-dev libboost-program-options1.55-dev + - sudo apt-get -qq install libboost1.55-dev libboost-thread1.55-dev libboost-filesystem1.55-dev libboost-system1.55-dev libboost-program-options1.55-dev libboost-iostreams1.55-dev install: - mysql -uroot -e 'create database test_mysql;' diff --git a/cmake/macros/ConfigureBoost.cmake b/cmake/macros/ConfigureBoost.cmake index 54700a37b6b..190151af155 100644 --- a/cmake/macros/ConfigureBoost.cmake +++ b/cmake/macros/ConfigureBoost.cmake @@ -25,11 +25,36 @@ if(WIN32) add_definitions(-D_WIN32_WINNT=${ver}) endif() -find_package(Boost 1.49 REQUIRED system thread program_options) +find_package(Boost 1.49 REQUIRED system filesystem thread program_options iostreams) add_definitions(-DBOOST_DATE_TIME_NO_LIB) add_definitions(-DBOOST_REGEX_NO_LIB) add_definitions(-DBOOST_CHRONO_NO_LIB) +# Find if Boost was compiled in C++03 mode because it requires -DBOOST_NO_CXX11_SCOPED_ENUMS + +include (CheckCXXSourceCompiles) + +set(CMAKE_REQUIRED_INCLUDES ${Boost_INCLUDE_DIR}) +set(CMAKE_REQUIRED_LIBRARIES ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_IOSTREAMS_LIBRARY}) +set(CMAKE_REQUIRED_FLAGS "-std=c++11") +unset(boost_filesystem_copy_links_without_NO_SCOPED_ENUM CACHE) +check_cxx_source_compiles(" + #include + #include + int main() { boost::filesystem::copy_file(boost::filesystem::path(), boost::filesystem::path()); }" +boost_filesystem_copy_links_without_NO_SCOPED_ENUM) +unset(CMAKE_REQUIRED_INCLUDES CACHE) +unset(CMAKE_REQUIRED_LIBRARIES CACHE) +unset(CMAKE_REQUIRED_FLAGS CACHE) + +if (NOT boost_filesystem_copy_links_without_NO_SCOPED_ENUM) + if (Boost_VERSION LESS 105100) # 1.51 + add_definitions(-DBOOST_NO_SCOPED_ENUMS) + else() + add_definitions(-DBOOST_NO_CXX11_SCOPED_ENUMS) + endif() +endif() + if(Boost_FOUND) include_directories(${Boost_INCLUDE_DIRS}) endif() diff --git a/cmake/macros/FindMySQL.cmake b/cmake/macros/FindMySQL.cmake index 990f4918d6a..6b00510ba42 100644 --- a/cmake/macros/FindMySQL.cmake +++ b/cmake/macros/FindMySQL.cmake @@ -5,6 +5,7 @@ # This module defines # MYSQL_INCLUDE_DIR, where to find mysql.h # MYSQL_LIBRARIES, the libraries to link against to connect to MySQL +# MYSQL_EXECUTABLE, the MySQL executable. # MYSQL_FOUND, if false, you cannot build anything that requires MySQL. # also defined, but not for general use are @@ -182,6 +183,65 @@ else( NOT WIN32 ) set( MYSQL_EXTRA_LIBRARIES "" ) endif( NOT WIN32 ) +if( UNIX ) + find_program(MYSQL_EXECUTABLE mysql + PATHS + ${MYSQL_CONFIG_PREFER_PATH} + /usr/local/mysql/bin/ + /usr/local/bin/ + /usr/bin/ + DOC + "path to your mysql binary." + ) +endif( UNIX ) + +if( WIN32 ) + find_program(MYSQL_EXECUTABLE mysql + PATHS + "C:/Program Files/MySQL/MySQL Server 5.6/bin" + "C:/Program Files/MySQL/MySQL Server 5.6/bin/opt" + "C:/Program Files/MySQL/MySQL Server 5.5/bin" + "C:/Program Files/MySQL/MySQL Server 5.5/bin/opt" + "C:/Program Files/MySQL/MySQL Server 5.1/bin" + "C:/Program Files/MySQL/MySQL Server 5.1/bin/opt" + "C:/Program Files/MySQL/MySQL Server 5.0/bin" + "C:/Program Files/MySQL/MySQL Server 5.0/bin/opt" + "C:/Program Files/MySQL/bin" + "C:/Program Files (x86)/MySQL/MySQL Server 5.6/bin" + "C:/Program Files (x86)/MySQL/MySQL Server 5.6/bin/opt" + "C:/Program Files (x86)/MySQL/MySQL Server 5.5/bin" + "C:/Program Files (x86)/MySQL/MySQL Server 5.5/bin/opt" + "C:/Program Files (x86)/MySQL/MySQL Server 5.1/bin" + "C:/Program Files (x86)/MySQL/MySQL Server 5.1/bin/opt" + "C:/Program Files (x86)/MySQL/MySQL Server 5.0/bin" + "C:/Program Files (x86)/MySQL/MySQL Server 5.0/bin/opt" + "C:/Program Files (x86)/MySQL/bin" + "C:/MySQL/bin/debug" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/bin/opt" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.5;Location]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.5;Location]/bin/opt" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.1;Location]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.1;Location]/bin/opt" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.0;Location]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.0;Location]/bin/opt" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.6;Location]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.6;Location]/bin/opt" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.5;Location]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.5;Location]/bin/opt" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.1;Location]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.1;Location]/bin/opt" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.0;Location]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.0;Location]/bin/opt" + "$ENV{ProgramFiles}/MySQL/*/bin/opt" + "$ENV{SystemDrive}/MySQL/*/bin/opt" + "c:/msys/local/include" + "$ENV{MYSQL_ROOT}/bin" + DOC + "path to your mysql binary." + ) +endif( WIN32 ) + if( MYSQL_LIBRARY ) if( MYSQL_INCLUDE_DIR ) set( MYSQL_FOUND 1 ) @@ -190,7 +250,10 @@ if( MYSQL_LIBRARY ) else( MYSQL_INCLUDE_DIR ) message(FATAL_ERROR "Could not find MySQL headers! Please install the development libraries and headers") endif( MYSQL_INCLUDE_DIR ) - mark_as_advanced( MYSQL_FOUND MYSQL_LIBRARY MYSQL_EXTRA_LIBRARIES MYSQL_INCLUDE_DIR ) + if( MYSQL_EXECUTABLE ) + message(STATUS "Found MySQL executable: ${MYSQL_EXECUTABLE}") + endif( MYSQL_EXECUTABLE ) + mark_as_advanced( MYSQL_FOUND MYSQL_LIBRARY MYSQL_EXTRA_LIBRARIES MYSQL_INCLUDE_DIR MYSQL_EXECUTABLE) else( MYSQL_LIBRARY ) message(FATAL_ERROR "Could not find the MySQL libraries! Please install the development libraries and headers") endif( MYSQL_LIBRARY ) diff --git a/dep/PackageList.txt b/dep/PackageList.txt index a4cbbe2caf9..7f571917080 100644 --- a/dep/PackageList.txt +++ b/dep/PackageList.txt @@ -4,6 +4,10 @@ Boost http://www.boost.org Version: 1.55 +Boost Process (Proposed for boost, but its not an official part of it yet. Used to start child processes.) + http://www.highscore.de/boost/process0.5/ + Version: 0.5 + bzip2 (a freely available, patent free, high-quality data compressor) http://www.bzip.org/ Version: 1.0.6 diff --git a/revision.h.in.cmake b/revision.h.in.cmake index f50c8022062..eab0437c600 100644 --- a/revision.h.in.cmake +++ b/revision.h.in.cmake @@ -3,6 +3,9 @@ #define _HASH "@rev_hash@" #define _DATE "@rev_date@" #define _BRANCH "@rev_branch@" + #define _SOURCE_DIRECTORY "@CMAKE_SOURCE_DIR@" + #define _MYSQL_EXECUTABLE "@MYSQL_EXECUTABLE@" + #define _FULL_DATABASE "TDB_full_335.58_2015_03_21.sql" #define VER_COMPANYNAME_STR "TrinityCore Developers" #define VER_LEGALCOPYRIGHT_STR "(c)2008-2015 TrinityCore" #define VER_FILEVERSION 0,0,0 diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql index 85d0a8e10f3..86f21acad26 100644 --- a/sql/base/auth_database.sql +++ b/sql/base/auth_database.sql @@ -1,8 +1,8 @@ --- MySQL dump 10.15 Distrib 10.0.15-MariaDB, for Win64 (x86) +-- MySQL dump 10.13 Distrib 5.6.9-rc, for Win64 (x86_64) -- -- Host: localhost Database: auth_4x -- ------------------------------------------------------ --- Server version 10.0.15-MariaDB +-- Server version 5.6.9-rc /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -509,7 +509,7 @@ CREATE TABLE `rbac_default_permissions` ( LOCK TABLES `rbac_default_permissions` WRITE; /*!40000 ALTER TABLE `rbac_default_permissions` DISABLE KEYS */; -INSERT INTO `rbac_default_permissions` VALUES (0,195,-1),(1,194,-1),(2,193,-1),(3,192,-1); +INSERT INTO `rbac_default_permissions` VALUES (3,192,-1),(2,193,-1),(1,194,-1),(0,195,-1); /*!40000 ALTER TABLE `rbac_default_permissions` ENABLE KEYS */; UNLOCK TABLES; @@ -627,6 +627,57 @@ INSERT INTO `realmlist` VALUES (1,'Trinity','127.0.0.1','127.0.0.1','255.255.255 /*!40000 ALTER TABLE `realmlist` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `updates` +-- + +DROP TABLE IF EXISTS `updates`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `updates` ( + `name` varchar(200) NOT NULL COMMENT 'filename with extension of the update.', + `hash` char(40) DEFAULT '' COMMENT 'sha1 hash of the sql file.', + `state` enum('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if an update is released or archived.', + `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'timestamp when the query was applied.', + `speed` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'time the query takes to apply in ms.', + PRIMARY KEY (`name`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='List of all applied updates in this database.'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `updates` +-- + +LOCK TABLES `updates` WRITE; +/*!40000 ALTER TABLE `updates` DISABLE KEYS */; +INSERT INTO `updates` VALUES ('2014_11_10_00_auth.sql','0E3CB119442D09DD88E967015319BBC8DAFBBFE0','ARCHIVED','2015-03-21 21:44:12',0),('2014_11_10_01_auth.sql','327E77A1DA3546D5275AB249915DD57EDD6FDD3D','ARCHIVED','2015-03-21 21:44:12',0),('2014_12_10_00_auth.sql','821703A96D80F9080074852B5A46E2909C9562EA','ARCHIVED','2015-03-21 21:44:12',0),('2014_12_21_00_auth.sql','CE2E5D2CD82E79C25294539ADED27A1429105B43','ARCHIVED','2015-03-21 21:44:12',0),('2015_03_20_00_auth.sql','E8C5B74BB45F0F35DEC182C72BACF435C7066FB0','ARCHIVED','2015-03-21 21:44:12',0),('2015_03_20_01_auth.sql','862961815354DA2746F5F71FBC8155F57CBE75AB','ARCHIVED','2015-03-21 21:44:12',0),('2015_03_20_02_auth.sql','33E4F94086590768EF5D4855DD43D7DE7C06ADA4','ARCHIVED','2015-03-21 21:44:51',0); +/*!40000 ALTER TABLE `updates` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `updates_include` +-- + +DROP TABLE IF EXISTS `updates_include`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `updates_include` ( + `path` varchar(200) NOT NULL COMMENT 'directory to include. $ means relative to the source directory.', + `state` enum('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if the directory contains released or archived updates.', + PRIMARY KEY (`path`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='List of directories where we want to include sql updates.'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `updates_include` +-- + +LOCK TABLES `updates_include` WRITE; +/*!40000 ALTER TABLE `updates_include` DISABLE KEYS */; +INSERT INTO `updates_include` VALUES ('$/sql/updates/auth','RELEASED'),('$/sql/custom/auth','RELEASED'),('$/sql/old/3.3.5a/auth','ARCHIVED'); +/*!40000 ALTER TABLE `updates_include` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `uptime` -- @@ -662,4 +713,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2014-12-21 20:42:33 +-- Dump completed on 2015-03-21 21:48:22 diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index 71f7287f67a..6ab13feafbe 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -1,8 +1,8 @@ --- MySQL dump 10.13 Distrib 5.5.40, for debian-linux-gnu (x86_64) +-- MySQL dump 10.13 Distrib 5.6.9-rc, for Win64 (x86_64) -- -- Host: localhost Database: characters_4x -- ------------------------------------------------------ --- Server version 5.5.40-0ubuntu0.14.04.1 +-- Server version 5.6.9-rc /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -2738,6 +2738,57 @@ LOCK TABLES `reserved_name` WRITE; /*!40000 ALTER TABLE `reserved_name` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `updates` +-- + +DROP TABLE IF EXISTS `updates`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `updates` ( + `name` varchar(200) NOT NULL COMMENT 'filename with extension of the update.', + `hash` char(40) DEFAULT '' COMMENT 'sha1 hash of the sql file.', + `state` enum('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if an update is released or archived.', + `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'timestamp when the query was applied.', + `speed` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'time the query takes to apply in ms.', + PRIMARY KEY (`name`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='List of all applied updates in this database.'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `updates` +-- + +LOCK TABLES `updates` WRITE; +/*!40000 ALTER TABLE `updates` DISABLE KEYS */; +INSERT INTO `updates` VALUES ('2015_03_20_00_characters.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 21:44:15',0),('2015_03_20_01_characters.sql','894F08B70449A5481FFAF394EE5571D7FC4D8A3A','ARCHIVED','2015-03-21 21:44:15',0),('2015_03_20_02_characters.sql','97D7BE0CAADC79F3F11B9FD296B8C6CD40FE593B','ARCHIVED','2015-03-21 21:44:51',0); +/*!40000 ALTER TABLE `updates` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `updates_include` +-- + +DROP TABLE IF EXISTS `updates_include`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `updates_include` ( + `path` varchar(200) NOT NULL COMMENT 'directory to include. $ means relative to the source directory.', + `state` enum('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if the directory contains released or archived updates.', + PRIMARY KEY (`path`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='List of directories where we want to include sql updates.'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `updates_include` +-- + +LOCK TABLES `updates_include` WRITE; +/*!40000 ALTER TABLE `updates_include` DISABLE KEYS */; +INSERT INTO `updates_include` VALUES ('$/sql/updates/characters','RELEASED'),('$/sql/custom/characters','RELEASED'),('$/sql/old/3.3.5a/characters','ARCHIVED'); +/*!40000 ALTER TABLE `updates_include` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `warden_action` -- @@ -2795,4 +2846,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2014-10-18 18:02:06 +-- Dump completed on 2015-03-21 21:48:11 diff --git a/sql/base/dev/world_database.sql b/sql/base/dev/world_database.sql index 1a9e58d0569..818a311ff7a 100644 --- a/sql/base/dev/world_database.sql +++ b/sql/base/dev/world_database.sql @@ -3715,6 +3715,37 @@ CREATE TABLE `trinity_string` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `updates` +-- + +DROP TABLE IF EXISTS `updates`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `updates` ( + `name` varchar(200) NOT NULL COMMENT 'filename with extension of the update.', + `hash` char(40) DEFAULT '' COMMENT 'sha1 hash of the sql file.', + `state` enum('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if an update is released or archived.', + `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'timestamp when the query was applied.', + `speed` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'time the query takes to apply in ms.', + PRIMARY KEY (`name`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='List of all applied updates in this database.'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `updates_include` +-- + +DROP TABLE IF EXISTS `updates_include`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `updates_include` ( + `path` varchar(200) NOT NULL COMMENT 'directory to include. $ means relative to the source directory.', + `state` enum('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if the directory contains released or archived updates.', + PRIMARY KEY (`path`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='List of directories where we want to include sql updates.'; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `vehicle_accessory` -- diff --git a/sql/custom/auth/.gitignore b/sql/custom/auth/.gitignore new file mode 100644 index 00000000000..d1b811b7de5 --- /dev/null +++ b/sql/custom/auth/.gitignore @@ -0,0 +1 @@ +*.sql diff --git a/sql/custom/characters/.gitignore b/sql/custom/characters/.gitignore new file mode 100644 index 00000000000..d1b811b7de5 --- /dev/null +++ b/sql/custom/characters/.gitignore @@ -0,0 +1 @@ +*.sql diff --git a/sql/custom/world/.gitignore b/sql/custom/world/.gitignore new file mode 100644 index 00000000000..d1b811b7de5 --- /dev/null +++ b/sql/custom/world/.gitignore @@ -0,0 +1 @@ +*.sql diff --git a/sql/updates/auth/2014_11_10_00_auth.sql b/sql/old/3.3.5a/auth/57_2014_10_19/2014_11_10_00_auth.sql similarity index 100% rename from sql/updates/auth/2014_11_10_00_auth.sql rename to sql/old/3.3.5a/auth/57_2014_10_19/2014_11_10_00_auth.sql diff --git a/sql/updates/auth/2014_11_10_01_auth.sql b/sql/old/3.3.5a/auth/57_2014_10_19/2014_11_10_01_auth.sql similarity index 100% rename from sql/updates/auth/2014_11_10_01_auth.sql rename to sql/old/3.3.5a/auth/57_2014_10_19/2014_11_10_01_auth.sql diff --git a/sql/updates/auth/2014_12_10_00_auth.sql b/sql/old/3.3.5a/auth/57_2014_10_19/2014_12_10_00_auth.sql similarity index 100% rename from sql/updates/auth/2014_12_10_00_auth.sql rename to sql/old/3.3.5a/auth/57_2014_10_19/2014_12_10_00_auth.sql diff --git a/sql/updates/auth/2014_12_21_00_auth.sql b/sql/old/3.3.5a/auth/57_2014_10_19/2014_12_21_00_auth.sql similarity index 100% rename from sql/updates/auth/2014_12_21_00_auth.sql rename to sql/old/3.3.5a/auth/57_2014_10_19/2014_12_21_00_auth.sql diff --git a/sql/old/3.3.5a/auth/57_2014_10_19/2015_03_20_00_auth.sql b/sql/old/3.3.5a/auth/57_2014_10_19/2015_03_20_00_auth.sql new file mode 100644 index 00000000000..69e4d38f0d2 --- /dev/null +++ b/sql/old/3.3.5a/auth/57_2014_10_19/2015_03_20_00_auth.sql @@ -0,0 +1,36 @@ +-- Updates base tables +DROP TABLE IF EXISTS `updates`; +CREATE TABLE `updates` ( + `name` VARCHAR(200) NOT NULL COMMENT 'filename with extension of the update.', + `hash` CHAR(40) NULL DEFAULT '' COMMENT 'sha1 hash of the sql file.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if an update is released or archived.', + `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'timestamp when the query was applied.', + `speed` INT(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'time the query takes to apply in ms.', + PRIMARY KEY (`name`) +) +COMMENT='List of all applied updates in this database.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; + +DROP TABLE IF EXISTS `updates_include`; +CREATE TABLE `updates_include` ( + `path` VARCHAR(200) NOT NULL COMMENT 'directory to include. $ means relative to the source directory.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if the directory contains released or archived updates.', + PRIMARY KEY (`path`) +) +COMMENT='List of directories where we want to include sql updates.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; + +-- Auth database update data +TRUNCATE TABLE `updates_include`; +INSERT INTO `updates_include` (`path`, `state`) VALUES +('$/sql/updates/auth', 'RELEASED'), +('$/sql/custom/auth', 'RELEASED'), +('$/sql/old/3.3.5a/auth', 'ARCHIVED'); + +INSERT IGNORE INTO `updates` (`name`, `hash`) VALUES +('2015_03_20_00_auth.sql', ''), +('2015_03_20_01_auth.sql', ''), +('2015_03_20_02_auth.sql', ''); + diff --git a/sql/old/3.3.5a/auth/57_2014_10_19/2015_03_20_01_auth.sql b/sql/old/3.3.5a/auth/57_2014_10_19/2015_03_20_01_auth.sql new file mode 100644 index 00000000000..970243fd278 --- /dev/null +++ b/sql/old/3.3.5a/auth/57_2014_10_19/2015_03_20_01_auth.sql @@ -0,0 +1,6 @@ +-- Auth database update data +TRUNCATE TABLE `updates_include`; +INSERT INTO `updates_include` (`path`, `state`) VALUES +('$/sql/updates/auth', 'RELEASED'), +('$/sql/custom/auth', 'RELEASED'), +('$/sql/old/3.3.5a/auth', 'ARCHIVED'); diff --git a/sql/old/3.3.5a/auth/57_2014_10_19/2015_03_20_02_auth.sql b/sql/old/3.3.5a/auth/57_2014_10_19/2015_03_20_02_auth.sql new file mode 100644 index 00000000000..71abadebf60 --- /dev/null +++ b/sql/old/3.3.5a/auth/57_2014_10_19/2015_03_20_02_auth.sql @@ -0,0 +1,8 @@ +INSERT IGNORE INTO `updates` (`name`, `hash`) VALUES +('2014_11_10_00_auth.sql', '0E3CB119442D09DD88E967015319BBC8DAFBBFE0'), +('2014_11_10_01_auth.sql', '327E77A1DA3546D5275AB249915DD57EDD6FDD3D'), +('2014_12_10_00_auth.sql', '821703A96D80F9080074852B5A46E2909C9562EA'), +('2014_12_21_00_auth.sql', 'CE2E5D2CD82E79C25294539ADED27A1429105B43'), +('2015_03_20_00_auth.sql', 'E8C5B74BB45F0F35DEC182C72BACF435C7066FB0'), +('2015_03_20_01_auth.sql', '862961815354DA2746F5F71FBC8155F57CBE75AB'), +('2015_03_20_02_auth.sql', ''); diff --git a/sql/old/3.3.5a/characters/57_2014_10_19/2015_03_20_00_characters.sql b/sql/old/3.3.5a/characters/57_2014_10_19/2015_03_20_00_characters.sql new file mode 100644 index 00000000000..05c120274da --- /dev/null +++ b/sql/old/3.3.5a/characters/57_2014_10_19/2015_03_20_00_characters.sql @@ -0,0 +1,23 @@ +-- Updates base tables +DROP TABLE IF EXISTS `updates`; +CREATE TABLE `updates` ( + `name` VARCHAR(200) NOT NULL COMMENT 'filename with extension of the update.', + `hash` CHAR(40) NULL DEFAULT '' COMMENT 'sha1 hash of the sql file.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if an update is released or archived.', + `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'timestamp when the query was applied.', + `speed` INT(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'time the query takes to apply in ms.', + PRIMARY KEY (`name`) +) +COMMENT='List of all applied updates in this database.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; + +DROP TABLE IF EXISTS `updates_include`; +CREATE TABLE `updates_include` ( + `path` VARCHAR(200) NOT NULL COMMENT 'directory to include. $ means relative to the source directory.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if the directory contains released or archived updates.', + PRIMARY KEY (`path`) +) +COMMENT='List of directories where we want to include sql updates.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; diff --git a/sql/old/3.3.5a/characters/57_2014_10_19/2015_03_20_01_characters.sql b/sql/old/3.3.5a/characters/57_2014_10_19/2015_03_20_01_characters.sql new file mode 100644 index 00000000000..2655d4884a5 --- /dev/null +++ b/sql/old/3.3.5a/characters/57_2014_10_19/2015_03_20_01_characters.sql @@ -0,0 +1,6 @@ +-- Characters database update data +TRUNCATE TABLE `updates_include`; +INSERT INTO `updates_include` (`path`, `state`) VALUES +('$/sql/updates/characters', 'RELEASED'), +('$/sql/custom/characters', 'RELEASED'), +('$/sql/old/3.3.5a/characters', 'ARCHIVED'); diff --git a/sql/old/3.3.5a/characters/57_2014_10_19/2015_03_20_02_characters.sql b/sql/old/3.3.5a/characters/57_2014_10_19/2015_03_20_02_characters.sql new file mode 100644 index 00000000000..5fcc42d4614 --- /dev/null +++ b/sql/old/3.3.5a/characters/57_2014_10_19/2015_03_20_02_characters.sql @@ -0,0 +1,4 @@ +INSERT IGNORE INTO `updates` (`name`, `hash`) VALUES +('2015_03_20_00_characters.sql', 'B761760804EA73BD297F296C5C1919687DF7191C'), +('2015_03_20_01_characters.sql', '894F08B70449A5481FFAF394EE5571D7FC4D8A3A'), +('2015_03_20_02_characters.sql', ''); diff --git a/sql/updates/world/2014_10_19_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_19_00_world.sql similarity index 100% rename from sql/updates/world/2014_10_19_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_19_00_world.sql diff --git a/sql/updates/world/2014_10_19_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_19_01_world.sql similarity index 100% rename from sql/updates/world/2014_10_19_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_19_01_world.sql diff --git a/sql/updates/world/2014_10_20_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_20_00_world.sql similarity index 100% rename from sql/updates/world/2014_10_20_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_20_00_world.sql diff --git a/sql/updates/world/2014_10_21_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_21_00_world.sql similarity index 100% rename from sql/updates/world/2014_10_21_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_21_00_world.sql diff --git a/sql/updates/world/2014_10_22_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_22_00_world.sql similarity index 100% rename from sql/updates/world/2014_10_22_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_22_00_world.sql diff --git a/sql/updates/world/2014_10_23_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_23_00_world.sql similarity index 100% rename from sql/updates/world/2014_10_23_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_23_00_world.sql diff --git a/sql/updates/world/2014_10_23_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_23_01_world.sql similarity index 100% rename from sql/updates/world/2014_10_23_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_23_01_world.sql diff --git a/sql/updates/world/2014_10_24_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_24_00_world.sql similarity index 100% rename from sql/updates/world/2014_10_24_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_24_00_world.sql diff --git a/sql/updates/world/2014_10_24_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_24_01_world.sql similarity index 100% rename from sql/updates/world/2014_10_24_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_24_01_world.sql diff --git a/sql/updates/world/2014_10_26_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_26_00_world.sql similarity index 100% rename from sql/updates/world/2014_10_26_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_26_00_world.sql diff --git a/sql/updates/world/2014_10_27_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_27_00_world.sql similarity index 100% rename from sql/updates/world/2014_10_27_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_27_00_world.sql diff --git a/sql/updates/world/2014_10_27_01_world_335.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_27_01_world_335.sql similarity index 100% rename from sql/updates/world/2014_10_27_01_world_335.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_27_01_world_335.sql diff --git a/sql/updates/world/2014_10_27_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_27_02_world.sql similarity index 100% rename from sql/updates/world/2014_10_27_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_27_02_world.sql diff --git a/sql/updates/world/2014_10_28_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_28_00_world.sql similarity index 100% rename from sql/updates/world/2014_10_28_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_28_00_world.sql diff --git a/sql/updates/world/2014_10_29_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_29_00_world.sql similarity index 100% rename from sql/updates/world/2014_10_29_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_29_00_world.sql diff --git a/sql/updates/world/2014_10_30_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_30_00_world.sql similarity index 100% rename from sql/updates/world/2014_10_30_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_30_00_world.sql diff --git a/sql/updates/world/2014_10_30_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_10_30_02_world.sql similarity index 100% rename from sql/updates/world/2014_10_30_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_10_30_02_world.sql diff --git a/sql/updates/world/2014_11_01_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_01_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_01_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_01_00_world.sql diff --git a/sql/updates/world/2014_11_01_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_01_01_world.sql similarity index 100% rename from sql/updates/world/2014_11_01_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_01_01_world.sql diff --git a/sql/updates/world/2014_11_01_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_01_02_world.sql similarity index 100% rename from sql/updates/world/2014_11_01_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_01_02_world.sql diff --git a/sql/updates/world/2014_11_01_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_01_03_world.sql similarity index 100% rename from sql/updates/world/2014_11_01_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_01_03_world.sql diff --git a/sql/updates/world/2014_11_02_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_02_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_02_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_02_00_world.sql diff --git a/sql/updates/world/2014_11_02_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_02_01_world.sql similarity index 100% rename from sql/updates/world/2014_11_02_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_02_01_world.sql diff --git a/sql/updates/world/2014_11_04_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_04_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_04_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_04_00_world.sql diff --git a/sql/updates/world/2014_11_05_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_05_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_05_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_05_00_world.sql diff --git a/sql/updates/world/2014_11_07_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_07_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_07_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_07_00_world.sql diff --git a/sql/updates/world/2014_11_07_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_07_01_world.sql similarity index 100% rename from sql/updates/world/2014_11_07_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_07_01_world.sql diff --git a/sql/updates/world/2014_11_07_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_07_02_world.sql similarity index 100% rename from sql/updates/world/2014_11_07_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_07_02_world.sql diff --git a/sql/updates/world/2014_11_07_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_07_03_world.sql similarity index 100% rename from sql/updates/world/2014_11_07_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_07_03_world.sql diff --git a/sql/updates/world/2014_11_08_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_08_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_08_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_08_00_world.sql diff --git a/sql/updates/world/2014_11_09_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_09_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_09_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_09_00_world.sql diff --git a/sql/updates/world/2014_11_10_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_10_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_10_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_10_00_world.sql diff --git a/sql/updates/world/2014_11_10_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_10_01_world.sql similarity index 100% rename from sql/updates/world/2014_11_10_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_10_01_world.sql diff --git a/sql/updates/world/2014_11_10_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_10_02_world.sql similarity index 100% rename from sql/updates/world/2014_11_10_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_10_02_world.sql diff --git a/sql/updates/world/2014_11_10_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_10_03_world.sql similarity index 100% rename from sql/updates/world/2014_11_10_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_10_03_world.sql diff --git a/sql/updates/world/2014_11_10_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_10_04_world.sql similarity index 100% rename from sql/updates/world/2014_11_10_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_10_04_world.sql diff --git a/sql/updates/world/2014_11_10_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_10_05_world.sql similarity index 100% rename from sql/updates/world/2014_11_10_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_10_05_world.sql diff --git a/sql/updates/world/2014_11_11_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_11_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_11_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_11_00_world.sql diff --git a/sql/updates/world/2014_11_11_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_11_01_world.sql similarity index 100% rename from sql/updates/world/2014_11_11_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_11_01_world.sql diff --git a/sql/updates/world/2014_11_13_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_13_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_13_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_13_00_world.sql diff --git a/sql/updates/world/2014_11_16_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_16_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_16_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_16_00_world.sql diff --git a/sql/updates/world/2014_11_17_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_17_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_17_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_17_00_world.sql diff --git a/sql/updates/world/2014_11_19_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_19_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_19_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_19_00_world.sql diff --git a/sql/updates/world/2014_11_19_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_19_01_world.sql similarity index 100% rename from sql/updates/world/2014_11_19_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_19_01_world.sql diff --git a/sql/updates/world/2014_11_19_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_19_02_world.sql similarity index 100% rename from sql/updates/world/2014_11_19_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_19_02_world.sql diff --git a/sql/updates/world/2014_11_20_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_20_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_20_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_20_00_world.sql diff --git a/sql/updates/world/2014_11_20_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_20_01_world.sql similarity index 100% rename from sql/updates/world/2014_11_20_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_20_01_world.sql diff --git a/sql/updates/world/2014_11_20_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_20_02_world.sql similarity index 100% rename from sql/updates/world/2014_11_20_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_20_02_world.sql diff --git a/sql/updates/world/2014_11_20_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_20_03_world.sql similarity index 100% rename from sql/updates/world/2014_11_20_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_20_03_world.sql diff --git a/sql/updates/world/2014_11_20_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_20_04_world.sql similarity index 100% rename from sql/updates/world/2014_11_20_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_20_04_world.sql diff --git a/sql/updates/world/2014_11_20_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_20_05_world.sql similarity index 100% rename from sql/updates/world/2014_11_20_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_20_05_world.sql diff --git a/sql/updates/world/2014_11_21_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_21_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_21_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_21_00_world.sql diff --git a/sql/updates/world/2014_11_21_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_21_01_world.sql similarity index 100% rename from sql/updates/world/2014_11_21_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_21_01_world.sql diff --git a/sql/updates/world/2014_11_21_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_21_02_world.sql similarity index 100% rename from sql/updates/world/2014_11_21_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_21_02_world.sql diff --git a/sql/updates/world/2014_11_22_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_22_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_22_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_22_00_world.sql diff --git a/sql/updates/world/2014_11_23_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_23_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_23_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_23_00_world.sql diff --git a/sql/updates/world/2014_11_23_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_23_01_world.sql similarity index 100% rename from sql/updates/world/2014_11_23_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_23_01_world.sql diff --git a/sql/updates/world/2014_11_23_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_23_02_world.sql similarity index 100% rename from sql/updates/world/2014_11_23_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_23_02_world.sql diff --git a/sql/updates/world/2014_11_23_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_23_03_world.sql similarity index 100% rename from sql/updates/world/2014_11_23_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_23_03_world.sql diff --git a/sql/updates/world/2014_11_23_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_23_04_world.sql similarity index 100% rename from sql/updates/world/2014_11_23_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_23_04_world.sql diff --git a/sql/updates/world/2014_11_24_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_24_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_24_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_24_00_world.sql diff --git a/sql/updates/world/2014_11_24_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_24_01_world.sql similarity index 100% rename from sql/updates/world/2014_11_24_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_24_01_world.sql diff --git a/sql/updates/world/2014_11_24_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_24_02_world.sql similarity index 100% rename from sql/updates/world/2014_11_24_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_24_02_world.sql diff --git a/sql/updates/world/2014_11_24_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_24_03_world.sql similarity index 100% rename from sql/updates/world/2014_11_24_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_24_03_world.sql diff --git a/sql/updates/world/2014_11_24_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_24_04_world.sql similarity index 100% rename from sql/updates/world/2014_11_24_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_24_04_world.sql diff --git a/sql/updates/world/2014_11_25_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_25_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_25_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_25_00_world.sql diff --git a/sql/updates/world/2014_11_25_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_25_01_world.sql similarity index 100% rename from sql/updates/world/2014_11_25_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_25_01_world.sql diff --git a/sql/updates/world/2014_11_26_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_26_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_26_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_26_00_world.sql diff --git a/sql/updates/world/2014_11_27_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_27_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_27_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_27_00_world.sql diff --git a/sql/updates/world/2014_11_27_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_27_01_world.sql similarity index 100% rename from sql/updates/world/2014_11_27_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_27_01_world.sql diff --git a/sql/updates/world/2014_11_28_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_28_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_28_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_28_00_world.sql diff --git a/sql/updates/world/2014_11_28_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_28_01_world.sql similarity index 100% rename from sql/updates/world/2014_11_28_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_28_01_world.sql diff --git a/sql/updates/world/2014_11_29_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_11_29_00_world.sql similarity index 100% rename from sql/updates/world/2014_11_29_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_11_29_00_world.sql diff --git a/sql/updates/world/2014_12_02_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_02_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_02_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_02_00_world.sql diff --git a/sql/updates/world/2014_12_03_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_03_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_03_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_03_00_world.sql diff --git a/sql/updates/world/2014_12_04_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_04_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_04_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_04_00_world.sql diff --git a/sql/updates/world/2014_12_05_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_05_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_05_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_05_00_world.sql diff --git a/sql/updates/world/2014_12_05_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_05_01_world.sql similarity index 100% rename from sql/updates/world/2014_12_05_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_05_01_world.sql diff --git a/sql/updates/world/2014_12_09_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_09_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_09_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_09_00_world.sql diff --git a/sql/updates/world/2014_12_09_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_09_01_world.sql similarity index 100% rename from sql/updates/world/2014_12_09_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_09_01_world.sql diff --git a/sql/updates/world/2014_12_09_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_09_02_world.sql similarity index 100% rename from sql/updates/world/2014_12_09_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_09_02_world.sql diff --git a/sql/updates/world/2014_12_09_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_09_03_world.sql similarity index 100% rename from sql/updates/world/2014_12_09_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_09_03_world.sql diff --git a/sql/updates/world/2014_12_09_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_09_04_world.sql similarity index 100% rename from sql/updates/world/2014_12_09_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_09_04_world.sql diff --git a/sql/updates/world/2014_12_11_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_11_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_11_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_11_00_world.sql diff --git a/sql/updates/world/2014_12_11_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_11_01_world.sql similarity index 100% rename from sql/updates/world/2014_12_11_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_11_01_world.sql diff --git a/sql/updates/world/2014_12_12_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_12_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_12_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_12_00_world.sql diff --git a/sql/updates/world/2014_12_12_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_12_01_world.sql similarity index 100% rename from sql/updates/world/2014_12_12_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_12_01_world.sql diff --git a/sql/updates/world/2014_12_13_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_13_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_13_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_13_00_world.sql diff --git a/sql/updates/world/2014_12_14_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_14_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_14_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_14_00_world.sql diff --git a/sql/updates/world/2014_12_14_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_14_01_world.sql similarity index 100% rename from sql/updates/world/2014_12_14_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_14_01_world.sql diff --git a/sql/updates/world/2014_12_14_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_14_02_world.sql similarity index 100% rename from sql/updates/world/2014_12_14_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_14_02_world.sql diff --git a/sql/updates/world/2014_12_15_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_15_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_15_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_15_00_world.sql diff --git a/sql/updates/world/2014_12_16_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_16_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_16_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_16_00_world.sql diff --git a/sql/updates/world/2014_12_17_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_17_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_17_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_17_00_world.sql diff --git a/sql/updates/world/2014_12_18_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_18_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_18_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_18_00_world.sql diff --git a/sql/updates/world/2014_12_21_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_21_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_21_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_21_00_world.sql diff --git a/sql/updates/world/2014_12_22_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_22_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_22_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_22_00_world.sql diff --git a/sql/updates/world/2014_12_26_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_26_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_26_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_26_00_world.sql diff --git a/sql/updates/world/2014_12_26_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_26_01_world.sql similarity index 100% rename from sql/updates/world/2014_12_26_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_26_01_world.sql diff --git a/sql/updates/world/2014_12_27_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_27_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_00_world.sql diff --git a/sql/updates/world/2014_12_27_01_world_335.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_01_world_335.sql similarity index 100% rename from sql/updates/world/2014_12_27_01_world_335.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_01_world_335.sql diff --git a/sql/updates/world/2014_12_27_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_02_world.sql similarity index 100% rename from sql/updates/world/2014_12_27_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_02_world.sql diff --git a/sql/updates/world/2014_12_27_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_03_world.sql similarity index 100% rename from sql/updates/world/2014_12_27_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_03_world.sql diff --git a/sql/updates/world/2014_12_27_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_04_world.sql similarity index 100% rename from sql/updates/world/2014_12_27_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_04_world.sql diff --git a/sql/updates/world/2014_12_27_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_05_world.sql similarity index 100% rename from sql/updates/world/2014_12_27_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_05_world.sql diff --git a/sql/updates/world/2014_12_27_06_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_06_world.sql similarity index 100% rename from sql/updates/world/2014_12_27_06_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_06_world.sql diff --git a/sql/updates/world/2014_12_27_07_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_07_world.sql similarity index 100% rename from sql/updates/world/2014_12_27_07_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_07_world.sql diff --git a/sql/updates/world/2014_12_27_08_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_08_world.sql similarity index 100% rename from sql/updates/world/2014_12_27_08_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_08_world.sql diff --git a/sql/updates/world/2014_12_27_09_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_09_world.sql similarity index 100% rename from sql/updates/world/2014_12_27_09_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_09_world.sql diff --git a/sql/updates/world/2014_12_27_10_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_10_world.sql similarity index 100% rename from sql/updates/world/2014_12_27_10_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_10_world.sql diff --git a/sql/updates/world/2014_12_27_11_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_11_world.sql similarity index 100% rename from sql/updates/world/2014_12_27_11_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_11_world.sql diff --git a/sql/updates/world/2014_12_27_12_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_12_world.sql similarity index 100% rename from sql/updates/world/2014_12_27_12_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_27_12_world.sql diff --git a/sql/updates/world/2014_12_28_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_28_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_28_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_28_00_world.sql diff --git a/sql/updates/world/2014_12_28_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_28_01_world.sql similarity index 100% rename from sql/updates/world/2014_12_28_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_28_01_world.sql diff --git a/sql/updates/world/2014_12_28_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_28_02_world.sql similarity index 100% rename from sql/updates/world/2014_12_28_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_28_02_world.sql diff --git a/sql/updates/world/2014_12_28_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_28_03_world.sql similarity index 100% rename from sql/updates/world/2014_12_28_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_28_03_world.sql diff --git a/sql/updates/world/2014_12_28_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_28_04_world.sql similarity index 100% rename from sql/updates/world/2014_12_28_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_28_04_world.sql diff --git a/sql/updates/world/2014_12_28_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_28_05_world.sql similarity index 100% rename from sql/updates/world/2014_12_28_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_28_05_world.sql diff --git a/sql/updates/world/2014_12_29_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_29_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_29_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_29_00_world.sql diff --git a/sql/updates/world/2014_12_29_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_29_01_world.sql similarity index 100% rename from sql/updates/world/2014_12_29_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_29_01_world.sql diff --git a/sql/updates/world/2014_12_29_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_29_02_world.sql similarity index 100% rename from sql/updates/world/2014_12_29_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_29_02_world.sql diff --git a/sql/updates/world/2014_12_30_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_30_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_30_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_30_00_world.sql diff --git a/sql/updates/world/2014_12_30_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_30_01_world.sql similarity index 100% rename from sql/updates/world/2014_12_30_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_30_01_world.sql diff --git a/sql/updates/world/2014_12_31_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2014_12_31_00_world.sql similarity index 100% rename from sql/updates/world/2014_12_31_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2014_12_31_00_world.sql diff --git a/sql/updates/world/2015_01_01_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_01_00_world.sql similarity index 100% rename from sql/updates/world/2015_01_01_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_01_00_world.sql diff --git a/sql/updates/world/2015_01_07_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_07_00_world.sql similarity index 100% rename from sql/updates/world/2015_01_07_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_07_00_world.sql diff --git a/sql/updates/world/2015_01_08_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_08_00_world.sql similarity index 100% rename from sql/updates/world/2015_01_08_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_08_00_world.sql diff --git a/sql/updates/world/2015_01_09_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_09_00_world.sql similarity index 100% rename from sql/updates/world/2015_01_09_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_09_00_world.sql diff --git a/sql/updates/world/2015_01_09_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_09_01_world.sql similarity index 100% rename from sql/updates/world/2015_01_09_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_09_01_world.sql diff --git a/sql/updates/world/2015_01_11_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_11_00_world.sql similarity index 100% rename from sql/updates/world/2015_01_11_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_11_00_world.sql diff --git a/sql/updates/world/2015_01_11_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_11_01_world.sql similarity index 100% rename from sql/updates/world/2015_01_11_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_11_01_world.sql diff --git a/sql/updates/world/2015_01_12_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_12_00_world.sql similarity index 100% rename from sql/updates/world/2015_01_12_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_12_00_world.sql diff --git a/sql/updates/world/2015_01_12_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_12_01_world.sql similarity index 100% rename from sql/updates/world/2015_01_12_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_12_01_world.sql diff --git a/sql/updates/world/2015_01_12_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_12_02_world.sql similarity index 100% rename from sql/updates/world/2015_01_12_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_12_02_world.sql diff --git a/sql/updates/world/2015_01_16_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_16_00_world.sql similarity index 100% rename from sql/updates/world/2015_01_16_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_16_00_world.sql diff --git a/sql/updates/world/2015_01_17_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_17_00_world.sql similarity index 100% rename from sql/updates/world/2015_01_17_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_17_00_world.sql diff --git a/sql/updates/world/2015_01_18_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_18_00_world.sql similarity index 100% rename from sql/updates/world/2015_01_18_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_18_00_world.sql diff --git a/sql/updates/world/2015_01_21_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_21_00_world.sql similarity index 100% rename from sql/updates/world/2015_01_21_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_21_00_world.sql diff --git a/sql/updates/world/2015_01_22_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_22_00_world.sql similarity index 100% rename from sql/updates/world/2015_01_22_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_22_00_world.sql diff --git a/sql/updates/world/2015_01_25_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_25_00_world.sql similarity index 100% rename from sql/updates/world/2015_01_25_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_25_00_world.sql diff --git a/sql/updates/world/2015_01_27_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_27_00_world.sql similarity index 100% rename from sql/updates/world/2015_01_27_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_27_00_world.sql diff --git a/sql/updates/world/2015_01_30_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_30_00_world.sql similarity index 100% rename from sql/updates/world/2015_01_30_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_30_00_world.sql diff --git a/sql/updates/world/2015_01_31_00_335.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_01_31_00_335.sql similarity index 100% rename from sql/updates/world/2015_01_31_00_335.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_01_31_00_335.sql diff --git a/sql/updates/world/2015_02_02_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_02_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_02_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_02_00_world.sql diff --git a/sql/updates/world/2015_02_05_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_05_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_05_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_05_00_world.sql diff --git a/sql/updates/world/2015_02_06_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_06_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_00_world.sql diff --git a/sql/updates/world/2015_02_06_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_01_world.sql similarity index 100% rename from sql/updates/world/2015_02_06_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_01_world.sql diff --git a/sql/updates/world/2015_02_06_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_02_world.sql similarity index 100% rename from sql/updates/world/2015_02_06_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_02_world.sql diff --git a/sql/updates/world/2015_02_06_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_03_world.sql similarity index 100% rename from sql/updates/world/2015_02_06_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_03_world.sql diff --git a/sql/updates/world/2015_02_06_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_04_world.sql similarity index 100% rename from sql/updates/world/2015_02_06_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_04_world.sql diff --git a/sql/updates/world/2015_02_06_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_05_world.sql similarity index 100% rename from sql/updates/world/2015_02_06_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_05_world.sql diff --git a/sql/updates/world/2015_02_06_06_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_06_world.sql similarity index 100% rename from sql/updates/world/2015_02_06_06_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_06_world.sql diff --git a/sql/updates/world/2015_02_06_07_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_07_world.sql similarity index 100% rename from sql/updates/world/2015_02_06_07_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_07_world.sql diff --git a/sql/updates/world/2015_02_06_08_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_08_world.sql similarity index 100% rename from sql/updates/world/2015_02_06_08_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_08_world.sql diff --git a/sql/updates/world/2015_02_06_09_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_09_world.sql similarity index 100% rename from sql/updates/world/2015_02_06_09_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_09_world.sql diff --git a/sql/updates/world/2015_02_06_10_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_10_world.sql similarity index 100% rename from sql/updates/world/2015_02_06_10_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_10_world.sql diff --git a/sql/updates/world/2015_02_06_11_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_11_world.sql similarity index 100% rename from sql/updates/world/2015_02_06_11_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_11_world.sql diff --git a/sql/updates/world/2015_02_06_12_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_12_world.sql similarity index 100% rename from sql/updates/world/2015_02_06_12_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_12_world.sql diff --git a/sql/updates/world/2015_02_06_13_world_335.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_13_world_335.sql similarity index 100% rename from sql/updates/world/2015_02_06_13_world_335.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_06_13_world_335.sql diff --git a/sql/updates/world/2015_02_07_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_07_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_07_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_07_00_world.sql diff --git a/sql/updates/world/2015_02_07_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_07_01_world.sql similarity index 100% rename from sql/updates/world/2015_02_07_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_07_01_world.sql diff --git a/sql/updates/world/2015_02_09_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_09_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_00_world.sql diff --git a/sql/updates/world/2015_02_09_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_01_world.sql similarity index 100% rename from sql/updates/world/2015_02_09_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_01_world.sql diff --git a/sql/updates/world/2015_02_09_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_02_world.sql similarity index 100% rename from sql/updates/world/2015_02_09_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_02_world.sql diff --git a/sql/updates/world/2015_02_09_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_03_world.sql similarity index 100% rename from sql/updates/world/2015_02_09_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_03_world.sql diff --git a/sql/updates/world/2015_02_09_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_04_world.sql similarity index 100% rename from sql/updates/world/2015_02_09_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_04_world.sql diff --git a/sql/updates/world/2015_02_09_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_05_world.sql similarity index 100% rename from sql/updates/world/2015_02_09_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_05_world.sql diff --git a/sql/updates/world/2015_02_09_06_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_06_world.sql similarity index 100% rename from sql/updates/world/2015_02_09_06_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_06_world.sql diff --git a/sql/updates/world/2015_02_09_07_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_07_world.sql similarity index 100% rename from sql/updates/world/2015_02_09_07_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_07_world.sql diff --git a/sql/updates/world/2015_02_09_08_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_08_world.sql similarity index 100% rename from sql/updates/world/2015_02_09_08_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_08_world.sql diff --git a/sql/updates/world/2015_02_09_09_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_09_world.sql similarity index 100% rename from sql/updates/world/2015_02_09_09_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_09_world.sql diff --git a/sql/updates/world/2015_02_09_10_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_10_world.sql similarity index 100% rename from sql/updates/world/2015_02_09_10_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_10_world.sql diff --git a/sql/updates/world/2015_02_09_11_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_11_world.sql similarity index 100% rename from sql/updates/world/2015_02_09_11_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_11_world.sql diff --git a/sql/updates/world/2015_02_09_12_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_12_world.sql similarity index 100% rename from sql/updates/world/2015_02_09_12_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_12_world.sql diff --git a/sql/updates/world/2015_02_09_13_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_13_world.sql similarity index 100% rename from sql/updates/world/2015_02_09_13_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_13_world.sql diff --git a/sql/updates/world/2015_02_09_14_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_14_world.sql similarity index 100% rename from sql/updates/world/2015_02_09_14_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_14_world.sql diff --git a/sql/updates/world/2015_02_09_15_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_15_world.sql similarity index 100% rename from sql/updates/world/2015_02_09_15_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_09_15_world.sql diff --git a/sql/updates/world/2015_02_10_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_10_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_00_world.sql diff --git a/sql/updates/world/2015_02_10_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_01_world.sql similarity index 100% rename from sql/updates/world/2015_02_10_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_01_world.sql diff --git a/sql/updates/world/2015_02_10_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_02_world.sql similarity index 100% rename from sql/updates/world/2015_02_10_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_02_world.sql diff --git a/sql/updates/world/2015_02_10_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_03_world.sql similarity index 100% rename from sql/updates/world/2015_02_10_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_03_world.sql diff --git a/sql/updates/world/2015_02_10_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_04_world.sql similarity index 100% rename from sql/updates/world/2015_02_10_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_04_world.sql diff --git a/sql/updates/world/2015_02_10_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_05_world.sql similarity index 100% rename from sql/updates/world/2015_02_10_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_05_world.sql diff --git a/sql/updates/world/2015_02_10_06_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_06_world.sql similarity index 100% rename from sql/updates/world/2015_02_10_06_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_06_world.sql diff --git a/sql/updates/world/2015_02_10_07_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_07_world.sql similarity index 100% rename from sql/updates/world/2015_02_10_07_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_07_world.sql diff --git a/sql/updates/world/2015_02_10_08_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_08_world.sql similarity index 100% rename from sql/updates/world/2015_02_10_08_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_08_world.sql diff --git a/sql/updates/world/2015_02_10_09_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_09_world.sql similarity index 100% rename from sql/updates/world/2015_02_10_09_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_10_09_world.sql diff --git a/sql/updates/world/2015_02_11_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_11_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_11_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_11_00_world.sql diff --git a/sql/updates/world/2015_02_11_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_11_01_world.sql similarity index 100% rename from sql/updates/world/2015_02_11_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_11_01_world.sql diff --git a/sql/updates/world/2015_02_11_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_11_02_world.sql similarity index 100% rename from sql/updates/world/2015_02_11_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_11_02_world.sql diff --git a/sql/updates/world/2015_02_11_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_11_03_world.sql similarity index 100% rename from sql/updates/world/2015_02_11_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_11_03_world.sql diff --git a/sql/updates/world/2015_02_11_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_11_04_world.sql similarity index 100% rename from sql/updates/world/2015_02_11_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_11_04_world.sql diff --git a/sql/updates/world/2015_02_11_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_11_05_world.sql similarity index 100% rename from sql/updates/world/2015_02_11_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_11_05_world.sql diff --git a/sql/updates/world/2015_02_12_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_12_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_00_world.sql diff --git a/sql/updates/world/2015_02_12_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_01_world.sql similarity index 100% rename from sql/updates/world/2015_02_12_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_01_world.sql diff --git a/sql/updates/world/2015_02_12_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_02_world.sql similarity index 100% rename from sql/updates/world/2015_02_12_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_02_world.sql diff --git a/sql/updates/world/2015_02_12_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_03_world.sql similarity index 100% rename from sql/updates/world/2015_02_12_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_03_world.sql diff --git a/sql/updates/world/2015_02_12_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_04_world.sql similarity index 100% rename from sql/updates/world/2015_02_12_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_04_world.sql diff --git a/sql/updates/world/2015_02_12_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_05_world.sql similarity index 100% rename from sql/updates/world/2015_02_12_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_05_world.sql diff --git a/sql/updates/world/2015_02_12_06_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_06_world.sql similarity index 100% rename from sql/updates/world/2015_02_12_06_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_06_world.sql diff --git a/sql/updates/world/2015_02_12_07_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_07_world.sql similarity index 100% rename from sql/updates/world/2015_02_12_07_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_07_world.sql diff --git a/sql/updates/world/2015_02_12_08_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_08_world.sql similarity index 100% rename from sql/updates/world/2015_02_12_08_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_08_world.sql diff --git a/sql/updates/world/2015_02_12_09_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_09_world.sql similarity index 100% rename from sql/updates/world/2015_02_12_09_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_09_world.sql diff --git a/sql/updates/world/2015_02_12_10_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_10_world.sql similarity index 100% rename from sql/updates/world/2015_02_12_10_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_12_10_world.sql diff --git a/sql/updates/world/2015_02_13_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_13_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_00_world.sql diff --git a/sql/updates/world/2015_02_13_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_01_world.sql similarity index 100% rename from sql/updates/world/2015_02_13_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_01_world.sql diff --git a/sql/updates/world/2015_02_13_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_02_world.sql similarity index 100% rename from sql/updates/world/2015_02_13_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_02_world.sql diff --git a/sql/updates/world/2015_02_13_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_03_world.sql similarity index 100% rename from sql/updates/world/2015_02_13_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_03_world.sql diff --git a/sql/updates/world/2015_02_13_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_04_world.sql similarity index 100% rename from sql/updates/world/2015_02_13_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_04_world.sql diff --git a/sql/updates/world/2015_02_13_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_05_world.sql similarity index 100% rename from sql/updates/world/2015_02_13_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_05_world.sql diff --git a/sql/updates/world/2015_02_13_06_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_06_world.sql similarity index 100% rename from sql/updates/world/2015_02_13_06_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_06_world.sql diff --git a/sql/updates/world/2015_02_13_07_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_07_world.sql similarity index 100% rename from sql/updates/world/2015_02_13_07_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_07_world.sql diff --git a/sql/updates/world/2015_02_13_08_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_08_world.sql similarity index 100% rename from sql/updates/world/2015_02_13_08_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_08_world.sql diff --git a/sql/updates/world/2015_02_13_09_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_09_world.sql similarity index 100% rename from sql/updates/world/2015_02_13_09_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_13_09_world.sql diff --git a/sql/updates/world/2015_02_14_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_14_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_14_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_14_00_world.sql diff --git a/sql/updates/world/2015_02_14_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_14_01_world.sql similarity index 100% rename from sql/updates/world/2015_02_14_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_14_01_world.sql diff --git a/sql/updates/world/2015_02_14_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_14_02_world.sql similarity index 100% rename from sql/updates/world/2015_02_14_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_14_02_world.sql diff --git a/sql/updates/world/2015_02_14_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_14_03_world.sql similarity index 100% rename from sql/updates/world/2015_02_14_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_14_03_world.sql diff --git a/sql/updates/world/2015_02_14_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_14_04_world.sql similarity index 100% rename from sql/updates/world/2015_02_14_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_14_04_world.sql diff --git a/sql/updates/world/2015_02_14_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_14_05_world.sql similarity index 100% rename from sql/updates/world/2015_02_14_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_14_05_world.sql diff --git a/sql/updates/world/2015_02_15_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_15_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_00_world.sql diff --git a/sql/updates/world/2015_02_15_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_01_world.sql similarity index 100% rename from sql/updates/world/2015_02_15_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_01_world.sql diff --git a/sql/updates/world/2015_02_15_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_02_world.sql similarity index 100% rename from sql/updates/world/2015_02_15_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_02_world.sql diff --git a/sql/updates/world/2015_02_15_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_03_world.sql similarity index 100% rename from sql/updates/world/2015_02_15_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_03_world.sql diff --git a/sql/updates/world/2015_02_15_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_04_world.sql similarity index 100% rename from sql/updates/world/2015_02_15_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_04_world.sql diff --git a/sql/updates/world/2015_02_15_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_05_world.sql similarity index 100% rename from sql/updates/world/2015_02_15_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_05_world.sql diff --git a/sql/updates/world/2015_02_15_06_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_06_world.sql similarity index 100% rename from sql/updates/world/2015_02_15_06_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_06_world.sql diff --git a/sql/updates/world/2015_02_15_07_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_07_world.sql similarity index 100% rename from sql/updates/world/2015_02_15_07_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_07_world.sql diff --git a/sql/updates/world/2015_02_15_08_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_08_world.sql similarity index 100% rename from sql/updates/world/2015_02_15_08_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_08_world.sql diff --git a/sql/updates/world/2015_02_15_09_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_09_world.sql similarity index 100% rename from sql/updates/world/2015_02_15_09_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_09_world.sql diff --git a/sql/updates/world/2015_02_15_10_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_10_world.sql similarity index 100% rename from sql/updates/world/2015_02_15_10_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_10_world.sql diff --git a/sql/updates/world/2015_02_15_11_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_11_world.sql similarity index 100% rename from sql/updates/world/2015_02_15_11_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_11_world.sql diff --git a/sql/updates/world/2015_02_15_12_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_12_world.sql similarity index 100% rename from sql/updates/world/2015_02_15_12_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_12_world.sql diff --git a/sql/updates/world/2015_02_15_13_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_13_world.sql similarity index 100% rename from sql/updates/world/2015_02_15_13_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_13_world.sql diff --git a/sql/updates/world/2015_02_15_14_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_14_world.sql similarity index 100% rename from sql/updates/world/2015_02_15_14_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_15_14_world.sql diff --git a/sql/updates/world/2015_02_16_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_16_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_16_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_16_00_world.sql diff --git a/sql/updates/world/2015_02_16_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_16_01_world.sql similarity index 100% rename from sql/updates/world/2015_02_16_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_16_01_world.sql diff --git a/sql/updates/world/2015_02_16_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_16_02_world.sql similarity index 100% rename from sql/updates/world/2015_02_16_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_16_02_world.sql diff --git a/sql/updates/world/2015_02_16_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_16_03_world.sql similarity index 100% rename from sql/updates/world/2015_02_16_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_16_03_world.sql diff --git a/sql/updates/world/2015_02_16_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_16_04_world.sql similarity index 100% rename from sql/updates/world/2015_02_16_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_16_04_world.sql diff --git a/sql/updates/world/2015_02_16_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_16_05_world.sql similarity index 100% rename from sql/updates/world/2015_02_16_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_16_05_world.sql diff --git a/sql/updates/world/2015_02_16_06_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_16_06_world.sql similarity index 100% rename from sql/updates/world/2015_02_16_06_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_16_06_world.sql diff --git a/sql/updates/world/2015_02_17_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_17_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_17_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_17_00_world.sql diff --git a/sql/updates/world/2015_02_17_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_17_01_world.sql similarity index 100% rename from sql/updates/world/2015_02_17_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_17_01_world.sql diff --git a/sql/updates/world/2015_02_17_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_17_02_world.sql similarity index 100% rename from sql/updates/world/2015_02_17_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_17_02_world.sql diff --git a/sql/updates/world/2015_02_17_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_17_03_world.sql similarity index 100% rename from sql/updates/world/2015_02_17_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_17_03_world.sql diff --git a/sql/updates/world/2015_02_17_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_17_04_world.sql similarity index 100% rename from sql/updates/world/2015_02_17_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_17_04_world.sql diff --git a/sql/updates/world/2015_02_17_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_17_05_world.sql similarity index 100% rename from sql/updates/world/2015_02_17_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_17_05_world.sql diff --git a/sql/updates/world/2015_02_18_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_18_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_18_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_18_00_world.sql diff --git a/sql/updates/world/2015_02_18_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_18_01_world.sql similarity index 100% rename from sql/updates/world/2015_02_18_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_18_01_world.sql diff --git a/sql/updates/world/2015_02_18_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_18_02_world.sql similarity index 100% rename from sql/updates/world/2015_02_18_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_18_02_world.sql diff --git a/sql/updates/world/2015_02_18_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_18_03_world.sql similarity index 100% rename from sql/updates/world/2015_02_18_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_18_03_world.sql diff --git a/sql/updates/world/2015_02_19_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_19_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_19_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_19_00_world.sql diff --git a/sql/updates/world/2015_02_20_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_20_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_20_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_20_00_world.sql diff --git a/sql/updates/world/2015_02_20_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_20_01_world.sql similarity index 100% rename from sql/updates/world/2015_02_20_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_20_01_world.sql diff --git a/sql/updates/world/2015_02_20_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_20_02_world.sql similarity index 100% rename from sql/updates/world/2015_02_20_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_20_02_world.sql diff --git a/sql/updates/world/2015_02_20_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_20_03_world.sql similarity index 100% rename from sql/updates/world/2015_02_20_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_20_03_world.sql diff --git a/sql/updates/world/2015_02_20_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_20_04_world.sql similarity index 100% rename from sql/updates/world/2015_02_20_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_20_04_world.sql diff --git a/sql/updates/world/2015_02_21_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_21_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_21_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_21_00_world.sql diff --git a/sql/updates/world/2015_02_22_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_22_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_22_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_22_00_world.sql diff --git a/sql/updates/world/2015_02_23_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_23_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_00_world.sql diff --git a/sql/updates/world/2015_02_23_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_01_world.sql similarity index 100% rename from sql/updates/world/2015_02_23_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_01_world.sql diff --git a/sql/updates/world/2015_02_23_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_02_world.sql similarity index 100% rename from sql/updates/world/2015_02_23_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_02_world.sql diff --git a/sql/updates/world/2015_02_23_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_03_world.sql similarity index 100% rename from sql/updates/world/2015_02_23_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_03_world.sql diff --git a/sql/updates/world/2015_02_23_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_04_world.sql similarity index 100% rename from sql/updates/world/2015_02_23_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_04_world.sql diff --git a/sql/updates/world/2015_02_23_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_05_world.sql similarity index 100% rename from sql/updates/world/2015_02_23_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_05_world.sql diff --git a/sql/updates/world/2015_02_23_06_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_06_world.sql similarity index 100% rename from sql/updates/world/2015_02_23_06_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_06_world.sql diff --git a/sql/updates/world/2015_02_23_07_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_07_world.sql similarity index 100% rename from sql/updates/world/2015_02_23_07_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_07_world.sql diff --git a/sql/updates/world/2015_02_23_08_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_08_world.sql similarity index 100% rename from sql/updates/world/2015_02_23_08_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_08_world.sql diff --git a/sql/updates/world/2015_02_23_09_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_09_world.sql similarity index 100% rename from sql/updates/world/2015_02_23_09_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_09_world.sql diff --git a/sql/updates/world/2015_02_23_10_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_10_world.sql similarity index 100% rename from sql/updates/world/2015_02_23_10_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_23_10_world.sql diff --git a/sql/updates/world/2015_02_24_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_24_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_24_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_24_00_world.sql diff --git a/sql/updates/world/2015_02_24_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_24_01_world.sql similarity index 100% rename from sql/updates/world/2015_02_24_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_24_01_world.sql diff --git a/sql/updates/world/2015_02_25_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_25_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_25_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_25_00_world.sql diff --git a/sql/updates/world/2015_02_27_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_27_00_world.sql similarity index 100% rename from sql/updates/world/2015_02_27_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_27_00_world.sql diff --git a/sql/updates/world/2015_02_27_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_27_01_world.sql similarity index 100% rename from sql/updates/world/2015_02_27_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_27_01_world.sql diff --git a/sql/updates/world/2015_02_27_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_02_27_02_world.sql similarity index 100% rename from sql/updates/world/2015_02_27_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_02_27_02_world.sql diff --git a/sql/updates/world/2015_03_01_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_01_00_world.sql similarity index 100% rename from sql/updates/world/2015_03_01_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_01_00_world.sql diff --git a/sql/updates/world/2015_03_02_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_02_00_world.sql similarity index 100% rename from sql/updates/world/2015_03_02_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_02_00_world.sql diff --git a/sql/updates/world/2015_03_02_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_02_01_world.sql similarity index 100% rename from sql/updates/world/2015_03_02_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_02_01_world.sql diff --git a/sql/updates/world/2015_03_02_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_02_02_world.sql similarity index 100% rename from sql/updates/world/2015_03_02_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_02_02_world.sql diff --git a/sql/updates/world/2015_03_02_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_02_03_world.sql similarity index 100% rename from sql/updates/world/2015_03_02_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_02_03_world.sql diff --git a/sql/updates/world/2015_03_02_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_02_04_world.sql similarity index 100% rename from sql/updates/world/2015_03_02_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_02_04_world.sql diff --git a/sql/updates/world/2015_03_02_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_02_05_world.sql similarity index 100% rename from sql/updates/world/2015_03_02_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_02_05_world.sql diff --git a/sql/updates/world/2015_03_02_06_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_02_06_world.sql similarity index 100% rename from sql/updates/world/2015_03_02_06_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_02_06_world.sql diff --git a/sql/updates/world/2015_03_07_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_07_00_world.sql similarity index 100% rename from sql/updates/world/2015_03_07_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_07_00_world.sql diff --git a/sql/updates/world/2015_03_07_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_07_01_world.sql similarity index 100% rename from sql/updates/world/2015_03_07_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_07_01_world.sql diff --git a/sql/updates/world/2015_03_07_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_07_02_world.sql similarity index 100% rename from sql/updates/world/2015_03_07_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_07_02_world.sql diff --git a/sql/updates/world/2015_03_07_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_07_03_world.sql similarity index 100% rename from sql/updates/world/2015_03_07_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_07_03_world.sql diff --git a/sql/updates/world/2015_03_08_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_08_00_world.sql similarity index 100% rename from sql/updates/world/2015_03_08_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_08_00_world.sql diff --git a/sql/updates/world/2015_03_08_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_08_01_world.sql similarity index 100% rename from sql/updates/world/2015_03_08_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_08_01_world.sql diff --git a/sql/updates/world/2015_03_10_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_00_world.sql similarity index 100% rename from sql/updates/world/2015_03_10_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_00_world.sql diff --git a/sql/updates/world/2015_03_10_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_01_world.sql similarity index 100% rename from sql/updates/world/2015_03_10_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_01_world.sql diff --git a/sql/updates/world/2015_03_10_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_02_world.sql similarity index 100% rename from sql/updates/world/2015_03_10_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_02_world.sql diff --git a/sql/updates/world/2015_03_10_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_03_world.sql similarity index 100% rename from sql/updates/world/2015_03_10_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_03_world.sql diff --git a/sql/updates/world/2015_03_10_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_04_world.sql similarity index 100% rename from sql/updates/world/2015_03_10_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_04_world.sql diff --git a/sql/updates/world/2015_03_10_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_05_world.sql similarity index 100% rename from sql/updates/world/2015_03_10_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_05_world.sql diff --git a/sql/updates/world/2015_03_10_06_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_06_world.sql similarity index 100% rename from sql/updates/world/2015_03_10_06_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_06_world.sql diff --git a/sql/updates/world/2015_03_10_07_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_07_world.sql similarity index 100% rename from sql/updates/world/2015_03_10_07_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_07_world.sql diff --git a/sql/updates/world/2015_03_10_08_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_08_world.sql similarity index 100% rename from sql/updates/world/2015_03_10_08_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_08_world.sql diff --git a/sql/updates/world/2015_03_10_09_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_09_world.sql similarity index 100% rename from sql/updates/world/2015_03_10_09_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_09_world.sql diff --git a/sql/updates/world/2015_03_10_10_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_10_world.sql similarity index 100% rename from sql/updates/world/2015_03_10_10_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_10_10_world.sql diff --git a/sql/updates/world/2015_03_12_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_12_00_world.sql similarity index 100% rename from sql/updates/world/2015_03_12_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_12_00_world.sql diff --git a/sql/updates/world/2015_03_12_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_12_01_world.sql similarity index 100% rename from sql/updates/world/2015_03_12_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_12_01_world.sql diff --git a/sql/updates/world/2015_03_14_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_14_00_world.sql similarity index 100% rename from sql/updates/world/2015_03_14_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_14_00_world.sql diff --git a/sql/updates/world/2015_03_14_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_14_01_world.sql similarity index 100% rename from sql/updates/world/2015_03_14_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_14_01_world.sql diff --git a/sql/updates/world/2015_03_14_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_14_02_world.sql similarity index 100% rename from sql/updates/world/2015_03_14_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_14_02_world.sql diff --git a/sql/updates/world/2015_03_15_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_00_world.sql similarity index 100% rename from sql/updates/world/2015_03_15_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_00_world.sql diff --git a/sql/updates/world/2015_03_15_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_01_world.sql similarity index 100% rename from sql/updates/world/2015_03_15_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_01_world.sql diff --git a/sql/updates/world/2015_03_15_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_02_world.sql similarity index 100% rename from sql/updates/world/2015_03_15_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_02_world.sql diff --git a/sql/updates/world/2015_03_15_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_03_world.sql similarity index 100% rename from sql/updates/world/2015_03_15_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_03_world.sql diff --git a/sql/updates/world/2015_03_15_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_04_world.sql similarity index 100% rename from sql/updates/world/2015_03_15_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_04_world.sql diff --git a/sql/updates/world/2015_03_15_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_05_world.sql similarity index 100% rename from sql/updates/world/2015_03_15_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_05_world.sql diff --git a/sql/updates/world/2015_03_15_06_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_06_world.sql similarity index 100% rename from sql/updates/world/2015_03_15_06_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_06_world.sql diff --git a/sql/updates/world/2015_03_15_07_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_07_world.sql similarity index 100% rename from sql/updates/world/2015_03_15_07_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_07_world.sql diff --git a/sql/updates/world/2015_03_15_08_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_08_world.sql similarity index 100% rename from sql/updates/world/2015_03_15_08_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_08_world.sql diff --git a/sql/updates/world/2015_03_15_09_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_09_world.sql similarity index 100% rename from sql/updates/world/2015_03_15_09_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_09_world.sql diff --git a/sql/updates/world/2015_03_15_10_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_10_world.sql similarity index 100% rename from sql/updates/world/2015_03_15_10_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_10_world.sql diff --git a/sql/updates/world/2015_03_15_11_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_11_world.sql similarity index 100% rename from sql/updates/world/2015_03_15_11_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_11_world.sql diff --git a/sql/updates/world/2015_03_15_12_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_12_world.sql similarity index 100% rename from sql/updates/world/2015_03_15_12_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_12_world.sql diff --git a/sql/updates/world/2015_03_15_13_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_13_world.sql similarity index 100% rename from sql/updates/world/2015_03_15_13_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_13_world.sql diff --git a/sql/updates/world/2015_03_15_14_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_14_world.sql similarity index 100% rename from sql/updates/world/2015_03_15_14_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_15_14_world.sql diff --git a/sql/updates/world/2015_03_16_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_16_00_world.sql similarity index 100% rename from sql/updates/world/2015_03_16_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_16_00_world.sql diff --git a/sql/updates/world/2015_03_16_01_world_335.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_16_01_world_335.sql similarity index 100% rename from sql/updates/world/2015_03_16_01_world_335.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_16_01_world_335.sql diff --git a/sql/updates/world/2015_03_16_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_16_02_world.sql similarity index 100% rename from sql/updates/world/2015_03_16_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_16_02_world.sql diff --git a/sql/updates/world/2015_03_16_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_16_03_world.sql similarity index 100% rename from sql/updates/world/2015_03_16_03_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_16_03_world.sql diff --git a/sql/updates/world/2015_03_16_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_16_04_world.sql similarity index 100% rename from sql/updates/world/2015_03_16_04_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_16_04_world.sql diff --git a/sql/updates/world/2015_03_16_05_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_16_05_world.sql similarity index 100% rename from sql/updates/world/2015_03_16_05_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_16_05_world.sql diff --git a/sql/updates/world/2015_03_16_06_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_16_06_world.sql similarity index 100% rename from sql/updates/world/2015_03_16_06_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_16_06_world.sql diff --git a/sql/updates/world/2015_03_17_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_17_00_world.sql similarity index 100% rename from sql/updates/world/2015_03_17_00_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_17_00_world.sql diff --git a/sql/updates/world/2015_03_17_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_17_01_world.sql similarity index 100% rename from sql/updates/world/2015_03_17_01_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_17_01_world.sql diff --git a/sql/updates/world/2015_03_17_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_17_02_world.sql similarity index 100% rename from sql/updates/world/2015_03_17_02_world.sql rename to sql/old/3.3.5a/world/57_2014_10_19/2015_03_17_02_world.sql diff --git a/sql/old/3.3.5a/world/57_2014_10_19/2015_03_19_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_19_00_world.sql new file mode 100644 index 00000000000..1d87dafb9f1 --- /dev/null +++ b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_19_00_world.sql @@ -0,0 +1,4 @@ +UPDATE `trinity_string` SET `content_default` = 'Map: %u (%s) Zone: %u (%s) Area: %u (%s) Phase: %u\nX: %f Y: %f Z: %f Orientation: %f' WHERE `entry` = 101; +DELETE FROM `trinity_string` WHERE `entry` = 178; +INSERT INTO `trinity_string` (`entry`, `content_default`) VALUES +(178, 'grid[%u,%u]cell[%u,%u] InstanceID: %u\n ZoneX: %f ZoneY: %f\nGroundZ: %f FloorZ: %f Have height data (Map: %u VMap: %u MMap: %u)'); diff --git a/sql/old/3.3.5a/world/57_2014_10_19/2015_03_20_00_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_20_00_world.sql new file mode 100644 index 00000000000..93083732c4d --- /dev/null +++ b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_20_00_world.sql @@ -0,0 +1,13 @@ +-- +UPDATE `creature_template` SET `spell1`=49285,`spell2`=29577,`flags_extra`=2,`ainame`='SmartAI' WHERE `entry`=26472; + +DELETE FROM `smart_scripts` WHERE `entryorguid`=26472 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(26472,0,0,0,8,0,100,0,49266,0,0,0,69,1,0,0,0,0,0,7,0,0,0,0,0,0,0,'Highland Mustang - On Spell Hit(Dangle Wild Carrot) - Move To Player'), +(26472,0,1,2,34,0,100,0,0,1,0,0,103,1,0,0,0,0,0,1,0,0,0,0,0,0,0,'Highland Mustang - On Movement Inform - Set Root'), +(26472,0,2,0,61,0,100,0,0,0,0,0,85,49282,0,0,0,0,0,1,0,0,0,0,0,0,0,'Highland Mustang - Link With Previous - Invoker Cast Ride Highland Mustang'), +(26472,0,3,0,27,0,100,0,0,0,0,0,103,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Highland Mustang - On Passenger Boarded - Remove Root'); + +DELETE FROM `spell_script_names` WHERE `spell_id`=49285; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(49285,'spell_q12414_hand_over_reins'); diff --git a/sql/old/3.3.5a/world/57_2014_10_19/2015_03_20_01_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_20_01_world.sql new file mode 100644 index 00000000000..a489bcc9a4e --- /dev/null +++ b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_20_01_world.sql @@ -0,0 +1,2 @@ +-- +UPDATE `smart_scripts` SET `link`=0, `event_flags`=0, `comment`='Syreian the Bonecarver - On Aggro CMC - Cast \'Frost Arrow\'' WHERE `entryorguid`=32438 AND `source_type`=0 AND `id`=0 AND `link`=3; diff --git a/sql/old/3.3.5a/world/57_2014_10_19/2015_03_20_02_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_20_02_world.sql new file mode 100644 index 00000000000..05c120274da --- /dev/null +++ b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_20_02_world.sql @@ -0,0 +1,23 @@ +-- Updates base tables +DROP TABLE IF EXISTS `updates`; +CREATE TABLE `updates` ( + `name` VARCHAR(200) NOT NULL COMMENT 'filename with extension of the update.', + `hash` CHAR(40) NULL DEFAULT '' COMMENT 'sha1 hash of the sql file.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if an update is released or archived.', + `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'timestamp when the query was applied.', + `speed` INT(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'time the query takes to apply in ms.', + PRIMARY KEY (`name`) +) +COMMENT='List of all applied updates in this database.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; + +DROP TABLE IF EXISTS `updates_include`; +CREATE TABLE `updates_include` ( + `path` VARCHAR(200) NOT NULL COMMENT 'directory to include. $ means relative to the source directory.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if the directory contains released or archived updates.', + PRIMARY KEY (`path`) +) +COMMENT='List of directories where we want to include sql updates.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; diff --git a/sql/old/3.3.5a/world/57_2014_10_19/2015_03_20_03_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_20_03_world.sql new file mode 100644 index 00000000000..e8f9680dbee --- /dev/null +++ b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_20_03_world.sql @@ -0,0 +1,6 @@ +-- World database update data +TRUNCATE TABLE `updates_include`; +INSERT INTO `updates_include` (`path`, `state`) VALUES +('$/sql/updates/world', 'RELEASED'), +('$/sql/custom/world', 'RELEASED'), +('$/sql/old/3.3.5a/world', 'ARCHIVED'); diff --git a/sql/old/3.3.5a/world/57_2014_10_19/2015_03_20_04_world.sql b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_20_04_world.sql new file mode 100644 index 00000000000..2786dc1ef4e --- /dev/null +++ b/sql/old/3.3.5a/world/57_2014_10_19/2015_03_20_04_world.sql @@ -0,0 +1,339 @@ +INSERT IGNORE INTO `updates` (`name`, `hash`, `state`) VALUES +('2014_10_19_00_world.sql', 'DD3A24E92A894418F58C8AC280CBDAE2AC849B6C', 'ARCHIVED'), +('2014_10_19_01_world.sql', '76D19F7888A41B1B4AB4A5F366AE98057F066128', 'ARCHIVED'), +('2014_10_20_00_world.sql', 'E74390D42EF46218FE189C22A2A68BC454293F30', 'ARCHIVED'), +('2014_10_21_00_world.sql', '0E29A91E897F5EF08BFD09893475B483084F9BB9', 'ARCHIVED'), +('2014_10_22_00_world.sql', 'AD4925A3B6326E0E599693964BAABA38A0ED3FEF', 'ARCHIVED'), +('2014_10_23_00_world.sql', '73AD951F22484AD30C04B1514ECC1DFCB7A764C7', 'ARCHIVED'), +('2014_10_23_01_world.sql', '2D53A8A4A079CDF881CD1B7F142208E6453FF51A', 'ARCHIVED'), +('2014_10_24_00_world.sql', 'E743491473D33A8CCE30D580B1234BBC2E9D46B9', 'ARCHIVED'), +('2014_10_24_01_world.sql', '5A6EFA81F56575F85B27709944371C3E0A75D5D6', 'ARCHIVED'), +('2014_10_26_00_world.sql', 'FA22609D1B1D0B56760595FEA7445B0724A44EE6', 'ARCHIVED'), +('2014_10_27_00_world.sql', 'DA9FF17FA413017913715AAD27AD28F486340085', 'ARCHIVED'), +('2014_10_27_01_world_335.sql', '702C94D55094B6C94548B1357DC0811EBF0B5A45', 'ARCHIVED'), +('2014_10_27_02_world.sql', '3DAEB7EC510D924B37BFAC7D8CA06B8E38D60FEA', 'ARCHIVED'), +('2014_10_28_00_world.sql', 'C59E8BCC1A58FB150B08A6D2F4003E5EC151E696', 'ARCHIVED'), +('2014_10_29_00_world.sql', 'F478D2AE25B9C36E3456DD35884357063556AA36', 'ARCHIVED'), +('2014_10_30_00_world.sql', '46D284FE1E2847CE99FE707ECC0BDAB4C9F7EE06', 'ARCHIVED'), +('2014_10_30_02_world.sql', '6F0FFB389D698B8AFFA723EF55895C6CF2CBF7D3', 'ARCHIVED'), +('2014_11_01_00_world.sql', 'F874E451AD388BB495A6EF18EE9ACCC8A8EE6BAE', 'ARCHIVED'), +('2014_11_01_01_world.sql', '635673300CACA15DBCB955FFF135C626F4839676', 'ARCHIVED'), +('2014_11_01_02_world.sql', '030ABB19FC45B686C1980FA3412C46CC68B11DF0', 'ARCHIVED'), +('2014_11_01_03_world.sql', '43D89B12E9BB1A792683F18094A869F20DFE56AD', 'ARCHIVED'), +('2014_11_02_00_world.sql', 'F30EE29A22CD3109A3A592A6981EA02FF0C3027E', 'ARCHIVED'), +('2014_11_02_01_world.sql', 'C6C572068126299A5D97B5A076220DA2B11AC914', 'ARCHIVED'), +('2014_11_04_00_world.sql', '517BE655C4F39EAAA3025F843B29A0F276559FEF', 'ARCHIVED'), +('2014_11_05_00_world.sql', '0C1F022696DF96302AB62B4A215FC37FAD66FA35', 'ARCHIVED'), +('2014_11_07_00_world.sql', '16A0E153EDE2AB8C63A3BA6656AD71BB237FBCF3', 'ARCHIVED'), +('2014_11_07_01_world.sql', '5DCE2E3A55185587AD2DF83D5FB146C7A7D794A3', 'ARCHIVED'), +('2014_11_07_02_world.sql', '24FF1EA9DFB75FDF0FB0BF639A40BDDDFE2A5FA6', 'ARCHIVED'), +('2014_11_07_03_world.sql', '58D676DB962E4AF5A2B56238F3E54783EBD921AC', 'ARCHIVED'), +('2014_11_08_00_world.sql', '136936E2E16955DCD4B0EEA34AA3D22B6852A031', 'ARCHIVED'), +('2014_11_09_00_world.sql', '1EC2C8EF22A8E7B26D8E30762149C00339B96671', 'ARCHIVED'), +('2014_11_10_00_world.sql', '98E33F8928A52C0FA5CDE00B4C3025923852E42F', 'ARCHIVED'), +('2014_11_10_01_world.sql', '670F0A9C49B5CC59F38E1361855AAAD8AED62FC3', 'ARCHIVED'), +('2014_11_10_02_world.sql', '0E646076699FD04B7AFEE7068212403FF4A55A31', 'ARCHIVED'), +('2014_11_10_03_world.sql', '8734F326B496D24871E16809D167F055B10D6F93', 'ARCHIVED'), +('2014_11_10_04_world.sql', 'F22AB772400FB35B1BFF6F58534CA681BF769281', 'ARCHIVED'), +('2014_11_10_05_world.sql', '4DC43402104F8296FA992C40916036B76F35560C', 'ARCHIVED'), +('2014_11_11_00_world.sql', '8BD5D844D0EDE1ACC72495D368E54702D155B6B9', 'ARCHIVED'), +('2014_11_11_01_world.sql', 'E7A8D259AF4FA21D6433A81FEF6B2A4662D12140', 'ARCHIVED'), +('2014_11_13_00_world.sql', 'F5044137D5AE5F3DF7F8234990E50DDC4836E723', 'ARCHIVED'), +('2014_11_16_00_world.sql', '178BA69418C7784475F36518CEE6D3C0233A3A07', 'ARCHIVED'), +('2014_11_17_00_world.sql', '5BF38AD9646A3282799D036EEABC2097CEF04BA5', 'ARCHIVED'), +('2014_11_19_00_world.sql', '6E1D3D0451297EAE3A85903D4901E824BB4B5E50', 'ARCHIVED'), +('2014_11_19_01_world.sql', 'FF6BA950F542A73EBB000B641B0359CD940E05AF', 'ARCHIVED'), +('2014_11_19_02_world.sql', '9AC0C9130AF6426980611AD319F5052CADB1D8C5', 'ARCHIVED'), +('2014_11_20_00_world.sql', 'AD9D0A6F657F0A3DB2DE5B2D0F304AC8270965B4', 'ARCHIVED'), +('2014_11_20_01_world.sql', '2FC08035F0F09783E228788781D5D492452803F7', 'ARCHIVED'), +('2014_11_20_02_world.sql', '92143904667CDE981DAFF2A2F2FBFB72F9D8D060', 'ARCHIVED'), +('2014_11_20_03_world.sql', '8142DE63DCD1CB415336C73F29BE8D137FD49B48', 'ARCHIVED'), +('2014_11_20_04_world.sql', 'D52B5EF4374EE67FE77D3C1AF004E42E1425DB10', 'ARCHIVED'), +('2014_11_20_05_world.sql', '24A8F2ABEB2165424CE9476562E8B2F7149DD3C4', 'ARCHIVED'), +('2014_11_21_00_world.sql', '3A4461A509B39A3A4F3190F3E131E509C7D1DC62', 'ARCHIVED'), +('2014_11_21_01_world.sql', '4BA6FE2B55D4C83A2D4A7D3BD7D9D7041C6A6D0E', 'ARCHIVED'), +('2014_11_21_02_world.sql', '9853F7519702607305B89AD6AA6A4A116B5FC43F', 'ARCHIVED'), +('2014_11_22_00_world.sql', '9F3DF132A1361293310E3FD0068CFB412681A757', 'ARCHIVED'), +('2014_11_23_00_world.sql', 'A0F6F1ADB3E5EE23ADEB6B62152DAC3A3B824F1D', 'ARCHIVED'), +('2014_11_23_01_world.sql', 'DA7E05D771C87839F9E716264075F973ACDE1F5F', 'ARCHIVED'), +('2014_11_23_02_world.sql', 'F72CAC3E13C989A067F4877F379FE9272E6CD6A0', 'ARCHIVED'), +('2014_11_23_03_world.sql', '88661B16A67F3DA4546CC7869A37BBACA35F8BF2', 'ARCHIVED'), +('2014_11_23_04_world.sql', 'F0E9DDCF540B58123811993D09F61A2EFA34BC8D', 'ARCHIVED'), +('2014_11_24_00_world.sql', '35A5ED435EEA251DCB77EA64EE5AC90A6ADDFC0F', 'ARCHIVED'), +('2014_11_24_01_world.sql', 'A92185C01A2BD5A8749A6046531EE5A2914BF4CE', 'ARCHIVED'), +('2014_11_24_02_world.sql', '5DA05026C4F14BA0AEDC2B2E868485725A0DFC25', 'ARCHIVED'), +('2014_11_24_03_world.sql', 'C03D82E6D66BB958AB4B11E6C72AD0474E894CB2', 'ARCHIVED'), +('2014_11_24_04_world.sql', '8CBA6F45C04490763BF79D481102B2A63A99B450', 'ARCHIVED'), +('2014_11_25_00_world.sql', 'BF84443D6633723C26F35C9F87D34207935A8E46', 'ARCHIVED'), +('2014_11_25_01_world.sql', '36C805A7F35539C215C8D94D2380790E3FF21429', 'ARCHIVED'), +('2014_11_26_00_world.sql', 'A564902A142C6747E7CF334E45B74871EF581879', 'ARCHIVED'), +('2014_11_27_00_world.sql', 'B91B254E548AA0E59B3720BB03074A91F159023A', 'ARCHIVED'), +('2014_11_27_01_world.sql', 'B02FAB47E4FC1209CC97B2854A42807ACB815683', 'ARCHIVED'), +('2014_11_28_00_world.sql', '7215A2E204BACB04DDE4FDC944DDBD981F76DEF5', 'ARCHIVED'), +('2014_11_28_01_world.sql', 'DCF0E0F31CEC5CB12F1DDBA15A5B005A2E91EDD8', 'ARCHIVED'), +('2014_11_29_00_world.sql', '513ABD50C6097E60E5EDC7A9E253AC7B6D50573C', 'ARCHIVED'), +('2014_12_02_00_world.sql', '79D4705344B2B6B5125E5B7CD39DD63241653E94', 'ARCHIVED'), +('2014_12_03_00_world.sql', '1C55F7E222557C2B94A4127BEAFBFC53E10E2267', 'ARCHIVED'), +('2014_12_04_00_world.sql', '92B53420220CFD02B5BB4F1FB87C74EF89A687FF', 'ARCHIVED'), +('2014_12_05_00_world.sql', '00BCE89B80E3F387369AB182D8BABA8BD06738ED', 'ARCHIVED'), +('2014_12_05_01_world.sql', '7A6EB0C29F9E5151A64112A055DB862356C275E3', 'ARCHIVED'), +('2014_12_09_00_world.sql', '4EE336088D6B18CD7036A23D0E8532E471CBD44B', 'ARCHIVED'), +('2014_12_09_01_world.sql', 'D335CA5679B748454A8740B620A2869B6339B9A5', 'ARCHIVED'), +('2014_12_09_02_world.sql', '5A6A84B52CE1D81E5F554A30D05902C3B9FDE87F', 'ARCHIVED'), +('2014_12_09_03_world.sql', '05A557A57010732FB526C7133FB3C7AD088A9B0D', 'ARCHIVED'), +('2014_12_09_04_world.sql', '84080AC56AF1D7878F24DE2E2B533B85F31AAB27', 'ARCHIVED'), +('2014_12_11_00_world.sql', '9BD187258DD3D7AB8BA56176F7AFED913DDC7EA0', 'ARCHIVED'), +('2014_12_11_01_world.sql', '2983BE4BF4FACE83262CE794676C0E66068F4DBC', 'ARCHIVED'), +('2014_12_12_00_world.sql', '3E31732550055B7EB72443C30EA2ED975862215D', 'ARCHIVED'), +('2014_12_12_01_world.sql', 'BFB07C36367BD9A198BB9CC34103EC0C401A09E8', 'ARCHIVED'), +('2014_12_13_00_world.sql', '394CF64309B1BACD7BDF1A6BF7D88DE2A335FFEE', 'ARCHIVED'), +('2014_12_14_00_world.sql', 'E540554C57BFE99D35D0B324F0D8ADA347E81E18', 'ARCHIVED'), +('2014_12_14_01_world.sql', '8DA26FD3DC3056DF34CC6DB7F490C11070D42026', 'ARCHIVED'), +('2014_12_14_02_world.sql', '0930DC3E10808F1E55C42F55B6C9E015BEF16711', 'ARCHIVED'), +('2014_12_15_00_world.sql', '88FF35DC8B665070E96249CA01AA079DBE995BBB', 'ARCHIVED'), +('2014_12_16_00_world.sql', 'A1CEF65E6829841A9A97722D212C5A15AA6BC11B', 'ARCHIVED'), +('2014_12_17_00_world.sql', '545A3022BB1D85E8FCF9BC1086D5C3864BF1F0CA', 'ARCHIVED'), +('2014_12_18_00_world.sql', 'D0AF91CBF2B7AB16EC05AFF45B9E8124A133ACC0', 'ARCHIVED'), +('2014_12_21_00_world.sql', '4F07D137F7628A7DABED5FDD8EDB1B1A83086C0B', 'ARCHIVED'), +('2014_12_22_00_world.sql', 'FD642CF297E2B97325878EF0451EB3020EBBAF91', 'ARCHIVED'), +('2014_12_26_00_world.sql', '1DEED382A0CA4FFDC3329133CDDB718ADA87A27D', 'ARCHIVED'), +('2014_12_26_01_world.sql', '58564849E75F397C8E1C744692191ADE39DFA514', 'ARCHIVED'), +('2014_12_27_00_world.sql', 'E50AD029788BB42019794276C6C031041EBAF1AC', 'ARCHIVED'), +('2014_12_27_01_world_335.sql', '97D824705A26B9839E9CBB0ED6B4B868C2032442', 'ARCHIVED'), +('2014_12_27_02_world.sql', '73CB9DC61F1561C924CF7EB4EE40C33CB8581482', 'ARCHIVED'), +('2014_12_27_03_world.sql', '70C1936BC930000EE5CC3943E0B69F786647174C', 'ARCHIVED'), +('2014_12_27_04_world.sql', '9C376FE601EA95E05DE6DEA7FF9CCF1C10DDA3C9', 'ARCHIVED'), +('2014_12_27_05_world.sql', '40D43FC1B6A5007424A282F6C1E0412A1FD0D17A', 'ARCHIVED'), +('2014_12_27_06_world.sql', '87B1AA417FBA9C2ECFD42FCB8572280455571618', 'ARCHIVED'), +('2014_12_27_07_world.sql', 'F88EAD8F73639240BD87D99DAD9BE9395F8F9B60', 'ARCHIVED'), +('2014_12_27_08_world.sql', '35259FF08825E06EA1C494C321693D5185036F97', 'ARCHIVED'), +('2014_12_27_09_world.sql', 'F56FCF5BBE53DFD5EA2CF64D28EE30573D180EBD', 'ARCHIVED'), +('2014_12_27_10_world.sql', '5343C6F21C31BC930C6615C62175655393E0CC7A', 'ARCHIVED'), +('2014_12_27_11_world.sql', '79386ABE46C96E2ECD639F3E1C20A92F085DAB22', 'ARCHIVED'), +('2014_12_27_12_world.sql', '02812768BC41BE72801909EA06944097138CCF84', 'ARCHIVED'), +('2014_12_28_00_world.sql', '4321A8A3C7FFC24EEE409758D9DA2899FC40465D', 'ARCHIVED'), +('2014_12_28_01_world.sql', '58A8781F79C8968B5A16D6CADC5355483D80A54C', 'ARCHIVED'), +('2014_12_28_02_world.sql', '53E8B3A24AEB4467C5765FFF2B99CB646CC77319', 'ARCHIVED'), +('2014_12_28_03_world.sql', 'AA56071ACFE2F5858C575EA9882713B4C37724AA', 'ARCHIVED'), +('2014_12_28_04_world.sql', '277DFC82FE17489C519001A778ABE17F0FBCC605', 'ARCHIVED'), +('2014_12_28_05_world.sql', '717CF0E7F4795A972096EDFECCAAB561FBD8E987', 'ARCHIVED'), +('2014_12_29_00_world.sql', 'D1240CA18A858174112F403A238DE1811CEF4216', 'ARCHIVED'), +('2014_12_29_01_world.sql', '7F49A01DBC65106150F6F6755A25D0CF0FF3B62C', 'ARCHIVED'), +('2014_12_29_02_world.sql', '31D25589F914F4B6F6A645B70901877839233B98', 'ARCHIVED'), +('2014_12_30_00_world.sql', '9A5BF5AF7928E7F90607AA56972C027EBA3E70B7', 'ARCHIVED'), +('2014_12_30_01_world.sql', '215A8A5870BD6B739C768399E112D6E9374C92B1', 'ARCHIVED'), +('2014_12_31_00_world.sql', '0ECDB859228284ACBB124109F730D0B1AFA62354', 'ARCHIVED'), +('2015_01_01_00_world.sql', '0859CA1CA62DA6D22ADD6A1752657221C400F003', 'ARCHIVED'), +('2015_01_07_00_world.sql', '2E6F5ECB971C6C385C7E407D31E1B354F8D55FD1', 'ARCHIVED'), +('2015_01_08_00_world.sql', '0FB250F5B41C9BFF073A2B26659218F022EC1A4F', 'ARCHIVED'), +('2015_01_09_00_world.sql', '2C2DB1FF3E27595766C8DD49A00CA9CED1F25812', 'ARCHIVED'), +('2015_01_09_01_world.sql', 'D3CB658D8C880BF5988E31D2789DC1188AF12244', 'ARCHIVED'), +('2015_01_11_00_world.sql', 'D82B37FDF21C20D7C4AD901D694DCAEC55FB3F7D', 'ARCHIVED'), +('2015_01_11_01_world.sql', 'D50C7E01233D8E96B0D469D07EF44D88189426D4', 'ARCHIVED'), +('2015_01_12_00_world.sql', '3227E335F9FFA02CDBE02400AAE0BC7BCEEC8A8E', 'ARCHIVED'), +('2015_01_12_01_world.sql', 'CB62D8927520732802B1972EB8FCB939EDDD3001', 'ARCHIVED'), +('2015_01_12_02_world.sql', 'D8CBED7B2E00357E5535B252061DE4935A4F3E29', 'ARCHIVED'), +('2015_01_16_00_world.sql', 'E6471500DB443D29EE2E8A68329138571D766732', 'ARCHIVED'), +('2015_01_17_00_world.sql', '571B36B8FDD658CAD36BB9B98E39F979950534E7', 'ARCHIVED'), +('2015_01_18_00_world.sql', 'F61B99920FDC39EB2121D54AC46D80066AD48223', 'ARCHIVED'), +('2015_01_21_00_world.sql', '5B84E438A8775299182D7608CF3DC67058F2A39B', 'ARCHIVED'), +('2015_01_22_00_world.sql', '0F7F69CD48FA6A82443DB4E43E2A05FE106FB6F4', 'ARCHIVED'), +('2015_01_25_00_world.sql', '3D6B8414B7D47BAAF8E4F1926F70983BCAD31222', 'ARCHIVED'), +('2015_01_27_00_world.sql', '3DBD87A8C21D4998954E9DC1F24620BB7A90C9F8', 'ARCHIVED'), +('2015_01_30_00_world.sql', 'E18282EE743A88D2EDEF677489C6B93817399CA0', 'ARCHIVED'), +('2015_01_31_00_335.sql', 'CEC1C0C4C6A79C8FA2A5F5C2911A89F82BBEEC3D', 'ARCHIVED'), +('2015_02_02_00_world.sql', '4A7F644212D0BC1D8B4BDC7E27BA70BBBCF5C1A8', 'ARCHIVED'), +('2015_02_05_00_world.sql', '38F13F6FC99172DDB4FA2D5784363AD9F2D0C2BB', 'ARCHIVED'), +('2015_02_06_00_world.sql', '94062B928DC098C3BC21ECA381D74C157975BEA0', 'ARCHIVED'), +('2015_02_06_01_world.sql', 'DB4C759DC3FE146C78E5108A3D4C8F7690DE2329', 'ARCHIVED'), +('2015_02_06_02_world.sql', '5DB5CB82FD4B545440380AE2875F36A8965B87C8', 'ARCHIVED'), +('2015_02_06_03_world.sql', '9E668BA77990F4F2C246C2727A755CAD29B12854', 'ARCHIVED'), +('2015_02_06_04_world.sql', '4054010C47223827AF2C66D7DF8695F12668C818', 'ARCHIVED'), +('2015_02_06_05_world.sql', '0AE6B9713495B1D0E2B29323027EBF94C9DC20B0', 'ARCHIVED'), +('2015_02_06_06_world.sql', '656086116C0F561C264B5DCABA1811EE6A9352E2', 'ARCHIVED'), +('2015_02_06_07_world.sql', 'B59FEF5851B9DA2C0FC9E8454486F57EAE112996', 'ARCHIVED'), +('2015_02_06_08_world.sql', '8BDF881C53077DA04544BA6890921D49018693CB', 'ARCHIVED'), +('2015_02_06_09_world.sql', 'EDF8CDC077B79843213B7E015BDF8756A41922C7', 'ARCHIVED'), +('2015_02_06_10_world.sql', '0444E8AC273B886330EC119300675774618EA463', 'ARCHIVED'), +('2015_02_06_11_world.sql', 'D995A9DD8E2CBAD243D48E2B55A019D6DD72CF5E', 'ARCHIVED'), +('2015_02_06_12_world.sql', '83931738DD68110A93DBE1DBE1D4BA66351BD469', 'ARCHIVED'), +('2015_02_06_13_world_335.sql', '9F769C1E8BBF6488DBE332D4218B119FF7C2BA1E', 'ARCHIVED'), +('2015_02_07_00_world.sql', '5ABC7660D593224BB3533C56988A1D7D28F0EEFD', 'ARCHIVED'), +('2015_02_07_01_world.sql', '9CBEE43FC6C5E58BD76F6A6E1A947D051F29B12B', 'ARCHIVED'), +('2015_02_09_00_world.sql', '22DC8522928C16AB4C620652C3B53BD17594D663', 'ARCHIVED'), +('2015_02_09_01_world.sql', 'DC7C43F2EA5E8938CA6648AED595B6BF3EA8D937', 'ARCHIVED'), +('2015_02_09_02_world.sql', '7EE5458CFD14C343F397877F0A2509D1E8AA5803', 'ARCHIVED'), +('2015_02_09_03_world.sql', '561E3721B9F06D5A3F060FFFFB05AA1BF9D39E76', 'ARCHIVED'), +('2015_02_09_04_world.sql', 'BBCEE2D1C837B1B6FB4D6B7E0F32CA8EB33A251F', 'ARCHIVED'), +('2015_02_09_05_world.sql', '4D32D3BD4863BDA74FD25DA8910B7937648A7639', 'ARCHIVED'), +('2015_02_09_06_world.sql', '89CC8CDB51D9FA2437E61E18AE261259AF7D998B', 'ARCHIVED'), +('2015_02_09_07_world.sql', '8763439D3B13DD7F0397DD11E10DB93111D5E7BE', 'ARCHIVED'), +('2015_02_09_08_world.sql', '0BABD51056D66A0100B940C4F53AAA8EE7E001E1', 'ARCHIVED'), +('2015_02_09_09_world.sql', 'D87D1ED50CA9273BD548AF01AD376FAD79AD731D', 'ARCHIVED'), +('2015_02_09_10_world.sql', '0B24AA9924383F3F0BD515FBDC18E7DFE75BD6BB', 'ARCHIVED'), +('2015_02_09_11_world.sql', 'F871DEECC735582259193BB524B031DFE3810535', 'ARCHIVED'), +('2015_02_09_12_world.sql', '758083A309171B8FEF4CA8E3A1E0758412C62BE7', 'ARCHIVED'), +('2015_02_09_13_world.sql', '5F2523B534ACF194860EB7F6530E083C0E086BBA', 'ARCHIVED'), +('2015_02_09_14_world.sql', 'C6294ADFA086060C842EE524A03B6CDCA8C34D86', 'ARCHIVED'), +('2015_02_09_15_world.sql', 'B675FFBF3A5B34F99BE7D7759ACC94C5C3639EC1', 'ARCHIVED'), +('2015_02_10_00_world.sql', 'CD1826303ECB7C1B82F6BE40BD6FCC91E239C098', 'ARCHIVED'), +('2015_02_10_01_world.sql', '29E25D672C5F85E20D17691D77F62B8AEB5FF0D6', 'ARCHIVED'), +('2015_02_10_02_world.sql', '7AB6A48ABE89D5D66B4F9F960A0E5B1A62A75CC6', 'ARCHIVED'), +('2015_02_10_03_world.sql', '111973198B2D5E6F4C5C2516E30A2D2B14C41EEC', 'ARCHIVED'), +('2015_02_10_04_world.sql', 'EED7D1133C94A78A43FFEB6A51A934142BE224D0', 'ARCHIVED'), +('2015_02_10_05_world.sql', '53A40BD0DE58CE6D88B142D54D8774666F74081C', 'ARCHIVED'), +('2015_02_10_06_world.sql', '3E997E7CF1ABA6723FAAC9B2F9D493B2AC88A562', 'ARCHIVED'), +('2015_02_10_07_world.sql', 'DCCBABEC0514D380E50746A15C29628DD4379504', 'ARCHIVED'), +('2015_02_10_08_world.sql', 'C3B9AAA017751F06F81F85BA2E849CCF438D78AD', 'ARCHIVED'), +('2015_02_10_09_world.sql', '55FCB77B78EC36BE7CE1989829FA2BE6451C7C01', 'ARCHIVED'), +('2015_02_11_00_world.sql', 'F5C741A373374EA8365834ACE769072C4F9DA8F6', 'ARCHIVED'), +('2015_02_11_01_world.sql', '23CB3EBEE69BA59ACB183C6D31527C88508A4EE4', 'ARCHIVED'), +('2015_02_11_02_world.sql', '159860281A22005101DCB29D103EB9C40C041910', 'ARCHIVED'), +('2015_02_11_03_world.sql', '57C46103FABC911DE3455A7B4D8457FA937E12AE', 'ARCHIVED'), +('2015_02_11_04_world.sql', '45AD1E641084C4E0F22C6F34087F10533C1E29DE', 'ARCHIVED'), +('2015_02_11_05_world.sql', '0E232D2810CBFC314EA65944D649CA4AC46D821E', 'ARCHIVED'), +('2015_02_12_00_world.sql', 'CBB58AF3CA19E7713A282E79F05FCB23B0F3F5B8', 'ARCHIVED'), +('2015_02_12_01_world.sql', '91975F888AB8F542EBB11EB31CDA0E201EABB141', 'ARCHIVED'), +('2015_02_12_02_world.sql', '42D6DF618F929E41014B9B17A4A0D66F9E70374C', 'ARCHIVED'), +('2015_02_12_03_world.sql', '2C4F77BC61CD8A1D8BC8C126F69D66D5E388F7A1', 'ARCHIVED'), +('2015_02_12_04_world.sql', 'CB379D0FD46FDFCF32F9A851E378B8F1FA4C88CD', 'ARCHIVED'), +('2015_02_12_05_world.sql', '62EDAD0D718F10F025CB287A8D596EBD8905EEEB', 'ARCHIVED'), +('2015_02_12_06_world.sql', '4E731729A44F3C13353BF65C7C10F862902832AA', 'ARCHIVED'), +('2015_02_12_07_world.sql', '08BB67B5E8D07FACFC6945E022CD31928FCCA40B', 'ARCHIVED'), +('2015_02_12_08_world.sql', 'B46AC2A8008AD32380E06BE4024344661A6E4E58', 'ARCHIVED'), +('2015_02_12_09_world.sql', '7BD015AE62CBE7348CFF7BBA1C9554D08B996491', 'ARCHIVED'), +('2015_02_12_10_world.sql', 'F9D6251BA0CA2DBF0E6F1330B4A31C0821944BF5', 'ARCHIVED'), +('2015_02_13_00_world.sql', 'B5DBE0F36514434E7D8EC6D3AEAE55C95F0F3FD7', 'ARCHIVED'), +('2015_02_13_01_world.sql', 'D6DA260F0B2C74C7304422750A3BAF0B0FD0748F', 'ARCHIVED'), +('2015_02_13_02_world.sql', '8B172CBAC67D280FABA1B853285FF4301A715876', 'ARCHIVED'), +('2015_02_13_03_world.sql', '9E85F0E44F14A489379311D0F3802F58D847827A', 'ARCHIVED'), +('2015_02_13_04_world.sql', '36DA1C4C2BC969AFB421E8047E0AA22B9E4B6F50', 'ARCHIVED'), +('2015_02_13_05_world.sql', 'E48073A920A754FD6F4AE0ED01C9D41072D7DD13', 'ARCHIVED'), +('2015_02_13_06_world.sql', 'CD3D63C6C11C825D5C7EC0C859AA282D2A6BD166', 'ARCHIVED'), +('2015_02_13_07_world.sql', '61E3135F3126C6790E42743CE53D95305EF905F2', 'ARCHIVED'), +('2015_02_13_08_world.sql', '4DA9FB4C377C175DF71A44D338BA60FD2C7B620F', 'ARCHIVED'), +('2015_02_13_09_world.sql', 'EF84AF4C6EFF2E6FABD52B9224348BBE198EAC82', 'ARCHIVED'), +('2015_02_14_00_world.sql', 'CC5511E0F41D79606D3E4468B6A080AF5D6428A1', 'ARCHIVED'), +('2015_02_14_01_world.sql', '6EC493C9A790DBCDEF70B1EFBF2E2A8E9C0247CB', 'ARCHIVED'), +('2015_02_14_02_world.sql', '7E85DB767AF4A6B74FD6658BCA7C3188BD297355', 'ARCHIVED'), +('2015_02_14_03_world.sql', 'F1D179F37F833B8796D891DF2D990453A86544A9', 'ARCHIVED'), +('2015_02_14_04_world.sql', '39C4A09A3C213578965053A8518156179B1B3F08', 'ARCHIVED'), +('2015_02_14_05_world.sql', '06218EA0397DBE3120E3E54A4F7734AF687D8156', 'ARCHIVED'), +('2015_02_15_00_world.sql', '5BDDF4410B1EFEB8CA5D22414342F28BD89D632F', 'ARCHIVED'), +('2015_02_15_01_world.sql', '9A1696F20A6FA6DB3156B8F26959C6D9EFDFCB78', 'ARCHIVED'), +('2015_02_15_02_world.sql', '44D8AF1F64B0FA6CD8B8CC98836FAB2855CB9D17', 'ARCHIVED'), +('2015_02_15_03_world.sql', 'F4661478999F173A978A4481AB49AC7427E31FB8', 'ARCHIVED'), +('2015_02_15_04_world.sql', '06970DBB20CA78C9D46790E56419CE4DF891692D', 'ARCHIVED'), +('2015_02_15_05_world.sql', 'A0ABF430DB7689C5A4C81E9365CB62FDC6D751E1', 'ARCHIVED'), +('2015_02_15_06_world.sql', '213158CF2559AB62D96F5D87CBCDB894B5CE6656', 'ARCHIVED'), +('2015_02_15_07_world.sql', '66E80F9160CDE708586850D2873FDC12D97CCB2A', 'ARCHIVED'), +('2015_02_15_08_world.sql', '7A80E85E1117C0886DF840C3E57ED3A37CC05B92', 'ARCHIVED'), +('2015_02_15_09_world.sql', '04C18E50C1D7F1D098A89CD61F4596448B27C5CA', 'ARCHIVED'), +('2015_02_15_10_world.sql', '39A86967CEB92A595756EF08BDC8B02BCC66A65C', 'ARCHIVED'), +('2015_02_15_11_world.sql', 'C2C3AFC0A6A8547FF75D8A444BC70032F0FAD5C8', 'ARCHIVED'), +('2015_02_15_12_world.sql', '8BFB17EAACFB73BC966F0130240EBE6896EBD861', 'ARCHIVED'), +('2015_02_15_13_world.sql', '7BA1F085FF528182D39667E0865AA747CFC679D9', 'ARCHIVED'), +('2015_02_15_14_world.sql', '4C428B313B19663A5AC947336E76B3FFAA8FBBFA', 'ARCHIVED'), +('2015_02_16_00_world.sql', '186FFEF331127382F282A13D9A6FC878A4053AD2', 'ARCHIVED'), +('2015_02_16_01_world.sql', 'FA1D413ADB609C601BE1D9D68BD555DC284A5377', 'ARCHIVED'), +('2015_02_16_02_world.sql', '973E420ED39F8C138A64CE0D78581ECAA0B7937B', 'ARCHIVED'), +('2015_02_16_03_world.sql', 'F4DB971B2C1F775543D2CCBDE56CB471A57BAF2C', 'ARCHIVED'), +('2015_02_16_04_world.sql', 'E829C54AE39C7D7A9A1FF51D58AD18DC06D6FE50', 'ARCHIVED'), +('2015_02_16_05_world.sql', '6A4AB1FC25A2613F8FCAD375C69367D034000F1A', 'ARCHIVED'), +('2015_02_16_06_world.sql', '53CF5C1224FE597B8BC0677A1E3C48E01E4F0E6B', 'ARCHIVED'), +('2015_02_17_00_world.sql', '9B44A6A414469B5746E50A9E647B93B9D6620CA2', 'ARCHIVED'), +('2015_02_17_01_world.sql', '49AF6376F02242E6B998F24D1C9E85CFBA2BC368', 'ARCHIVED'), +('2015_02_17_02_world.sql', '2B55FE84EB9E86C76D8440B4395938B00E543198', 'ARCHIVED'), +('2015_02_17_03_world.sql', '753257BB90B8CBA20073B6DB08676A9802D8FAC0', 'ARCHIVED'), +('2015_02_17_04_world.sql', 'CCB8B2D9CC99EBB30BB18B7D4533E1646A6BB8BD', 'ARCHIVED'), +('2015_02_17_05_world.sql', '99907BBFE2529EDB8AEF468C2098B6BA7713ACA4', 'ARCHIVED'), +('2015_02_18_00_world.sql', '6CE3FB9845AE14EEB521103135A1F8E94B25BABA', 'ARCHIVED'), +('2015_02_18_01_world.sql', '73FEA71CD4739F8CCB1924A248FDD006D6F4F811', 'ARCHIVED'), +('2015_02_18_02_world.sql', 'DBC1F166B84CA4E135D827D8D5A8682EFDDC84B3', 'ARCHIVED'), +('2015_02_18_03_world.sql', '9224197FD3427974D942FEBCCEDE7ABD40300E23', 'ARCHIVED'), +('2015_02_19_00_world.sql', '2569C13F6357FD9ED9EB3254133C2BC9BEC20E45', 'ARCHIVED'), +('2015_02_20_00_world.sql', '776DFDF6D728A260CBDE349B888C913DFD362DEE', 'ARCHIVED'), +('2015_02_20_01_world.sql', '24EF4FBF8701A73BA307989426F63C68E2B69D4E', 'ARCHIVED'), +('2015_02_20_02_world.sql', 'AAE9E57EC2ED176842AAD43BCB8932D7B0379321', 'ARCHIVED'), +('2015_02_20_03_world.sql', '77DE8E0108E079741E0C3CED01AB4FD60260C57A', 'ARCHIVED'), +('2015_02_20_04_world.sql', 'C8B171835AA13C0325D2EF4CB1245C786508DC34', 'ARCHIVED'), +('2015_02_21_00_world.sql', 'DF2BF4D30D26181273E510A1D0D887E3250CB325', 'ARCHIVED'), +('2015_02_22_00_world.sql', '25F9838572A396C41FF1348582DAC9B9E952E410', 'ARCHIVED'), +('2015_02_23_00_world.sql', '9BBE01B603ECBA91894DF10CFD45F21AB5A3DB52', 'ARCHIVED'), +('2015_02_23_01_world.sql', 'C4E7234C96912A784AE648CA92F4CD6CA036FEF1', 'ARCHIVED'), +('2015_02_23_02_world.sql', '94E1F9D35A12A0A594D5150299D35C43A5866260', 'ARCHIVED'), +('2015_02_23_03_world.sql', 'AC64B1419E78B50B65428424FA93E12B8631EB5F', 'ARCHIVED'), +('2015_02_23_04_world.sql', '6AB64CD095469CB52FF01928D175B0D9BF51AD3D', 'ARCHIVED'), +('2015_02_23_05_world.sql', 'F21061BD0E2F620E575A692C0E9C5A19F205AD57', 'ARCHIVED'), +('2015_02_23_06_world.sql', 'CAD1DC9C406B2D8621E165E94F06C96DB82899BA', 'ARCHIVED'), +('2015_02_23_07_world.sql', 'B647684F11ABC4ECD26741AB9183E3BBA6A96B1F', 'ARCHIVED'), +('2015_02_23_08_world.sql', '11174B20B34253E1A589D8A403BD9FFBD0FE3973', 'ARCHIVED'), +('2015_02_23_09_world.sql', '96911A36C1BB0ABB161AAB1D85B5CD215BEB6B4E', 'ARCHIVED'), +('2015_02_23_10_world.sql', '58EC7A84326C2612881254F42802BC2A950F5530', 'ARCHIVED'), +('2015_02_24_00_world.sql', '62586C8082319A83C84426BA228076513CA62721', 'ARCHIVED'), +('2015_02_24_01_world.sql', '2370977C4F5619F5AFDDEF66FE9016DCCCEABE4D', 'ARCHIVED'), +('2015_02_25_00_world.sql', '53964FDE738A1324839B5DDA76F15586518B8A23', 'ARCHIVED'), +('2015_02_27_00_world.sql', '54E76B4BFBDC09231BA4A304100E0D1F75C4C859', 'ARCHIVED'), +('2015_02_27_01_world.sql', '6FC4CD8E76BD4E3CC6FDDFE181814745F6E2351D', 'ARCHIVED'), +('2015_02_27_02_world.sql', 'BEBBD48CCC153D87EC0D39CD717D5C533F165356', 'ARCHIVED'), +('2015_03_01_00_world.sql', '00E3E47B590E37609DA1CC59008553C78425A40F', 'ARCHIVED'), +('2015_03_02_00_world.sql', 'BF62D0769132CFD9A7968DA98CEF463DD04D9E74', 'ARCHIVED'), +('2015_03_02_01_world.sql', 'C94C119B766EDE550B60CFBA156EDA5CA40911EE', 'ARCHIVED'), +('2015_03_02_02_world.sql', 'C37D2D5EBF341A51409C49653DA0584A0C9A0979', 'ARCHIVED'), +('2015_03_02_03_world.sql', 'BF185DC5D9780B27DF0788C4008EEF88FC4F20CC', 'ARCHIVED'), +('2015_03_02_04_world.sql', '9053F61D94A83CD4E85B5DB889786ED607B127FC', 'ARCHIVED'), +('2015_03_02_05_world.sql', 'BBE9A3822502E7B9F069D6C6B481B0B902E9341A', 'ARCHIVED'), +('2015_03_02_06_world.sql', '360956E421F0A8F5EB9DD9C611C53B53EA33F921', 'ARCHIVED'), +('2015_03_07_00_world.sql', '9DA807070CA63F4342884DF65C7FE409EEEBAE49', 'ARCHIVED'), +('2015_03_07_01_world.sql', 'D9E23CFC5B7488C0DAAA6D31032239552DEF6225', 'ARCHIVED'), +('2015_03_07_02_world.sql', 'C184D7B6B327C328EE98198751783A816C6EBD26', 'ARCHIVED'), +('2015_03_07_03_world.sql', '3FBA2EDD2A3641A697CA71D0E0C5E716A057C13E', 'ARCHIVED'), +('2015_03_08_00_world.sql', '9FA6752B038CA5618B7D135983CBEB174896A91B', 'ARCHIVED'), +('2015_03_08_01_world.sql', 'FD48D1D422A812CAE718C684EF5698E6073EE6B4', 'ARCHIVED'), +('2015_03_10_00_world.sql', 'BFA0AA6D6F99877D7601ABB52A17F08D0C381EA3', 'ARCHIVED'), +('2015_03_10_01_world.sql', '052E1B11617503217E01449C16DBA74D215EF69C', 'ARCHIVED'), +('2015_03_10_02_world.sql', 'BECFD758851E49D958C48BCA2334424CE224FE5D', 'ARCHIVED'), +('2015_03_10_03_world.sql', 'EB06069B49ACE84F4C580984236A54DE99FBA026', 'ARCHIVED'), +('2015_03_10_04_world.sql', '380829C6E79DED3B3A7C7D85709376B7D8B01819', 'ARCHIVED'), +('2015_03_10_05_world.sql', 'C846E361D9921B965D89689B95322C4179013F13', 'ARCHIVED'), +('2015_03_10_06_world.sql', 'F757056CD733BDBA66E9DE49FC9BCCDBA063A88C', 'ARCHIVED'), +('2015_03_10_07_world.sql', 'A9FDC376A21F8A7D5C6E0D2314B63863C443BEC5', 'ARCHIVED'), +('2015_03_10_08_world.sql', 'F7F42C02531CB3B2E5D5CD3956E9224DE17BB0EA', 'ARCHIVED'), +('2015_03_10_09_world.sql', '2ACF60BF182DA88175890C2F03A5AA6BFCC09131', 'ARCHIVED'), +('2015_03_10_10_world.sql', '641F1B50398EF7562A233201EF1692A7AEA849D2', 'ARCHIVED'), +('2015_03_12_00_world.sql', 'C6811FEC6834870BC3A04BB57A3F7B1D6F84FF17', 'ARCHIVED'), +('2015_03_12_01_world.sql', '24E91D341E658CD2B70A66AFF18F568B02AC50F0', 'ARCHIVED'), +('2015_03_14_00_world.sql', 'C362E3EF5A194382D361D6215733C4B6F9F46E1F', 'ARCHIVED'), +('2015_03_14_01_world.sql', 'ABFB47CE7607FA8369299E520A52200B9A0578CD', 'ARCHIVED'), +('2015_03_14_02_world.sql', 'C7B9EEB9F0D685BDA8ADAE996D967903D5D68F80', 'ARCHIVED'), +('2015_03_15_00_world.sql', '48E0D4A881CF9A55CA7C1D2CB74E7CFC1617FD54', 'ARCHIVED'), +('2015_03_15_01_world.sql', '224CCC1CAB129B6015227BA09EBC86E9BC4C345E', 'ARCHIVED'), +('2015_03_15_02_world.sql', 'CD8163944E0B5FF444F41B5D5BE392F792F71051', 'ARCHIVED'), +('2015_03_15_03_world.sql', 'DE058F6096EB44433CDA1EC7C22F6C1210D8CA4E', 'ARCHIVED'), +('2015_03_15_04_world.sql', 'F00232122D2F1957EDD9AE6E4E3FB7A628CE69C3', 'ARCHIVED'), +('2015_03_15_05_world.sql', '295FF7503CC35E803C52F31E867ABE9D1E169F6A', 'ARCHIVED'), +('2015_03_15_06_world.sql', '6AB7AB871B2FE6967097EC98B991AC64BDEBA13C', 'ARCHIVED'), +('2015_03_15_07_world.sql', 'E373B6D1F3D86AC4B6F7DF0247ABF377A04C805F', 'ARCHIVED'), +('2015_03_15_08_world.sql', '01E780198F1758F1EE4A96795EE13E8C37CF218F', 'ARCHIVED'), +('2015_03_15_09_world.sql', '57681C975B5242D749E60F57D7D481C4A7EA0AD1', 'ARCHIVED'), +('2015_03_15_10_world.sql', 'C2A820073BD679E3A1EE7CFFF840EF30383AC176', 'ARCHIVED'), +('2015_03_15_11_world.sql', '455B95B5F89EEEAB2D62776445813C48E9184B27', 'ARCHIVED'), +('2015_03_15_12_world.sql', 'A986A98F9FF74C288C2288C3B88C01BCFF7C1EDA', 'ARCHIVED'), +('2015_03_15_13_world.sql', '9FF82DA5F3C1E4B506B481DF5CA9B954E6D5D843', 'ARCHIVED'), +('2015_03_15_14_world.sql', 'FBC07BEADB265662AAFE23FD9C36A90A5F1508FD', 'ARCHIVED'), +('2015_03_16_00_world.sql', '836E4FEA197C5ECE330642C976EBC4599FFBC001', 'ARCHIVED'), +('2015_03_16_01_world_335.sql', '91A90BEF14D353250671EB95DFA854064592800A', 'ARCHIVED'), +('2015_03_16_02_world.sql', 'E88EB7C67969EECC025F0CBFC578ED39B8D36E54', 'ARCHIVED'), +('2015_03_16_03_world.sql', 'FBFCCCEBC57755A99F64816A17CADD8EBEC04FC1', 'ARCHIVED'), +('2015_03_16_04_world.sql', '7FDC23F3B4DAABF91156D40CDDC2E4A4E133A55B', 'ARCHIVED'), +('2015_03_16_05_world.sql', '39F873A5FAE5D0D0D95515A8E434BC8FAC24955C', 'ARCHIVED'), +('2015_03_16_06_world.sql', 'C782DF0FA4B99ED6B0557A5CAC4A101F71EBF5F1', 'ARCHIVED'), +('2015_03_17_00_world.sql', '31F53F813A604442DB08AAA1D0C359E5BF5A545B', 'ARCHIVED'), +('2015_03_17_01_world.sql', '8E3DD14F9A9C43345B843826153579A4F334787C', 'ARCHIVED'), +('2015_03_17_02_world.sql', '6212A1CF186600907CBAE1000B9D6AF2026B6E7D', 'ARCHIVED'), +('2015_03_19_00_world.sql', 'CC3E1954E10F06C62A41A04D39A0FF3F138DE477', 'ARCHIVED'), +('2015_03_20_00_world.sql', '8E7C56D7C5F6FC85C291BEEFCEDF036431A399E9', 'ARCHIVED'), +('2015_03_20_01_world.sql', '3C09B97025F2311420DF3B6364AC26B97B57935E', 'ARCHIVED'), +('2015_03_20_02_world.sql', 'B761760804EA73BD297F296C5C1919687DF7191C', 'ARCHIVED'), +('2015_03_20_03_world.sql', 'F721BC06369843A998B6339D52423F28B6168137', 'ARCHIVED'), +('2015_03_20_04_world.sql', '', 'ARCHIVED'); diff --git a/src/server/authserver/CMakeLists.txt b/src/server/authserver/CMakeLists.txt index 077cd15404b..994a645c528 100644 --- a/src/server/authserver/CMakeLists.txt +++ b/src/server/authserver/CMakeLists.txt @@ -44,6 +44,7 @@ endif() include_directories( ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/dep/cppformat + ${CMAKE_SOURCE_DIR}/dep/process ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration ${CMAKE_SOURCE_DIR}/src/server/shared/Database @@ -54,6 +55,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Logging ${CMAKE_SOURCE_DIR}/src/server/shared/Networking ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Updater ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/Authentication diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index cd58ec2bf68..26f1c872150 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -28,6 +28,7 @@ #include "Common.h" #include "Config.h" #include "DatabaseEnv.h" +#include "DatabaseLoader.h" #include "Log.h" #include "ProcessPriority.h" #include "RealmList.h" @@ -150,33 +151,15 @@ bool StartDB() { MySQL::Library_Init(); - std::string dbstring = sConfigMgr->GetStringDefault("LoginDatabaseInfo", ""); - if (dbstring.empty()) - { - TC_LOG_ERROR("server.authserver", "Database not specified"); + // Load databases + // NOTE: While authserver is singlethreaded you should keep synch_threads == 1. + // Increasing it is just silly since only 1 will be used ever. + DatabaseLoader loader("server.authserver", DatabaseLoader::DATABASE_NONE); + loader + .AddDatabase(LoginDatabase, "Login"); + + if (!loader.Load()) return false; - } - - int32 worker_threads = sConfigMgr->GetIntDefault("LoginDatabase.WorkerThreads", 1); - if (worker_threads < 1 || worker_threads > 32) - { - TC_LOG_ERROR("server.authserver", "Improper value specified for LoginDatabase.WorkerThreads, defaulting to 1."); - worker_threads = 1; - } - - int32 synch_threads = sConfigMgr->GetIntDefault("LoginDatabase.SynchThreads", 1); - if (synch_threads < 1 || synch_threads > 32) - { - TC_LOG_ERROR("server.authserver", "Improper value specified for LoginDatabase.SynchThreads, defaulting to 1."); - synch_threads = 1; - } - - // NOTE: While authserver is singlethreaded you should keep synch_threads == 1. Increasing it is just silly since only 1 will be used ever. - if (!LoginDatabase.Open(dbstring, uint8(worker_threads), uint8(synch_threads))) - { - TC_LOG_ERROR("server.authserver", "Cannot connect to database"); - return false; - } TC_LOG_INFO("server.authserver", "Started auth database connection pool."); sLog->SetRealmId(0); // Enables DB appenders when realm is set. diff --git a/src/server/authserver/authserver.conf.dist b/src/server/authserver/authserver.conf.dist index b7dee9ac08b..6ba05e89d72 100644 --- a/src/server/authserver/authserver.conf.dist +++ b/src/server/authserver/authserver.conf.dist @@ -9,6 +9,7 @@ # EXAMPLE CONFIG # AUTH SERVER SETTINGS # MYSQL SETTINGS +# UPDATE SETTINGS # LOGGING SYSTEM SETTINGS # ################################################################################################### @@ -157,6 +158,86 @@ Wrong.Password.Login.Logging = 0 # ################################################################################################### +################################################################################################### +# UPDATE SETTINGS +# +# Updates.EnableDatabases +# Description: A mask that describes which databases shall be updated. +# +# Following flags are available +# DATABASE_LOGIN = 1, // Auth database +# +# Default: 0 - (All Disabled) +# 1 - (All Enabled) + +Updates.EnableDatabases = 0 + +# +# Updates.SourcePath +# Description: The path to your TrinityCore source directory. +# If the path is left empty, built-in CMAKE_SOURCE_DIR is used. +# Example: "../TrinityCore" +# Default: "" + +Updates.SourcePath = "" + +# +# Updates.SourcePath +# Description: The path to your mysql cli binary. +# If the path is left empty, built-in path from cmake is used. +# Example: "C:/Program Files/MySQL/MySQL Server 5.6/bin/mysql.exe" +# "mysql.exe" +# "/usr/bin/mysql" +# Default: "" + +Updates.MySqlCLIPath = "" + +# +# Updates.AutoSetup +# Description: Auto populate empty databases. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.AutoSetup = 1 + +# +# Updates.Redundancy +# Description: Perform data redundancy checks through hashing +# to detect changes on sql updates and reapply it. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.Redundancy = 1 + +# +# Updates.ArchivedRedundancy +# Description: Check hashes of archived updates (slows down startup). +# Default: 0 - (Disabled) +# 1 - (Enabled) + +Updates.ArchivedRedundancy = 0 + +# +# Updates.AllowRehash +# Description: Inserts the current file hash in the database if it is left empty. +# Useful if you want to mark a file as applied but you don't know its hash. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.AllowRehash = 1 + +# +# Updates.CleanDeadRef +# Description: Cleans dead/ orphaned references that occure if a update was deleted or renamed and edited. +# Disable this if you want to know if the database is in a possible "dirty state". +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.CleanDeadRef = 1 + +# +################################################################################################### + ################################################################################################### # # LOGGING SYSTEM SETTINGS diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp index e7d39d715eb..5aa6ea8ea7a 100644 --- a/src/server/game/AI/CoreAI/UnitAI.cpp +++ b/src/server/game/AI/CoreAI/UnitAI.cpp @@ -141,7 +141,7 @@ void UnitAI::DoCast(uint32 spellId) { if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId)) { - bool playerOnly = (spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS) != 0; + bool playerOnly = spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS); target = SelectTarget(SELECT_TARGET_RANDOM, 0, spellInfo->GetMaxRange(false), playerOnly); } break; @@ -156,7 +156,7 @@ void UnitAI::DoCast(uint32 spellId) { if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId)) { - bool playerOnly = (spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS) != 0; + bool playerOnly = spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS); float range = spellInfo->GetMaxRange(false); DefaultTargetSelector targetSelector(me, range, playerOnly, -(int32)spellId); @@ -213,7 +213,7 @@ void UnitAI::FillAISpellInfo() if (!spellInfo) continue; - if (spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_DEAD) + if (spellInfo->HasAttribute(SPELL_ATTR0_CASTABLE_WHILE_DEAD)) AIInfo->condition = AICOND_DIE; else if (spellInfo->IsPassive() || spellInfo->GetDuration() == -1) AIInfo->condition = AICOND_AGGRO; diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 9e13364f492..869561eade4 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -541,7 +541,7 @@ inline void Battleground::_ProcessJoin(uint32 diff) if (!aura->IsPermanent() && aura->GetDuration() <= 30*IN_MILLISECONDS && aurApp->IsPositive() - && (!(aura->GetSpellInfo()->Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY)) + && (!aura->GetSpellInfo()->HasAttribute(SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY)) && (!aura->HasEffectType(SPELL_AURA_MOD_INVISIBILITY))) player->RemoveAura(iter); else diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt index 38e515a9609..1473550983c 100644 --- a/src/server/game/CMakeLists.txt +++ b/src/server/game/CMakeLists.txt @@ -130,6 +130,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Networking ${CMAKE_SOURCE_DIR}/src/server/shared/Packets ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Updater ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities ${CMAKE_SOURCE_DIR}/src/server/ipc ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/src/server/game/Chat/ChatLink.cpp b/src/server/game/Chat/ChatLink.cpp index e34c39c5637..1120274db78 100644 --- a/src/server/game/Chat/ChatLink.cpp +++ b/src/server/game/Chat/ChatLink.cpp @@ -285,7 +285,7 @@ bool SpellChatLink::ValidateName(char* buffer, const char* context) ChatLink::ValidateName(buffer, context); // spells with that flag have a prefix of "$PROFESSION: " - if (_spell->Attributes & SPELL_ATTR0_TRADESPELL) + if (_spell->HasAttribute(SPELL_ATTR0_TRADESPELL)) { SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(_spell->Id); if (bounds.first == bounds.second) diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp index 6e5ef094168..1f928c76da6 100644 --- a/src/server/game/Combat/ThreatManager.cpp +++ b/src/server/game/Combat/ThreatManager.cpp @@ -79,7 +79,7 @@ bool ThreatCalcHelper::isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellIn return false; // spell not causing threat - if (threatSpell && threatSpell->AttributesEx & SPELL_ATTR1_NO_THREAT) + if (threatSpell && threatSpell->HasAttribute(SPELL_ATTR1_NO_THREAT)) return false; ASSERT(hatingUnit->GetTypeId() == TYPEID_UNIT); diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index f9379dc7e67..97a8d110c35 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -2606,7 +2606,7 @@ void Creature::FocusTarget(Spell const* focusSpell, WorldObject const* target) _focusSpell = focusSpell; SetGuidValue(UNIT_FIELD_TARGET, target->GetGUID()); - if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST) + if (focusSpell->GetSpellInfo()->HasAttribute(SPELL_ATTR5_DONT_TURN_DURING_CAST)) AddUnitState(UNIT_STATE_ROTATING); // Set serverside orientation if needed (needs to be after attribute check) @@ -2625,7 +2625,7 @@ void Creature::ReleaseFocus(Spell const* focusSpell) else SetGuidValue(UNIT_FIELD_TARGET, ObjectGuid::Empty); - if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST) + if (focusSpell->GetSpellInfo()->HasAttribute(SPELL_ATTR5_DONT_TURN_DURING_CAST)) ClearUnitState(UNIT_STATE_ROTATING); } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 84825ef43a6..69e295ce9f4 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -3969,7 +3969,7 @@ bool Player::IsNeedCastPassiveSpellAtLearn(SpellInfo const* spellInfo) const // talent dependent passives activated at form apply have proper stance data ShapeshiftForm form = GetShapeshiftForm(); bool need_cast = (!spellInfo->Stances || (form && (spellInfo->Stances & (1 << (form - 1)))) || - (!form && (spellInfo->AttributesEx2 & SPELL_ATTR2_NOT_NEED_SHAPESHIFT))); + (!form && spellInfo->HasAttribute(SPELL_ATTR2_NOT_NEED_SHAPESHIFT))); if (spellInfo->AttributesEx8 & SPELL_ATTR8_MASTERY_SPECIALIZATION) need_cast &= IsCurrentSpecMasterySpell(spellInfo); @@ -22585,7 +22585,7 @@ void Player::AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 ite if (rec > 0) ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, rec, spell); - if (catrec > 0 && !(spellInfo->AttributesEx6 & SPELL_ATTR6_IGNORE_CATEGORY_COOLDOWN_MODS)) + if (catrec > 0 && !spellInfo->HasAttribute(SPELL_ATTR6_IGNORE_CATEGORY_COOLDOWN_MODS)) ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, catrec, spell); if (int32 cooldownMod = GetTotalAuraModifier(SPELL_AURA_MOD_COOLDOWN)) @@ -24464,7 +24464,7 @@ bool Player::HasItemFitToSpellRequirements(SpellInfo const* spellInfo, Item cons bool Player::CanNoReagentCast(SpellInfo const* spellInfo) const { // don't take reagents for spells with SPELL_ATTR5_NO_REAGENT_WHILE_PREP - if (spellInfo->AttributesEx5 & SPELL_ATTR5_NO_REAGENT_WHILE_PREP && + if (spellInfo->HasAttribute(SPELL_ATTR5_NO_REAGENT_WHILE_PREP) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION)) return true; @@ -25423,7 +25423,7 @@ void Player::RestoreBaseRune(uint8 index) { AuraEffect const* aura = m_runes->runes[index].ConvertAura; // If rune was converted by a non-pasive aura that still active we should keep it converted - if (aura && !(aura->GetSpellInfo()->Attributes & SPELL_ATTR0_PASSIVE)) + if (aura && !aura->GetSpellInfo()->HasAttribute(SPELL_ATTR0_PASSIVE)) return; ConvertRune(index, GetBaseRune(index)); SetRuneConvertAura(index, NULL); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 5e946af51eb..3cc4ba3b070 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -592,7 +592,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam // interrupting auras with AURA_INTERRUPT_FLAG_DAMAGE before checking !damage (absorbed damage breaks that type of auras) if (spellProto) { - if (!(spellProto->AttributesEx4 & SPELL_ATTR4_DAMAGE_DOESNT_BREAK_AURAS)) + if (!spellProto->HasAttribute(SPELL_ATTR4_DAMAGE_DOESNT_BREAK_AURAS)) victim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TAKE_DAMAGE, spellProto->Id); } else @@ -761,7 +761,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam if (damagetype != NODAMAGE && damage) { if (victim != this && victim->GetTypeId() == TYPEID_PLAYER && // does not support creature push_back - (!spellProto || !(spellProto->AttributesEx7 & SPELL_ATTR7_NO_PUSHBACK_ON_DAMAGE))) + (!spellProto || !spellProto->HasAttribute(SPELL_ATTR7_NO_PUSHBACK_ON_DAMAGE))) { if (damagetype != DOT) if (Spell* spell = victim->m_currentSpells[CURRENT_GENERIC_SPELL]) @@ -964,7 +964,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama SpellSchoolMask damageSchoolMask = SpellSchoolMask(damageInfo->schoolMask); // Spells with SPELL_ATTR4_FIXED_DAMAGE ignore resilience because their damage is based off another spell's damage. - if (!(spellInfo->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE)) + if (!spellInfo->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE)) { if (IsDamageReducedByArmor(damageSchoolMask, spellInfo)) damage = CalcArmorReducedDamage(victim, damage, spellInfo, attackType); @@ -1423,7 +1423,7 @@ bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo const* s if (spellInfo) { // there are spells with no specific attribute but they have "ignores armor" in tooltip - if (spellInfo->AttributesCu & SPELL_ATTR0_CU_IGNORE_ARMOR) + if (spellInfo->HasAttribute(SPELL_ATTR0_CU_IGNORE_ARMOR)) return false; // bleeding effects are not reduced by armor @@ -1506,7 +1506,7 @@ uint32 Unit::CalcSpellResistance(Unit* victim, SpellSchoolMask schoolMask, Spell return 0; // Ignore spells that can't be resisted - if (spellInfo && spellInfo->AttributesEx4 & SPELL_ATTR4_IGNORE_RESISTANCES) + if (spellInfo && spellInfo->HasAttribute(SPELL_ATTR4_IGNORE_RESISTANCES)) return 0; uint8 const bossLevel = 83; @@ -2141,7 +2141,7 @@ void Unit::SendMeleeAttackStop(Unit* victim) bool Unit::isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType /*attackType*/) { // These spells can't be blocked - if (spellProto && spellProto->Attributes & SPELL_ATTR0_IMPOSSIBLE_DODGE_PARRY_BLOCK) + if (spellProto && spellProto->HasAttribute(SPELL_ATTR0_IMPOSSIBLE_DODGE_PARRY_BLOCK)) return false; if (victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION) || victim->HasInArc(float(M_PI), this)) @@ -2206,7 +2206,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo { // Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will additionally fully ignore // resist and deflect chances - if (spellInfo->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT) + if (spellInfo->HasAttribute(SPELL_ATTR3_IGNORE_HIT_RESULT)) return SPELL_MISS_NONE; WeaponAttackType attType = BASE_ATTACK; @@ -2245,10 +2245,10 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo bool canDodge = true; bool canParry = true; - bool canBlock = (spellInfo->AttributesEx3 & SPELL_ATTR3_BLOCKABLE_SPELL) != 0; + bool canBlock = spellInfo->HasAttribute(SPELL_ATTR3_BLOCKABLE_SPELL); // Same spells cannot be parry/dodge - if (spellInfo->Attributes & SPELL_ATTR0_IMPOSSIBLE_DODGE_PARRY_BLOCK) + if (spellInfo->HasAttribute(SPELL_ATTR0_IMPOSSIBLE_DODGE_PARRY_BLOCK)) return SPELL_MISS_NONE; // Chance resist mechanic @@ -2288,7 +2288,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo } else // Only deterrence as of 3.3.5 { - if (spellInfo->AttributesCu & SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) + if (spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET)) canParry = false; } } @@ -2379,7 +2379,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo) { // Can`t miss on dead target (on skinning for example) - if ((!victim->IsAlive() && victim->GetTypeId() != TYPEID_PLAYER) || spellInfo->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT) + if ((!victim->IsAlive() && victim->GetTypeId() != TYPEID_PLAYER) || spellInfo->HasAttribute(SPELL_ATTR3_IGNORE_HIT_RESULT)) return SPELL_MISS_NONE; SpellSchoolMask schoolMask = spellInfo->GetSchoolMask(); @@ -2868,7 +2868,7 @@ bool Unit::IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled, bool skipAu { if (!skipInstant || m_currentSpells[CURRENT_GENERIC_SPELL]->GetCastTime()) { - if (!isAutoshoot || !(m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->AttributesEx2 & SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS)) + if (!isAutoshoot || !(m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->HasAttribute(SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS))) return true; } } @@ -2876,7 +2876,7 @@ bool Unit::IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled, bool skipAu if (!skipChanneled && m_currentSpells[CURRENT_CHANNELED_SPELL] && (m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED)) { - if (!isAutoshoot || !(m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->AttributesEx2 & SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS)) + if (!isAutoshoot || !(m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->HasAttribute(SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS))) return true; } // autorepeat spells may be finished or delayed, but they are still considered cast @@ -3011,7 +3011,7 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 castItemGUID = castItem->GetGUID(); // find current aura from spell and change it's stackamount, or refresh it's duration - if (Aura* foundAura = GetOwnedAura(newAura->Id, casterGUID, (newAura->AttributesCu & SPELL_ATTR0_CU_ENCHANT_PROC) ? castItemGUID : ObjectGuid::Empty, 0)) + if (Aura* foundAura = GetOwnedAura(newAura->Id, casterGUID, newAura->HasAttribute(SPELL_ATTR0_CU_ENCHANT_PROC) ? castItemGUID : ObjectGuid::Empty, 0)) { // effect masks do not match // extremely rare case @@ -3522,7 +3522,7 @@ void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId // Call OnDispel hook on AuraScript aura->CallScriptDispel(&dispelInfo); - if (aura->GetSpellInfo()->AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES) + if (aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_CHARGES)) aura->ModCharges(-dispelInfo.GetRemovedCharges(), AURA_REMOVE_BY_ENEMY_SPELL); else aura->ModStackAmount(-dispelInfo.GetRemovedCharges(), AURA_REMOVE_BY_ENEMY_SPELL); @@ -3567,7 +3567,7 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, U } } - bool stealCharge = (aura->GetSpellInfo()->AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES) != 0; + bool stealCharge = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_CHARGES); // Cast duration to unsigned to prevent permanent aura's such as Righteous Fury being permanently added to caster uint32 dur = std::min(2u * MINUTE * IN_MILLISECONDS, uint32(aura->GetDuration())); @@ -3827,9 +3827,9 @@ void Unit::RemoveArenaAuras() { AuraApplication const* aurApp = iter->second; Aura const* aura = aurApp->GetBase(); - if (!(aura->GetSpellInfo()->AttributesEx4 & SPELL_ATTR4_UNK21) // don't remove stances, shadowform, pally/hunter auras + if (!aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_UNK21) // don't remove stances, shadowform, pally/hunter auras && !aura->IsPassive() // don't remove passive auras - && (aurApp->IsPositive() || !(aura->GetSpellInfo()->AttributesEx3 & SPELL_ATTR3_DEATH_PERSISTENT))) // not negative death persistent auras + && (aurApp->IsPositive() || !aura->GetSpellInfo()->HasAttribute(SPELL_ATTR3_DEATH_PERSISTENT))) // not negative death persistent auras RemoveAura(iter); else ++iter; @@ -4089,7 +4089,7 @@ void Unit::GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelCharges // The charges / stack amounts don't count towards the total number of auras that can be dispelled. // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell // Polymorph instead of 1 / (5 + 1) -> 16%. - bool dispel_charges = (aura->GetSpellInfo()->AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES) != 0; + bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_CHARGES); uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount(); if (charges > 0) dispelList.push_back(std::make_pair(aura, charges)); @@ -8175,7 +8175,7 @@ bool Unit::IsMagnet() const Unit* Unit::GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo) { // Patch 1.2 notes: Spell Reflection no longer reflects abilities - if (spellInfo->Attributes & SPELL_ATTR0_ABILITY || spellInfo->AttributesEx & SPELL_ATTR1_CANT_BE_REDIRECTED || spellInfo->Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) + if (spellInfo->HasAttribute(SPELL_ATTR0_ABILITY) || spellInfo->HasAttribute(SPELL_ATTR1_CANT_BE_REDIRECTED) || spellInfo->HasAttribute(SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY)) return victim; Unit::AuraEffectList const& magnetAuras = victim->GetAuraEffectsByType(SPELL_AURA_SPELL_MAGNET); @@ -8427,7 +8427,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin return pdamage; // Some spells don't benefit from done mods - if (spellProto->AttributesEx3 & SPELL_ATTR3_NO_DONE_BONUS) + if (spellProto->HasAttribute(SPELL_ATTR3_NO_DONE_BONUS)) return pdamage; // For totems get damage bonus from owner @@ -8558,7 +8558,7 @@ float Unit::SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, Damage return 1.0f; // Some spells don't benefit from pct done mods - if (spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS) + if (spellProto->HasAttribute(SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS)) return 1.0f; // For totems pct done mods are calculated when its calculation is run on the player in SpellDamageBonusDone. @@ -8582,7 +8582,7 @@ float Unit::SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, Damage { if ((*i)->GetSpellInfo()->EquippedItemClass == -1) AddPct(DoneTotalMod, (*i)->GetAmount()); - else if (!((*i)->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0)) + else if (!(*i)->GetSpellInfo()->HasAttribute(SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0)) AddPct(DoneTotalMod, (*i)->GetAmount()); else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo())) AddPct(DoneTotalMod, (*i)->GetAmount()); @@ -8775,7 +8775,7 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui } } // Spells with SPELL_ATTR4_FIXED_DAMAGE should only benefit from mechanic damage mod auras. - if (!(spellProto->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE)) + if (!spellProto->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE)) { // get all auras from caster that allow the spell to ignore resistance (sanctified wrath) AuraEffectList const& IgnoreResistAuras = caster->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST); @@ -8905,7 +8905,7 @@ float Unit::GetUnitSpellCriticalChance(Unit* victim, SpellInfo const* spellProto return 0.0f; // not critting spell - if ((spellProto->AttributesEx2 & SPELL_ATTR2_CANT_CRIT)) + if (spellProto->HasAttribute(SPELL_ATTR2_CANT_CRIT)) return 0.0f; float crit_chance = 0.0f; @@ -9490,7 +9490,7 @@ bool Unit::IsImmunedToDamage(SpellSchoolMask shoolMask) const bool Unit::IsImmunedToDamage(SpellInfo const* spellInfo) const { - if (spellInfo->Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) + if (spellInfo->HasAttribute(SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY)) return false; uint32 shoolMask = spellInfo->GetSchoolMask(); @@ -9523,7 +9523,7 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo) const if (itr->type == spellInfo->Id) return true; - if (spellInfo->Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) + if (spellInfo->HasAttribute(SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY)) return false; if (spellInfo->Dispel) @@ -9581,7 +9581,7 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) cons if (!spellInfo || !spellInfo->Effects[index].IsEffect()) return false; - if (spellInfo->Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) + if (spellInfo->HasAttribute(SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY)) return false; // If m_immuneToEffect type contain this effect type, IMMUNE effect. @@ -9604,7 +9604,7 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) cons SpellImmuneList const& list = m_spellImmune[IMMUNITY_STATE]; for (SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr) if (itr->type == aura) - if (!(spellInfo->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT)) + if (!spellInfo->HasAttribute(SPELL_ATTR3_IGNORE_HIT_RESULT)) return true; // Check for immune to application of harmful magical effects @@ -9679,7 +9679,7 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType // Some spells don't benefit from pct done mods if (spellProto) - if (!(spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS)) + if (!spellProto->HasAttribute(SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS)) { AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i) @@ -9688,7 +9688,7 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType { if ((*i)->GetSpellInfo()->EquippedItemClass == -1) AddPct(DoneTotalMod, (*i)->GetAmount()); - else if (!((*i)->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0)) + else if (!(*i)->GetSpellInfo()->HasAttribute(SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0)) AddPct(DoneTotalMod, (*i)->GetAmount()); else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo())) AddPct(DoneTotalMod, (*i)->GetAmount()); @@ -9883,7 +9883,7 @@ void Unit::ApplySpellDispelImmunity(const SpellInfo* spellProto, DispelType type { ApplySpellImmune(spellProto->Id, IMMUNITY_DISPEL, type, apply); - if (apply && spellProto->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY) + if (apply && spellProto->HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)) { // Create dispel mask by dispel type uint32 dispelMask = SpellInfo::GetDispelMask(type); @@ -10271,7 +10271,7 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo return false; // can't attack invisible (ignore stealth for aoe spells) also if the area being looked at is from a spell use the dynamic object created instead of the casting unit. - if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && (obj ? !obj->CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()) : !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()))) + if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && (obj ? !obj->CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()) : !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()))) return false; // can't attack dead @@ -10279,7 +10279,7 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo return false; // can't attack untargetable - if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_UNTARGETABLE)) + if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_TARGET_UNTARGETABLE)) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) return false; @@ -10392,7 +10392,7 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co return false; // can't assist invisible - if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea())) + if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea())) return false; // can't assist dead @@ -10400,11 +10400,11 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co return false; // can't assist untargetable - if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_UNTARGETABLE)) + if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_TARGET_UNTARGETABLE)) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) return false; - if (!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_ASSIST_IGNORE_IMMUNE_FLAG)) + if (!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_ASSIST_IGNORE_IMMUNE_FLAG)) { if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)) { @@ -10451,7 +10451,7 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co // PvC case - player can assist creature only if has specific type flags // !target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && else if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) - && (!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_ASSIST_IGNORE_IMMUNE_FLAG)) + && (!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_ASSIST_IGNORE_IMMUNE_FLAG)) && !((target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_PVP))) { if (Creature const* creatureTarget = target->ToCreature()) @@ -11168,7 +11168,7 @@ int32 Unit::ModSpellDuration(SpellInfo const* spellProto, Unit const* target, in return duration; // some auras are not affected by duration modifiers - if (spellProto->AttributesEx7 & SPELL_ATTR7_IGNORE_DURATION_MODS) + if (spellProto->HasAttribute(SPELL_ATTR7_IGNORE_DURATION_MODS)) return duration; // cut duration only of negative effects @@ -11258,17 +11258,17 @@ void Unit::ModSpellCastTime(SpellInfo const* spellInfo, int32 & castTime, Spell* if (!spellInfo || castTime < 0) return; - if (spellInfo->IsChanneled() && !(spellInfo->AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION)) + if (spellInfo->IsChanneled() && !spellInfo->HasAttribute(SPELL_ATTR5_HASTE_AFFECT_DURATION)) return; // called from caster if (Player* modOwner = GetSpellModOwner()) modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CASTING_TIME, castTime, spell); - if (!((spellInfo->Attributes & (SPELL_ATTR0_ABILITY | SPELL_ATTR0_TRADESPELL)) || (spellInfo->AttributesEx3 & SPELL_ATTR3_NO_DONE_BONUS)) && + if (!(spellInfo->HasAttribute(SPELL_ATTR0_ABILITY) || spellInfo->HasAttribute(SPELL_ATTR0_TRADESPELL) || spellInfo->HasAttribute(SPELL_ATTR0_TRADESPELL) || spellInfo->HasAttribute(SPELL_ATTR3_NO_DONE_BONUS)) && ((GetTypeId() == TYPEID_PLAYER && spellInfo->SpellFamilyName) || GetTypeId() == TYPEID_UNIT)) castTime = int32(float(castTime) * GetFloatValue(UNIT_MOD_CAST_SPEED)); - else if (spellInfo->Attributes & SPELL_ATTR0_REQ_AMMO && !(spellInfo->AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG)) + else if (spellInfo->HasAttribute(SPELL_ATTR0_REQ_AMMO) && !spellInfo->HasAttribute(SPELL_ATTR2_AUTOREPEAT_FLAG)) castTime = int32(float(castTime) * m_modAttackSpeedPct[RANGED_ATTACK]); else if (spellInfo->SpellVisual[0] == 3881 && HasAura(67556)) // cooking with Chef Hat. castTime = 500; @@ -12091,7 +12091,7 @@ void CharmInfo::InitPossessCreateSpells() { uint32 spellId = _unit->ToCreature()->m_spells[i]; SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); - if (spellInfo && !(spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_DEAD)) + if (spellInfo && !spellInfo->HasAttribute(SPELL_ATTR0_CASTABLE_WHILE_DEAD)) { if (spellInfo->IsPassive()) _unit->CastSpell(_unit, spellInfo, true); @@ -12119,7 +12119,7 @@ void CharmInfo::InitCharmCreateSpells() uint32 spellId = _unit->ToCreature()->m_spells[x]; SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); - if (!spellInfo || spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_DEAD) + if (!spellInfo || spellInfo->HasAttribute(SPELL_ATTR0_CASTABLE_WHILE_DEAD)) { _charmspells[x].SetActionAndType(spellId, ACT_DISABLED); continue; @@ -12496,7 +12496,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u continue; // Triggered spells not triggering additional spells - bool triggered = !(spellProto->AttributesEx3 & SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED) ? + bool triggered = !spellProto->HasAttribute(SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED) ? (procExtra & PROC_EX_INTERNAL_TRIGGERED && !(procFlag & PROC_FLAG_DONE_TRAP_ACTIVATION)) : false; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) @@ -12553,7 +12553,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u cooldown = i->spellProcEvent->cooldown; // Note: must SetCantProc(false) before return - if (spellInfo->AttributesEx3 & SPELL_ATTR3_DISABLE_PROC) + if (spellInfo->HasAttribute(SPELL_ATTR3_DISABLE_PROC)) SetCantProc(true); bool handled = i->aura->CallScriptProcHandlers(aurApp, eventInfo); @@ -12758,7 +12758,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u i->aura->CallScriptAfterProcHandlers(aurApp, eventInfo); - if (spellInfo->AttributesEx3 & SPELL_ATTR3_DISABLE_PROC) + if (spellInfo->HasAttribute(SPELL_ATTR3_DISABLE_PROC)) SetCantProc(false); } @@ -13445,7 +13445,7 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, SpellInfo const // Additional checks for triggered spells (ignore trap casts) if (procExtra & PROC_EX_INTERNAL_TRIGGERED && !(procFlag & PROC_FLAG_DONE_TRAP_ACTIVATION)) { - if (!(spellProto->AttributesEx3 & SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED)) + if (!spellProto->HasAttribute(SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED)) return false; } @@ -14617,7 +14617,7 @@ Aura* Unit::AddAura(uint32 spellId, Unit* target) if (!spellInfo) return NULL; - if (!target->IsAlive() && !(spellInfo->Attributes & SPELL_ATTR0_PASSIVE) && !(spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_DEAD)) + if (!target->IsAlive() && !spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE) && !spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_DEAD)) return NULL; return AddAura(spellInfo, MAX_EFFECT_MASK, target); diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index c30b8c7a2dd..8a366febe3d 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -94,7 +94,7 @@ void WorldSession::HandlePetAction(WorldPacket& recvData) SpellInfo const* spell = (flag == ACT_ENABLED || flag == ACT_PASSIVE) ? sSpellMgr->GetSpellInfo(spellid) : NULL; if (!spell) return; - if (!(spell->Attributes & SPELL_ATTR0_CASTABLE_WHILE_DEAD)) + if (!spell->HasAttribute(SPELL_ATTR0_CASTABLE_WHILE_DEAD)) return; } diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index 54a3939ef99..28a6e4746d8 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -462,7 +462,7 @@ void WorldSession::HandleCancelAuraOpcode(WorldPacket& recvPacket) return; // not allow remove spells with attr SPELL_ATTR0_CANT_CANCEL - if (spellInfo->Attributes & SPELL_ATTR0_CANT_CANCEL) + if (spellInfo->HasAttribute(SPELL_ATTR0_CANT_CANCEL)) return; // channeled spell case (it currently cast then) diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index 7905f96c27c..291a8688b79 100644 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -191,6 +191,12 @@ void InstanceScript::UpdateDoorState(GameObject* door) door->SetGoState(open ? GO_STATE_ACTIVE : GO_STATE_READY); } +BossInfo* InstanceScript::GetBossInfo(uint32 id) +{ + ASSERT(id < bosses.size()); + return &bosses[id]; +} + void InstanceScript::AddObject(Creature* obj, bool add) { ObjectInfoMap::const_iterator j = _creatureInfo.find(obj->GetEntry()); diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index fa2b4e83fe7..fe1dc60f724 100644 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -260,12 +260,16 @@ class InstanceScript : public ZoneScript void AddObject(GameObject* obj, bool add); void AddObject(WorldObject* obj, uint32 type, bool add); - void AddDoor(GameObject* door, bool add); + virtual void AddDoor(GameObject* door, bool add); void AddMinion(Creature* minion, bool add); - void UpdateDoorState(GameObject* door); + virtual void UpdateDoorState(GameObject* door); void UpdateMinionState(Creature* minion, EncounterState state); + // Exposes private data that should never be modified unless exceptional cases. + // Pay very much attention at how the returned BossInfo data is modified to avoid issues. + BossInfo* GetBossInfo(uint32 id); + // Instance Load and Save bool ReadSaveDataHeaders(std::istringstream& data); void ReadSaveDataBossStates(std::istringstream& data); diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index a1c67a6aec9..828afa696c9 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -1843,7 +1843,7 @@ void LoadLootTemplates_Spell() { // not report about not trainable spells (optionally supported by DB) // ignore 61756 (Northrend Inscription Research (FAST QA VERSION) for example - if (!(spellInfo->Attributes & SPELL_ATTR0_NOT_SHAPESHIFT) || (spellInfo->Attributes & SPELL_ATTR0_TRADESPELL)) + if (!spellInfo->HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFT) || spellInfo->HasAttribute(SPELL_ATTR0_TRADESPELL)) { LootTemplates_Spell.ReportNonExistingId(spell_id, "Spell", spellInfo->Id); } diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index caab1652f2c..9b16ba5e77f 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -641,10 +641,11 @@ void AuraEffect::CalculatePeriodic(Unit* caster, bool resetPeriodicTimer /*= tru // Haste modifies periodic time of channeled spells if (m_spellInfo->IsChanneled()) { - if (m_spellInfo->AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION) + if (m_spellInfo->HasAttribute(SPELL_ATTR5_HASTE_AFFECT_DURATION)) caster->ModSpellCastTime(m_spellInfo, m_amplitude); } else if (m_spellInfo->AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION) + else if (caster->HasAuraTypeWithAffectMask(SPELL_AURA_PERIODIC_HASTE, m_spellInfo) || m_spellInfo->HasAttribute(SPELL_ATTR5_HASTE_AFFECT_DURATION)) m_amplitude = int32(m_amplitude * caster->GetFloatValue(UNIT_MOD_CAST_SPEED)); } } @@ -653,7 +654,7 @@ void AuraEffect::CalculatePeriodic(Unit* caster, bool resetPeriodicTimer /*= tru { m_tickNumber = m_amplitude ? GetBase()->GetDuration() / m_amplitude : 0; m_periodicTimer = m_amplitude ? GetBase()->GetDuration() % m_amplitude : 0; - if (m_spellInfo->AttributesEx5 & SPELL_ATTR5_START_PERIODIC_AT_APPLY) + if (m_spellInfo->HasAttribute(SPELL_ATTR5_START_PERIODIC_AT_APPLY)) ++m_tickNumber; } else // aura just created or reapplied @@ -666,7 +667,7 @@ void AuraEffect::CalculatePeriodic(Unit* caster, bool resetPeriodicTimer /*= tru { m_periodicTimer = 0; // Start periodic on next tick or at aura apply - if (m_amplitude && !(m_spellInfo->AttributesEx5 & SPELL_ATTR5_START_PERIODIC_AT_APPLY)) + if (m_amplitude && !m_spellInfo->HasAttribute(SPELL_ATTR5_START_PERIODIC_AT_APPLY)) m_periodicTimer += m_amplitude; } } @@ -1224,7 +1225,7 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const continue; SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); - if (!spellInfo || !(spellInfo->Attributes & (SPELL_ATTR0_PASSIVE | SPELL_ATTR0_HIDDEN_CLIENTSIDE))) + if (!spellInfo || !(spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE) || spellInfo->HasAttribute(SPELL_ATTR0_HIDDEN_CLIENTSIDE))) continue; if ((spellInfo->AttributesEx8 & SPELL_ATTR8_MASTERY_SPECIALIZATION) && !plrTarget->IsCurrentSpecMasterySpell(spellInfo)) @@ -1242,7 +1243,7 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const if (GlyphPropertiesEntry const* glyph = sGlyphPropertiesStore.LookupEntry(glyphId)) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(glyph->SpellId); - if (!spellInfo || !(spellInfo->Attributes & (SPELL_ATTR0_PASSIVE | SPELL_ATTR0_HIDDEN_CLIENTSIDE))) + if (!spellInfo || !(spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE) || spellInfo->HasAttribute(SPELL_ATTR0_HIDDEN_CLIENTSIDE))) continue; if (spellInfo->Stances & (1 << (GetMiscValue() - 1))) @@ -3316,7 +3317,7 @@ void AuraEffect::HandleModStateImmunityMask(AuraApplication const* aurApp, uint8 for (std::list ::iterator iter = aura_immunity_list.begin(); iter != aura_immunity_list.end(); ++iter) target->ApplySpellImmune(GetId(), IMMUNITY_STATE, *iter, apply); - if (apply && GetSpellInfo()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY) + if (apply && GetSpellInfo()->HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)) { target->RemoveAurasWithMechanic(mechanic_immunity_list, AURA_REMOVE_BY_DEFAULT, GetId()); for (std::list ::iterator iter = aura_immunity_list.begin(); iter != aura_immunity_list.end(); ++iter) @@ -3373,7 +3374,7 @@ void AuraEffect::HandleModMechanicImmunity(AuraApplication const* aurApp, uint8 break; } - if (apply && GetSpellInfo()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY) + if (apply && GetSpellInfo()->HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)) target->RemoveAurasWithMechanic(mechanic, AURA_REMOVE_BY_DEFAULT, GetId()); } @@ -3409,7 +3410,7 @@ void AuraEffect::HandleAuraModStateImmunity(AuraApplication const* aurApp, uint8 target->ApplySpellImmune(GetId(), IMMUNITY_STATE, GetMiscValue(), apply); - if (apply && GetSpellInfo()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY) + if (apply && GetSpellInfo()->HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)) target->RemoveAurasByType(AuraType(GetMiscValue()), ObjectGuid::Empty, GetBase()); } @@ -3445,13 +3446,13 @@ void AuraEffect::HandleAuraModSchoolImmunity(AuraApplication const* aurApp, uint target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); // remove all flag auras (they are positive, but they must be removed when you are immune) - if (GetSpellInfo()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY - && GetSpellInfo()->AttributesEx2 & SPELL_ATTR2_DAMAGE_REDUCED_SHIELD) + if (GetSpellInfo()->HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY) + && GetSpellInfo()->HasAttribute(SPELL_ATTR2_DAMAGE_REDUCED_SHIELD)) target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); /// @todo optimalize this cycle - use RemoveAurasWithInterruptFlags call or something else if ((apply) - && GetSpellInfo()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY + && GetSpellInfo()->HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY) && GetSpellInfo()->IsPositive()) //Only positive immunity removes auras { uint32 school_mask = GetMiscValue(); @@ -5893,7 +5894,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const else damage = uint32(target->CountPctFromMaxHealth(damage)); - if (!(m_spellInfo->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE)) + if (!m_spellInfo->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE)) if (m_spellInfo->Effects[m_effIndex].IsTargetingArea() || isAreaAura) { damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask)); @@ -5910,8 +5911,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target); int32 dmg = damage; - - if (!(GetSpellInfo()->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE)) + if (!GetSpellInfo()->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE)) caster->ApplyResilience(target, &dmg); damage = dmg; @@ -5983,7 +5983,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c damage = damageReductedArmor; } - if (!(m_spellInfo->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE)) + if (!m_spellInfo->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE)) if (m_spellInfo->Effects[m_effIndex].IsTargetingArea() || isAreaAura) { damage = uint32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask)); @@ -6000,7 +6000,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target); int32 dmg = damage; - if (!(GetSpellInfo()->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE)) + if (!GetSpellInfo()->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE)) caster->ApplyResilience(target, &dmg); damage = dmg; @@ -6076,7 +6076,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const } // heal for caster damage (must be alive) - if (target != caster && GetSpellInfo()->AttributesEx2 & SPELL_ATTR2_HEALTH_FUNNEL && !caster->IsAlive()) + if (target != caster && GetSpellInfo()->HasAttribute(SPELL_ATTR2_HEALTH_FUNNEL) && !caster->IsAlive()) return; // don't regen when permanent aura target has full power @@ -6161,7 +6161,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const // Health Funnel // damage caster for heal amount - if (target != caster && GetSpellInfo()->AttributesEx2 & SPELL_ATTR2_HEALTH_FUNNEL && GetSpellInfo()->Id != 755) + if (target != caster && GetSpellInfo()->HasAttribute(SPELL_ATTR2_HEALTH_FUNNEL)) { uint32 funnelDamage = GetSpellInfo()->ManaPerSecond; // damage is not affected by spell power @@ -6288,7 +6288,7 @@ void AuraEffect::HandlePeriodicEnergizeAuraTick(Unit* target, Unit* caster) cons { Powers powerType = Powers(GetMiscValue()); - if (target->GetTypeId() == TYPEID_PLAYER && target->getPowerType() != powerType && !(m_spellInfo->AttributesEx7 & SPELL_ATTR7_CAN_RESTORE_SECONDARY_POWER)) + if (target->GetTypeId() == TYPEID_PLAYER && target->getPowerType() != powerType && !m_spellInfo->HasAttribute(SPELL_ATTR7_CAN_RESTORE_SECONDARY_POWER)) return; if (!target->IsAlive() || !target->GetMaxPower(powerType)) diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index e18b605f088..fa1577e7355 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -194,7 +194,7 @@ void AuraApplication::BuildUpdatePacket(ByteBuffer& data, bool remove) const Aura const* aura = GetBase(); data << uint32(aura->GetId()); uint32 flags = _flags; - if (aura->GetMaxDuration() > 0 && !(aura->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_HIDE_DURATION)) + if (aura->GetMaxDuration() > 0 && !aura->GetSpellInfo()->HasAttribute(SPELL_ATTR5_HIDE_DURATION)) flags |= AFLAG_DURATION; data << uint16(flags); data << uint8(aura->GetCasterLevel()); @@ -763,7 +763,7 @@ void Aura::RefreshDuration(bool withMods) { int32 duration = m_spellInfo->GetMaxDuration(); // Calculate duration of periodics affected by haste. - if (caster->HasAuraTypeWithAffectMask(SPELL_AURA_PERIODIC_HASTE, m_spellInfo) || m_spellInfo->AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION) + if (caster->HasAuraTypeWithAffectMask(SPELL_AURA_PERIODIC_HASTE, m_spellInfo) || m_spellInfo->HasAttribute(SPELL_ATTR5_HASTE_AFFECT_DURATION)) duration = int32(duration * caster->GetFloatValue(UNIT_MOD_CAST_SPEED)); SetMaxDuration(duration); @@ -1642,7 +1642,7 @@ bool Aura::CanStackWith(Aura const* existingAura) const if (existingAura->GetSpellInfo()->IsChanneled()) return true; - if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_STACK_FOR_DIFF_CASTERS) + if (m_spellInfo->HasAttribute(SPELL_ATTR3_STACK_FOR_DIFF_CASTERS)) return true; // check same periodic auras @@ -1694,7 +1694,7 @@ bool Aura::CanStackWith(Aura const* existingAura) const if (m_spellInfo->IsMultiSlotAura() && !IsArea()) return true; if (GetCastItemGUID() && existingAura->GetCastItemGUID()) - if (GetCastItemGUID() != existingAura->GetCastItemGUID() && (m_spellInfo->AttributesCu & SPELL_ATTR0_CU_ENCHANT_PROC)) + if (GetCastItemGUID() != existingAura->GetCastItemGUID() && m_spellInfo->HasAttribute(SPELL_ATTR0_CU_ENCHANT_PROC)) return true; // same spell with same caster should not stack return false; diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index ac45461b333..6abcd578411 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -161,8 +161,8 @@ class Aura { return GetCasterGUID() == target->GetGUID() && m_spellInfo->Stances - && !(m_spellInfo->AttributesEx2 & SPELL_ATTR2_NOT_NEED_SHAPESHIFT) - && !(m_spellInfo->Attributes & SPELL_ATTR0_NOT_SHAPESHIFT); + && !m_spellInfo->HasAttribute(SPELL_ATTR2_NOT_NEED_SHAPESHIFT) + && !m_spellInfo->HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFT); } bool CanBeSaved() const; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 290560087b6..e4b49322c9d 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -514,7 +514,7 @@ SpellValue::SpellValue(SpellInfo const* proto) Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID, bool skipCheck) : m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)), -m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster) +m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster) , m_spellValue(new SpellValue(m_spellInfo)), m_preGeneratedPath(PathGenerator(m_caster)) { m_customError = SPELL_CUSTOM_ERROR_NONE; @@ -535,7 +535,7 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme switch (m_spellInfo->DmgClass) { case SPELL_DAMAGE_CLASS_MELEE: - if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_REQ_OFFHAND) + if (m_spellInfo->HasAttribute(SPELL_ATTR3_REQ_OFFHAND)) m_attackType = OFF_ATTACK; else m_attackType = BASE_ATTACK; @@ -545,7 +545,7 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme break; default: // Wands - if (m_spellInfo->AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG) + if (m_spellInfo->HasAttribute(SPELL_ATTR2_AUTOREPEAT_FLAG)) m_attackType = RANGED_ATTACK; else m_attackType = BASE_ATTACK; @@ -576,7 +576,7 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme m_spellState = SPELL_STATE_NULL; _triggeredCastFlags = triggerFlags; - if (info->AttributesEx4 & SPELL_ATTR4_CAN_CAST_WHILE_CASTING) + if (info->HasAttribute(SPELL_ATTR4_CAN_CAST_WHILE_CASTING)) _triggeredCastFlags = TriggerCastFlags(uint32(_triggeredCastFlags) | TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_CAST_DIRECTLY); m_CastItem = NULL; @@ -617,8 +617,8 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme // Determine if spell can be reflected back to the caster // Patch 1.2 notes: Spell Reflection no longer reflects abilities - m_canReflect = m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && !(m_spellInfo->Attributes & SPELL_ATTR0_ABILITY) - && !(m_spellInfo->AttributesEx & SPELL_ATTR1_CANT_BE_REFLECTED) && !(m_spellInfo->Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) + m_canReflect = m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && !m_spellInfo->HasAttribute(SPELL_ATTR0_ABILITY) + && !m_spellInfo->HasAttribute(SPELL_ATTR1_CANT_BE_REFLECTED) && !m_spellInfo->HasAttribute(SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) && !m_spellInfo->IsPassive() && !m_spellInfo->IsPositive(); CleanupTargetList(); @@ -1745,11 +1745,11 @@ uint32 Spell::GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList* default: break; } - if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_DEAD)) + if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_DEAD)) retMask &= ~GRID_MAP_TYPE_MASK_CORPSE; - if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS) + if (m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS)) retMask &= GRID_MAP_TYPE_MASK_CORPSE | GRID_MAP_TYPE_MASK_PLAYER; - if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_GHOSTS) + if (m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_GHOSTS)) retMask &= GRID_MAP_TYPE_MASK_PLAYER; if (condList) @@ -1839,7 +1839,7 @@ void Spell::SearchChainTargets(std::list& targets, uint32 chainTar } // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los - bool isBouncingFar = (m_spellInfo->AttributesEx4 & SPELL_ATTR4_AREA_TARGET_CHAIN + bool isBouncingFar = (m_spellInfo->HasAttribute(SPELL_ATTR4_AREA_TARGET_CHAIN) || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC); @@ -1940,7 +1940,7 @@ void Spell::prepareDataForTriggerSystem(AuraEffect const* /*triggeredByAura*/) break; case SPELL_DAMAGE_CLASS_RANGED: // Auto attack - if (m_spellInfo->AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG) + if (m_spellInfo->HasAttribute(SPELL_ATTR2_AUTOREPEAT_FLAG)) { m_procAttacker = PROC_FLAG_DONE_RANGED_AUTO_ATTACK; m_procVictim = PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK; @@ -1954,7 +1954,7 @@ void Spell::prepareDataForTriggerSystem(AuraEffect const* /*triggeredByAura*/) default: if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && m_spellInfo->EquippedItemSubClassMask & (1<AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG) // Wands auto attack + && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTOREPEAT_FLAG)) // Wands auto attack { m_procAttacker = PROC_FLAG_DONE_RANGED_AUTO_ATTACK; m_procVictim = PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK; @@ -1987,8 +1987,8 @@ void Spell::prepareDataForTriggerSystem(AuraEffect const* /*triggeredByAura*/) if (!(m_procAttacker & PROC_FLAG_DONE_RANGED_AUTO_ATTACK)) { if (_triggeredCastFlags & TRIGGERED_DISALLOW_PROC_EVENTS && - (m_spellInfo->AttributesEx2 & SPELL_ATTR2_TRIGGERED_CAN_TRIGGER_PROC || - m_spellInfo->AttributesEx3 & SPELL_ATTR3_TRIGGERED_CAN_TRIGGER_PROC_2)) + (m_spellInfo->HasAttribute(SPELL_ATTR2_TRIGGERED_CAN_TRIGGER_PROC) || + m_spellInfo->HasAttribute(SPELL_ATTR3_TRIGGERED_CAN_TRIGGER_PROC_2))) m_procEx |= PROC_EX_INTERNAL_CANT_PROC; else if (_triggeredCastFlags & TRIGGERED_DISALLOW_PROC_EVENTS) m_procEx |= PROC_EX_INTERNAL_TRIGGERED; @@ -2281,7 +2281,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) m_spellAura = NULL; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied //Spells with this flag cannot trigger if effect is cast on self - bool canEffectTrigger = !(m_spellInfo->AttributesEx3 & SPELL_ATTR3_CANT_TRIGGER_PROC) && unitTarget->CanProc() && (CanExecuteTriggersOnHit(mask) || missInfo == SPELL_MISS_IMMUNE || missInfo == SPELL_MISS_IMMUNE2); + bool canEffectTrigger = !m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_PROC) && unitTarget->CanProc() && (CanExecuteTriggersOnHit(mask) || missInfo == SPELL_MISS_IMMUNE || missInfo == SPELL_MISS_IMMUNE2); Unit* spellHitTarget = NULL; if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target @@ -2401,7 +2401,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) if (canEffectTrigger && missInfo != SPELL_MISS_REFLECT) { caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell); - if (caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->Attributes & SPELL_ATTR0_STOP_ATTACK_TARGET) == 0 && + if (caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->HasAttribute(SPELL_ATTR0_STOP_ATTACK_TARGET) == 0 && (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED)) caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx); } @@ -2421,7 +2421,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) caster->ProcDamageAndSpell(unit, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell); // Failed Pickpocket, reveal rogue - if (missInfo == SPELL_MISS_RESIST && m_spellInfo->AttributesCu & SPELL_ATTR0_CU_PICKPOCKET && unitTarget->GetTypeId() == TYPEID_UNIT) + if (missInfo == SPELL_MISS_RESIST && m_spellInfo->HasAttribute(SPELL_ATTR0_CU_PICKPOCKET) && unitTarget->GetTypeId() == TYPEID_UNIT) { m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK); if (unitTarget->ToCreature()->IsAIEnabled) @@ -2431,9 +2431,9 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) if (missInfo != SPELL_MISS_EVADE && !m_caster->IsFriendlyTo(unit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL))) { - m_caster->CombatStart(unit, !(m_spellInfo->AttributesEx3 & SPELL_ATTR3_NO_INITIAL_AGGRO)); + m_caster->CombatStart(unit, !m_spellInfo->HasAttribute(SPELL_ATTR3_NO_INITIAL_AGGRO)); - if (m_spellInfo->AttributesCu & SPELL_ATTR0_CU_AURA_CC) + if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_AURA_CC)) if (!unit->IsStandState()) unit->SetStandState(UNIT_STAND_STATE_STAND); } @@ -2504,7 +2504,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA { unit->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_HITBYSPELL); /// @todo This is a hack. But we do not know what types of stealth should be interrupted by CC - if ((m_spellInfo->AttributesCu & SPELL_ATTR0_CU_AURA_CC) && unit->IsControlledByPlayer()) + if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_AURA_CC) && unit->IsControlledByPlayer()) unit->RemoveAurasByType(SPELL_AURA_MOD_STEALTH); } else if (m_caster->IsFriendlyTo(unit)) @@ -2522,7 +2522,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA if (m_caster->GetTypeId() == TYPEID_PLAYER) m_caster->ToPlayer()->UpdatePvP(true); } - if (unit->IsInCombat() && !(m_spellInfo->AttributesEx3 & SPELL_ATTR3_NO_INITIAL_AGGRO)) + if (unit->IsInCombat() && !m_spellInfo->HasAttribute(SPELL_ATTR3_NO_INITIAL_AGGRO)) { m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit); unit->getHostileRefManager().threatAssist(m_caster, 0.0f); @@ -3201,7 +3201,7 @@ void Spell::cast(bool skipCheck) SendSpellGo(); // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells - if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled()) || m_spellInfo->AttributesEx4 & SPELL_ATTR4_UNK4) + if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled()) || m_spellInfo->HasAttribute(SPELL_ATTR4_UNK4)) { // Remove used for cast item if need (it can be already NULL after TakeReagents call // in case delayed spell remove item at cast delay start @@ -3606,7 +3606,7 @@ void Spell::finish(bool ok) break; } } - if (!found && !(m_spellInfo->AttributesEx2 & SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS)) + if (!found && !m_spellInfo->HasAttribute(SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS)) { m_caster->resetAttackTimer(BASE_ATTACK); if (m_caster->haveOffhandWeapon()) @@ -3632,7 +3632,7 @@ void Spell::finish(bool ok) } // Stop Attack for some spells - if (m_spellInfo->Attributes & SPELL_ATTR0_STOP_ATTACK_TARGET) + if (m_spellInfo->HasAttribute(SPELL_ATTR0_STOP_ATTACK_TARGET)) m_caster->AttackStop(); } @@ -4594,8 +4594,8 @@ void Spell::HandleThreatSpells() if (m_UniqueTargetInfo.empty()) return; - if ((m_spellInfo->AttributesEx & SPELL_ATTR1_NO_THREAT) || - (m_spellInfo->AttributesEx3 & SPELL_ATTR3_NO_INITIAL_AGGRO)) + if (m_spellInfo->HasAttribute(SPELL_ATTR1_NO_THREAT) || + m_spellInfo->HasAttribute(SPELL_ATTR3_NO_INITIAL_AGGRO)) return; float threat = 0.0f; @@ -4606,7 +4606,7 @@ void Spell::HandleThreatSpells() threat += threatEntry->flatMod; } - else if ((m_spellInfo->AttributesCu & SPELL_ATTR0_CU_NO_INITIAL_THREAT) == 0) + else if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_NO_INITIAL_THREAT) == 0) threat += m_spellInfo->SpellLevel; // past this point only multiplicative effects occur @@ -4701,11 +4701,11 @@ void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOT SpellCastResult Spell::CheckCast(bool strict) { // check death state - if (!m_caster->IsAlive() && !(m_spellInfo->Attributes & SPELL_ATTR0_PASSIVE) && !((m_spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_DEAD) || (IsTriggered() && !m_triggeredByAuraSpell))) + if (!m_caster->IsAlive() && !m_spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE) && !(m_spellInfo->HasAttribute(SPELL_ATTR0_CASTABLE_WHILE_DEAD) || (IsTriggered() && !m_triggeredByAuraSpell))) return SPELL_FAILED_CASTER_DEAD; // check cooldowns to prevent cheating - if (m_caster->GetTypeId() == TYPEID_PLAYER && !(m_spellInfo->Attributes & SPELL_ATTR0_PASSIVE)) + if (m_caster->GetTypeId() == TYPEID_PLAYER && !m_spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE)) { //can cast triggered (by aura only?) spells while have this flag if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_AURASTATE) && m_caster->ToPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY)) @@ -4724,7 +4724,7 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_NOT_READY; } - if (m_spellInfo->AttributesEx7 & SPELL_ATTR7_IS_CHEAT_SPELL && !m_caster->HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_ALLOW_CHEAT_SPELLS)) + if (m_spellInfo->HasAttribute(SPELL_ATTR7_IS_CHEAT_SPELL) && !m_caster->HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_ALLOW_CHEAT_SPELLS)) { m_customError = SPELL_CUSTOM_ERROR_GM_ONLY; return SPELL_FAILED_CUSTOM_ERROR; @@ -4742,11 +4742,11 @@ SpellCastResult Spell::CheckCast(bool strict) if (m_caster->GetTypeId() == TYPEID_PLAYER && VMAP::VMapFactory::createOrGetVMapManager()->isLineOfSightCalcEnabled()) { - if (m_spellInfo->Attributes & SPELL_ATTR0_OUTDOORS_ONLY && + if (m_spellInfo->HasAttribute(SPELL_ATTR0_OUTDOORS_ONLY) && !m_caster->GetMap()->IsOutdoors(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ())) return SPELL_FAILED_ONLY_OUTDOORS; - if (m_spellInfo->Attributes & SPELL_ATTR0_INDOORS_ONLY && + if (m_spellInfo->HasAttribute(SPELL_ATTR0_INDOORS_ONLY) && m_caster->GetMap()->IsOutdoors(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ())) return SPELL_FAILED_ONLY_INDOORS; } @@ -4772,7 +4772,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (shapeError != SPELL_CAST_OK) return shapeError; - if ((m_spellInfo->Attributes & SPELL_ATTR0_ONLY_STEALTHED) && !(m_caster->HasStealthAura())) + if (m_spellInfo->HasAttribute(SPELL_ATTR0_ONLY_STEALTHED) && !(m_caster->HasStealthAura())) return SPELL_FAILED_ONLY_STEALTHED; } } @@ -4859,7 +4859,7 @@ SpellCastResult Spell::CheckCast(bool strict) // those spells may have incorrect target entries or not filled at all (for example 15332) // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead // also, such casts shouldn't be sent to client - if (!((m_spellInfo->Attributes & SPELL_ATTR0_PASSIVE) && (!m_targets.GetUnitTarget() || m_targets.GetUnitTarget() == m_caster))) + if (!(m_spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE) && (!m_targets.GetUnitTarget() || m_targets.GetUnitTarget() == m_caster))) { // Check explicit target for m_originalCaster - todo: get rid of such workarounds SpellCastResult castResult = m_spellInfo->CheckExplicitTarget(m_originalCaster ? m_originalCaster : m_caster, m_targets.GetObjectTarget(), m_targets.GetItemTarget()); @@ -4876,11 +4876,11 @@ SpellCastResult Spell::CheckCast(bool strict) if (target != m_caster) { // Must be behind the target - if ((m_spellInfo->AttributesCu & SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast(M_PI), m_caster)) + if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast(M_PI), m_caster)) return SPELL_FAILED_NOT_BEHIND; // Target must be facing you - if ((m_spellInfo->AttributesCu & SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast(M_PI), m_caster)) + if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast(M_PI), m_caster)) return SPELL_FAILED_NOT_INFRONT; if (m_caster->GetEntry() != WORLD_TRIGGER) // Ignore LOS for gameobjects casts (wrongly cast by a trigger) @@ -4890,7 +4890,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (DynamicObject* dynObj = m_caster->GetDynObject(m_triggeredByAuraSpell->Id)) losTarget = dynObj; - if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !target->IsWithinLOSInMap(losTarget)) + if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !target->IsWithinLOSInMap(losTarget)) return SPELL_FAILED_LINE_OF_SIGHT; } } @@ -4902,7 +4902,7 @@ SpellCastResult Spell::CheckCast(bool strict) float x, y, z; m_targets.GetDstPos()->GetPosition(x, y, z); - if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !m_caster->IsWithinLOS(x, y, z)) + if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !m_caster->IsWithinLOS(x, y, z)) return SPELL_FAILED_LINE_OF_SIGHT; } @@ -4923,7 +4923,7 @@ SpellCastResult Spell::CheckCast(bool strict) } // Spell cast only in battleground - if ((m_spellInfo->AttributesEx3 & SPELL_ATTR3_BATTLEGROUND) && m_caster->GetTypeId() == TYPEID_PLAYER) + if (m_spellInfo->HasAttribute(SPELL_ATTR3_BATTLEGROUND) && m_caster->GetTypeId() == TYPEID_PLAYER) if (!m_caster->ToPlayer()->InBattleground()) return SPELL_FAILED_ONLY_BATTLEGROUNDS; @@ -4949,7 +4949,7 @@ SpellCastResult Spell::CheckCast(bool strict) // not let players cast spells at mount (and let do it to creatures) if (m_caster->IsMounted() && m_caster->GetTypeId() == TYPEID_PLAYER && !(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE) && - !m_spellInfo->IsPassive() && !(m_spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_MOUNTED)) + !m_spellInfo->IsPassive() && !m_spellInfo->HasAttribute(SPELL_ATTR0_CASTABLE_WHILE_MOUNTED)) { if (m_caster->IsInFlight()) return SPELL_FAILED_NOT_ON_TAXI; @@ -5588,7 +5588,7 @@ SpellCastResult Spell::CheckPetCast(Unit* target) SpellCastResult Spell::CheckCasterAuras() const { // spells totally immuned to caster auras (wsg flag drop, give marks etc) - if (m_spellInfo->AttributesEx6 & SPELL_ATTR6_IGNORE_CASTER_AURAS) + if (m_spellInfo->HasAttribute(SPELL_ATTR6_IGNORE_CASTER_AURAS)) return SPELL_CAST_OK; uint8 school_immune = 0; @@ -5597,7 +5597,7 @@ SpellCastResult Spell::CheckCasterAuras() const // Check if the spell grants school or mechanic immunity. // We use bitmasks so the loop is done only once and not on every aura check below. - if (m_spellInfo->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY) + if (m_spellInfo->HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)) { for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { @@ -5613,7 +5613,7 @@ SpellCastResult Spell::CheckCasterAuras() const mechanic_immune = IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK; } - bool usableInStun = (m_spellInfo->AttributesEx5 & SPELL_ATTR5_USABLE_WHILE_STUNNED) != 0; + bool usableInStun = m_spellInfo->HasAttribute(SPELL_ATTR5_USABLE_WHILE_STUNNED); // Glyph of Pain Suppression // Allow Pain Suppression and Guardian Spirit to be cast while stunned @@ -5646,9 +5646,9 @@ SpellCastResult Spell::CheckCasterAuras() const else prevented_reason = SPELL_FAILED_STUNNED; } - else if (unitflag & UNIT_FLAG_CONFUSED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR5_USABLE_WHILE_CONFUSED)) + else if (unitflag & UNIT_FLAG_CONFUSED && !m_spellInfo->HasAttribute(SPELL_ATTR5_USABLE_WHILE_CONFUSED)) prevented_reason = SPELL_FAILED_CONFUSED; - else if (unitflag & UNIT_FLAG_FLEEING && !(m_spellInfo->AttributesEx5 & SPELL_ATTR5_USABLE_WHILE_FEARED)) + else if (unitflag & UNIT_FLAG_FLEEING && !m_spellInfo->HasAttribute(SPELL_ATTR5_USABLE_WHILE_FEARED)) prevented_reason = SPELL_FAILED_FLEEING; else if (unitflag & UNIT_FLAG_SILENCED && m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) prevented_reason = SPELL_FAILED_SILENCED; @@ -5668,7 +5668,7 @@ SpellCastResult Spell::CheckCasterAuras() const SpellInfo const* auraInfo = aura->GetSpellInfo(); if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune) continue; - if (auraInfo->GetSchoolMask() & school_immune && !(auraInfo->AttributesEx & SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE)) + if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE)) continue; if (auraInfo->GetDispelMask() & dispel_immune) continue; @@ -5686,11 +5686,11 @@ SpellCastResult Spell::CheckCasterAuras() const return SPELL_FAILED_STUNNED; break; case SPELL_AURA_MOD_CONFUSE: - if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR5_USABLE_WHILE_CONFUSED)) + if (!m_spellInfo->HasAttribute(SPELL_ATTR5_USABLE_WHILE_CONFUSED)) return SPELL_FAILED_CONFUSED; break; case SPELL_AURA_MOD_FEAR: - if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR5_USABLE_WHILE_FEARED)) + if (!m_spellInfo->HasAttribute(SPELL_ATTR5_USABLE_WHILE_FEARED)) return SPELL_FAILED_FLEEING; break; case SPELL_AURA_MOD_SILENCE: @@ -6319,7 +6319,7 @@ SpellCastResult Spell::CheckItems() if (!(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) && m_spellInfo->EquippedItemClass >=0) { // main hand weapon required - if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_MAIN_HAND) + if (m_spellInfo->HasAttribute(SPELL_ATTR3_MAIN_HAND)) { Item* item = m_caster->ToPlayer()->GetWeaponForAttack(BASE_ATTACK); @@ -6333,7 +6333,7 @@ SpellCastResult Spell::CheckItems() } // offhand hand weapon required - if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_REQ_OFFHAND) + if (m_spellInfo->HasAttribute(SPELL_ATTR3_REQ_OFFHAND)) { Item* item = m_caster->ToPlayer()->GetWeaponForAttack(OFF_ATTACK); @@ -6522,11 +6522,11 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* lo } // check for ignore LOS on the effect itself - if (m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS || DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS)) + if (m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) || DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS)) return true; // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour - if (IsTriggered() && m_triggeredByAuraSpell && (m_triggeredByAuraSpell->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS || DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_triggeredByAuraSpell->Id, NULL, SPELL_DISABLE_LOS))) + if (IsTriggered() && m_triggeredByAuraSpell && (m_triggeredByAuraSpell->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) || DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_triggeredByAuraSpell->Id, NULL, SPELL_DISABLE_LOS))) return true; /// @todo shit below shouldn't be here, but it's temporary @@ -6577,7 +6577,7 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* lo bool Spell::IsNextMeleeSwingSpell() const { - return (m_spellInfo->Attributes & SPELL_ATTR0_ON_NEXT_SWING) != 0; + return m_spellInfo->HasAttribute(SPELL_ATTR0_ON_NEXT_SWING); } bool Spell::IsAutoActionResetSpell() const @@ -6756,7 +6756,7 @@ void Spell::HandleLaunchPhase() if (m_applyMultiplierMask & (1 << i)) multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this); - bool usesAmmo = (m_spellInfo->AttributesCu & SPELL_ATTR0_CU_DIRECT_DAMAGE) != 0; + bool usesAmmo = m_spellInfo->HasAttribute(SPELL_ATTR0_CU_DIRECT_DAMAGE); for (std::list::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) { @@ -7215,7 +7215,7 @@ bool Spell::CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToC bool Spell::CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const* triggeredByAura) const { - bool only_on_caster = (triggeredByAura && (triggeredByAura->AttributesEx4 & SPELL_ATTR4_PROC_ONLY_ON_CASTER)); + bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_PROC_ONLY_ON_CASTER)); // If triggeredByAura has SPELL_ATTR4_PROC_ONLY_ON_CASTER then it can only proc on a cast spell with TARGET_UNIT_CASTER for (uint8 i = 0;i < MAX_SPELL_EFFECTS; ++i) { @@ -7454,12 +7454,12 @@ WorldObjectSpellConeTargetCheck::WorldObjectSpellConeTargetCheck(float coneAngle bool WorldObjectSpellConeTargetCheck::operator()(WorldObject* target) { - if (_spellInfo->AttributesCu & SPELL_ATTR0_CU_CONE_BACK) + if (_spellInfo->HasAttribute(SPELL_ATTR0_CU_CONE_BACK)) { if (!_caster->isInBack(target, _coneAngle)) return false; } - else if (_spellInfo->AttributesCu & SPELL_ATTR0_CU_CONE_LINE) + else if (_spellInfo->HasAttribute(SPELL_ATTR0_CU_CONE_LINE)) { if (!_caster->HasInLine(target, _caster->GetObjectSize())) return false; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 720667db7cc..33d5b382b1c 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -345,7 +345,7 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) case SPELLFAMILY_GENERIC: { // Meteor like spells (divided damage to targets) - if (m_spellInfo->AttributesCu & SPELL_ATTR0_CU_SHARE_DAMAGE) + if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_SHARE_DAMAGE)) { uint32 count = 0; for (std::list::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) @@ -1593,7 +1593,7 @@ void Spell::EffectEnergize(SpellEffIndex effIndex) Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue); - if (unitTarget->GetTypeId() == TYPEID_PLAYER && unitTarget->getPowerType() != power && !(m_spellInfo->AttributesEx7 & SPELL_ATTR7_CAN_RESTORE_SECONDARY_POWER)) + if (unitTarget->GetTypeId() == TYPEID_PLAYER && unitTarget->getPowerType() != power && !m_spellInfo->HasAttribute(SPELL_ATTR7_CAN_RESTORE_SECONDARY_POWER)) return; if (unitTarget->GetMaxPower(power) == 0) @@ -1702,7 +1702,7 @@ void Spell::EffectEnergizePct(SpellEffIndex effIndex) Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue); - if (unitTarget->GetTypeId() == TYPEID_PLAYER && unitTarget->getPowerType() != power && !(m_spellInfo->AttributesEx7 & SPELL_ATTR7_CAN_RESTORE_SECONDARY_POWER)) + if (unitTarget->GetTypeId() == TYPEID_PLAYER && unitTarget->getPowerType() != power && !m_spellInfo->HasAttribute(SPELL_ATTR7_CAN_RESTORE_SECONDARY_POWER)) return; uint32 maxPower = unitTarget->GetMaxPower(power); @@ -5078,13 +5078,13 @@ void Spell::EffectStealBeneficialBuff(SpellEffIndex effIndex) if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask) { // Need check for passive? this - if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->AttributesEx4 & SPELL_ATTR4_NOT_STEALABLE) + if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_NOT_STEALABLE)) continue; // The charges / stack amounts don't count towards the total number of auras that can be dispelled. // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell // Polymorph instead of 1 / (5 + 1) -> 16%. - bool dispel_charges = (aura->GetSpellInfo()->AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES) != 0; + bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_CHARGES); uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount(); if (charges > 0) steal_list.push_back(std::make_pair(aura, charges)); diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 8bf19c90a6c..9b468d3fc61 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -525,7 +525,7 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const ======= */ if (!caster->IsControlledByPlayer() && _spellInfo->SpellLevel && _spellInfo->SpellLevel != caster->getLevel() && - !basePointsPerLevel && (_spellInfo->Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION)) + !basePointsPerLevel && _spellInfo->HasAttribute(SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION)) { bool canEffectScale = false; switch (Effect) @@ -1212,14 +1212,14 @@ bool SpellInfo::NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) con bool SpellInfo::IsPassive() const { - return (Attributes & SPELL_ATTR0_PASSIVE) != 0; + return HasAttribute(SPELL_ATTR0_PASSIVE); } bool SpellInfo::IsAutocastable() const { - if (Attributes & SPELL_ATTR0_PASSIVE) + if (HasAttribute(SPELL_ATTR0_PASSIVE)) return false; - if (AttributesEx & SPELL_ATTR1_UNAUTOCASTABLE_BY_PET) + if (HasAttribute(SPELL_ATTR1_UNAUTOCASTABLE_BY_PET)) return false; return true; } @@ -1270,37 +1270,37 @@ bool SpellInfo::IsMultiSlotAura() const bool SpellInfo::IsStackableOnOneSlotWithDifferentCasters() const { /// TODO: Re-verify meaning of SPELL_ATTR3_STACK_FOR_DIFF_CASTERS and update conditions here - return StackAmount > 1 && !IsChanneled() && !(AttributesEx3 & SPELL_ATTR3_STACK_FOR_DIFF_CASTERS); + return StackAmount > 1 && !IsChanneled() && !HasAttribute(SPELL_ATTR3_STACK_FOR_DIFF_CASTERS); } bool SpellInfo::IsCooldownStartedOnEvent() const { - return Attributes & SPELL_ATTR0_DISABLED_WHILE_ACTIVE || (CategoryEntry && CategoryEntry->Flags & SPELL_CATEGORY_FLAG_COOLDOWN_STARTS_ON_EVENT); + return HasAttribute(SPELL_ATTR0_DISABLED_WHILE_ACTIVE) || (CategoryEntry && CategoryEntry->Flags & SPELL_CATEGORY_FLAG_COOLDOWN_STARTS_ON_EVENT); } bool SpellInfo::IsDeathPersistent() const { - return (AttributesEx3 & SPELL_ATTR3_DEATH_PERSISTENT) != 0; + return HasAttribute(SPELL_ATTR3_DEATH_PERSISTENT); } bool SpellInfo::IsRequiringDeadTarget() const { - return (AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_GHOSTS) != 0; + return HasAttribute(SPELL_ATTR3_ONLY_TARGET_GHOSTS); } bool SpellInfo::IsAllowingDeadTarget() const { - return AttributesEx2 & SPELL_ATTR2_CAN_TARGET_DEAD || Targets & (TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_CORPSE_ENEMY | TARGET_FLAG_UNIT_DEAD); + return HasAttribute(SPELL_ATTR2_CAN_TARGET_DEAD) || Targets & (TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_CORPSE_ENEMY | TARGET_FLAG_UNIT_DEAD); } bool SpellInfo::CanBeUsedInCombat() const { - return !(Attributes & SPELL_ATTR0_CANT_USED_IN_COMBAT); + return !HasAttribute(SPELL_ATTR0_CANT_USED_IN_COMBAT); } bool SpellInfo::IsPositive() const { - return !(AttributesCu & SPELL_ATTR0_CU_NEGATIVE); + return !HasAttribute(SPELL_ATTR0_CU_NEGATIVE); } bool SpellInfo::IsPositiveEffect(uint8 effIndex) const @@ -1309,27 +1309,27 @@ bool SpellInfo::IsPositiveEffect(uint8 effIndex) const { default: case 0: - return !(AttributesCu & SPELL_ATTR0_CU_NEGATIVE_EFF0); + return !HasAttribute(SPELL_ATTR0_CU_NEGATIVE_EFF0); case 1: - return !(AttributesCu & SPELL_ATTR0_CU_NEGATIVE_EFF1); + return !HasAttribute(SPELL_ATTR0_CU_NEGATIVE_EFF1); case 2: - return !(AttributesCu & SPELL_ATTR0_CU_NEGATIVE_EFF2); + return !HasAttribute(SPELL_ATTR0_CU_NEGATIVE_EFF2); } } bool SpellInfo::IsChanneled() const { - return (AttributesEx & (SPELL_ATTR1_CHANNELED_1 | SPELL_ATTR1_CHANNELED_2)) != 0; + return HasAttribute(SPELL_ATTR1_CHANNELED_1) || HasAttribute(SPELL_ATTR1_CHANNELED_2); } bool SpellInfo::NeedsComboPoints() const { - return (AttributesEx & (SPELL_ATTR1_REQ_COMBO_POINTS1 | SPELL_ATTR1_REQ_COMBO_POINTS2)) != 0; + return HasAttribute(SPELL_ATTR1_REQ_COMBO_POINTS1) || HasAttribute(SPELL_ATTR1_REQ_COMBO_POINTS2); } bool SpellInfo::IsBreakingStealth() const { - return !(AttributesEx & SPELL_ATTR1_NOT_BREAK_STEALTH); + return !HasAttribute(SPELL_ATTR1_NOT_BREAK_STEALTH); } bool SpellInfo::IsRangedWeaponSpell() const @@ -1340,12 +1340,12 @@ bool SpellInfo::IsRangedWeaponSpell() const bool SpellInfo::IsAutoRepeatRangedSpell() const { - return (AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG) != 0; + return HasAttribute(SPELL_ATTR2_AUTOREPEAT_FLAG); } bool SpellInfo::IsAffectedBySpellMods() const { - return !(AttributesEx3 & SPELL_ATTR3_NO_DONE_BONUS); + return !HasAttribute(SPELL_ATTR3_NO_DONE_BONUS); } bool SpellInfo::IsAffectedBySpellMod(SpellModifier const* mod) const @@ -1368,11 +1368,11 @@ bool SpellInfo::IsAffectedBySpellMod(SpellModifier const* mod) const bool SpellInfo::CanPierceImmuneAura(SpellInfo const* aura) const { // these spells pierce all avalible spells (Resurrection Sickness for example) - if (Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) + if (HasAttribute(SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY)) return true; // these spells (Cyclone for example) can pierce all... // ...but not these (Divine shield, Ice block, Cyclone and Banish for example) - if ((AttributesEx & SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE) && !(aura && (aura->Mechanic == MECHANIC_IMMUNE_SHIELD || aura->Mechanic == MECHANIC_INVULNERABILITY || aura->Mechanic == MECHANIC_BANISH))) + if ((HasAttribute(SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE)) && !(aura && (aura->Mechanic == MECHANIC_IMMUNE_SHIELD || aura->Mechanic == MECHANIC_INVULNERABILITY || aura->Mechanic == MECHANIC_BANISH))) return true; return false; @@ -1381,15 +1381,15 @@ bool SpellInfo::CanPierceImmuneAura(SpellInfo const* aura) const bool SpellInfo::CanDispelAura(SpellInfo const* aura) const { // These spells (like Mass Dispel) can dispell all auras, except death persistent ones (like Dungeon and Battleground Deserter) - if (Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY && !aura->IsDeathPersistent()) + if (HasAttribute(SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) && !aura->IsDeathPersistent()) return true; // These auras (like Divine Shield) can't be dispelled - if (aura->Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) + if (aura->HasAttribute(SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY)) return false; // These auras (Cyclone for example) are not dispelable - if (aura->AttributesEx & SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE) + if (aura->HasAttribute(SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE)) return false; return true; @@ -1398,7 +1398,7 @@ bool SpellInfo::CanDispelAura(SpellInfo const* aura) const bool SpellInfo::IsSingleTarget() const { // all other single target spells have if it has AttributesEx5 - if (AttributesEx5 & SPELL_ATTR5_SINGLE_TARGET_SPELL) + if (HasAttribute(SPELL_ATTR5_SINGLE_TARGET_SPELL)) return true; switch (GetSpellSpecific()) @@ -1495,7 +1495,7 @@ SpellCastResult SpellInfo::CheckShapeshift(uint32 form) const if (actAsShifted) { - if (Attributes & SPELL_ATTR0_NOT_SHAPESHIFT) // not while shapeshifted + if (HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFT)) // not while shapeshifted return SPELL_FAILED_NOT_SHAPESHIFT; else if (Stances != 0) // needs other shapeshift return SPELL_FAILED_ONLY_SHAPESHIFT; @@ -1503,7 +1503,7 @@ SpellCastResult SpellInfo::CheckShapeshift(uint32 form) const else { // needs shapeshift - if (!(AttributesEx2 & SPELL_ATTR2_NOT_NEED_SHAPESHIFT) && Stances != 0) + if (!HasAttribute(SPELL_ATTR2_NOT_NEED_SHAPESHIFT) && Stances != 0) return SPELL_FAILED_ONLY_SHAPESHIFT; } @@ -1542,7 +1542,7 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a } // continent limitation (virtual continent) - if (AttributesEx4 & SPELL_ATTR4_CAST_ONLY_IN_OUTLAND) + if (HasAttribute(SPELL_ATTR4_CAST_ONLY_IN_OUTLAND)) { uint32 v_map = GetVirtualMapForMapAndZone(map_id, zone_id); MapEntry const* mapEntry = sMapStore.LookupEntry(v_map); @@ -1551,7 +1551,7 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a } // raid instance limitation - if (AttributesEx6 & SPELL_ATTR6_NOT_IN_RAID_INSTANCE) + if (HasAttribute(SPELL_ATTR6_NOT_IN_RAID_INSTANCE)) { MapEntry const* mapEntry = sMapStore.LookupEntry(map_id); if (!mapEntry || mapEntry->IsRaid()) @@ -1666,11 +1666,11 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* target, bool implicit) const { - if (AttributesEx & SPELL_ATTR1_CANT_TARGET_SELF && caster == target) + if (HasAttribute(SPELL_ATTR1_CANT_TARGET_SELF) && caster == target) return SPELL_FAILED_BAD_TARGETS; // check visibility - ignore stealth for implicit (area) targets - if (!(AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE) && !caster->CanSeeOrDetect(target, implicit)) + if (!HasAttribute(SPELL_ATTR6_CAN_TARGET_INVISIBLE) && !caster->CanSeeOrDetect(target, implicit)) return SPELL_FAILED_BAD_TARGETS; Unit const* unitTarget = target->ToUnit(); @@ -1678,7 +1678,7 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta // creature/player specific target checks if (unitTarget) { - if (AttributesEx & SPELL_ATTR1_CANT_TARGET_IN_COMBAT) + if (HasAttribute(SPELL_ATTR1_CANT_TARGET_IN_COMBAT)) { if (unitTarget->IsInCombat()) return SPELL_FAILED_TARGET_AFFECTING_COMBAT; @@ -1690,9 +1690,9 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta } // only spells with SPELL_ATTR3_ONLY_TARGET_GHOSTS can target ghosts - if (((AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_GHOSTS) != 0) != unitTarget->HasAuraType(SPELL_AURA_GHOST)) + if (HasAttribute(SPELL_ATTR3_ONLY_TARGET_GHOSTS) != unitTarget->HasAuraType(SPELL_AURA_GHOST)) { - if (AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_GHOSTS) + if (HasAttribute(SPELL_ATTR3_ONLY_TARGET_GHOSTS)) return SPELL_FAILED_TARGET_NOT_GHOST; else return SPELL_FAILED_BAD_TARGETS; @@ -1703,12 +1703,12 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta if (caster->GetTypeId() == TYPEID_PLAYER) { // Do not allow these spells to target creatures not tapped by us (Banish, Polymorph, many quest spells) - if (AttributesEx2 & SPELL_ATTR2_CANT_TARGET_TAPPED) + if (HasAttribute(SPELL_ATTR2_CANT_TARGET_TAPPED)) if (Creature const* targetCreature = unitTarget->ToCreature()) if (targetCreature->hasLootRecipient() && !targetCreature->isTappedBy(caster->ToPlayer())) return SPELL_FAILED_CANT_CAST_ON_TAPPED; - if (AttributesCu & SPELL_ATTR0_CU_PICKPOCKET) + if (HasAttribute(SPELL_ATTR0_CU_PICKPOCKET)) { if (unitTarget->GetTypeId() == TYPEID_PLAYER) return SPELL_FAILED_BAD_TARGETS; @@ -1748,21 +1748,21 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta else return SPELL_CAST_OK; // corpseOwner and unit specific target checks - if (AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS && !unitTarget->ToPlayer()) + if (HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS) && !unitTarget->ToPlayer()) return SPELL_FAILED_TARGET_NOT_PLAYER; if (!IsAllowingDeadTarget() && !unitTarget->IsAlive()) return SPELL_FAILED_TARGETS_DEAD; // check this flag only for implicit targets (chain and area), allow to explicitly target units for spells like Shield of Righteousness - if (implicit && AttributesEx6 & SPELL_ATTR6_CANT_TARGET_CROWD_CONTROLLED && !unitTarget->CanFreeMove()) + if (implicit && HasAttribute(SPELL_ATTR6_CANT_TARGET_CROWD_CONTROLLED) && !unitTarget->CanFreeMove()) return SPELL_FAILED_BAD_TARGETS; // checked in Unit::IsValidAttack/AssistTarget, shouldn't be checked for ENTRY targets - //if (!(AttributesEx6 & SPELL_ATTR6_CAN_TARGET_UNTARGETABLE) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) + //if (!HasAttribute(SPELL_ATTR6_CAN_TARGET_UNTARGETABLE) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) // return SPELL_FAILED_BAD_TARGETS; - //if (!(AttributesEx6 & SPELL_ATTR6_CAN_TARGET_POSSESSED_FRIENDS) + //if (!HasAttribute(SPELL_ATTR6_CAN_TARGET_POSSESSED_FRIENDS) if (!CheckTargetCreatureType(unitTarget)) { @@ -1878,7 +1878,7 @@ SpellCastResult SpellInfo::CheckVehicle(Unit const* caster) const checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK; VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(caster); - if (!(AttributesEx6 & SPELL_ATTR6_CASTABLE_WHILE_ON_VEHICLE) && !(Attributes & SPELL_ATTR0_CASTABLE_WHILE_MOUNTED) + if (!HasAttribute(SPELL_ATTR6_CASTABLE_WHILE_ON_VEHICLE) && !HasAttribute(SPELL_ATTR0_CASTABLE_WHILE_MOUNTED) && (vehicleSeat->m_flags & checkMask) != checkMask) return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; @@ -2334,7 +2334,7 @@ uint32 SpellInfo::GetRecoveryTime() const int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) const { // Spell drain all exist power on cast (Only paladin lay of Hands) - if (AttributesEx & SPELL_ATTR1_DRAIN_ALL_POWER) + if (HasAttribute(SPELL_ATTR1_DRAIN_ALL_POWER)) { // If power type - health drain all if (PowerType == POWER_HEALTH) @@ -2387,7 +2387,7 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) c } // Shiv - costs 20 + weaponSpeed*10 energy (apply only to non-triggered spell with energy cost) - if (AttributesEx4 & SPELL_ATTR4_SPELL_VS_EXTEND_COST) + if (HasAttribute(SPELL_ATTR4_SPELL_VS_EXTEND_COST)) { uint32 speed = 0; /* REVIEW - MERGE @@ -2397,7 +2397,7 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) c */ { WeaponAttackType slot = BASE_ATTACK; - if (AttributesEx3 & SPELL_ATTR3_REQ_OFFHAND) + if (HasAttribute(SPELL_ATTR3_REQ_OFFHAND)) slot = OFF_ATTACK; speed = caster->GetAttackTime(slot); @@ -2412,7 +2412,7 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) c if (!caster->IsControlledByPlayer()) { - if (Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION) + if (HasAttribute(SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION)) { GtNPCManaCostScalerEntry const* spellScaler = sGtNPCManaCostScalerStore.LookupEntry(SpellLevel - 1); GtNPCManaCostScalerEntry const* casterScaler = sGtNPCManaCostScalerStore.LookupEntry(caster->getLevel() - 1); @@ -2566,7 +2566,7 @@ void SpellInfo::_InitializeExplicitTargetMask() bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const { // not found a single positive spell with this attribute - if (Attributes & SPELL_ATTR0_NEGATIVE_1) + if (HasAttribute(SPELL_ATTR0_NEGATIVE_1)) return false; switch (SpellFamilyName) @@ -2730,7 +2730,7 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const if (Effects[effIndex].TargetA.GetTarget() != TARGET_UNIT_CASTER) return false; // but not this if this first effect (didn't find better check) - if (Attributes & SPELL_ATTR0_NEGATIVE_1 && effIndex == 0) + if (HasAttribute(SPELL_ATTR0_NEGATIVE_1) && effIndex == 0) return false; break; case SPELL_AURA_MECHANIC_IMMUNITY: diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 2eea66c1431..aa14199e42f 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -427,6 +427,16 @@ public: bool HasAura(AuraType aura) const; bool HasAreaAuraEffect() const; + inline bool HasAttribute(SpellAttr0 attribute) const { return !!(Attributes & attribute); } + inline bool HasAttribute(SpellAttr1 attribute) const { return !!(AttributesEx & attribute); } + inline bool HasAttribute(SpellAttr2 attribute) const { return !!(AttributesEx2 & attribute); } + inline bool HasAttribute(SpellAttr3 attribute) const { return !!(AttributesEx3 & attribute); } + inline bool HasAttribute(SpellAttr4 attribute) const { return !!(AttributesEx4 & attribute); } + inline bool HasAttribute(SpellAttr5 attribute) const { return !!(AttributesEx5 & attribute); } + inline bool HasAttribute(SpellAttr6 attribute) const { return !!(AttributesEx6 & attribute); } + inline bool HasAttribute(SpellAttr7 attribute) const { return !!(AttributesEx7 & attribute); } + inline bool HasAttribute(SpellCustomAttributes customAttribute) const { return !!(AttributesCu & customAttribute); } + bool IsExplicitDiscovery() const; bool IsLootCrafting() const; bool IsQuestTame() const; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index d94b2146438..ab1b7b468dd 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2293,7 +2293,7 @@ void SpellMgr::LoadEnchantCustomAttr() continue; /// @todo find a better check - if (!(spellInfo->AttributesEx2 & SPELL_ATTR2_PRESERVE_ENCHANT_IN_ARENA) || !(spellInfo->Attributes & SPELL_ATTR0_NOT_SHAPESHIFT)) + if (!spellInfo->HasAttribute(SPELL_ATTR2_PRESERVE_ENCHANT_IN_ARENA) || !spellInfo->HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFT)) continue; for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j) @@ -3768,7 +3768,7 @@ void SpellMgr::LoadSpellInfoCorrections() { case SPELLFAMILY_PALADIN: // Seals of the Pure should affect Seal of Righteousness - if (spellInfo->SpellIconID == 25 && spellInfo->Attributes & SPELL_ATTR0_PASSIVE) + if (spellInfo->SpellIconID == 25 && spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE)) spellInfo->Effects[EFFECT_0].SpellClassMask[1] |= 0x20000000; break; case SPELLFAMILY_DEATHKNIGHT: diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt index 10c01e6a128..bca1bec7f71 100644 --- a/src/server/scripts/CMakeLists.txt +++ b/src/server/scripts/CMakeLists.txt @@ -64,6 +64,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Logging ${CMAKE_SOURCE_DIR}/src/server/shared/Packets ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Updater ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities ${CMAKE_SOURCE_DIR}/src/server/ipc ${CMAKE_SOURCE_DIR}/src/server/collision diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 2d45cee2671..4f44db5b6d8 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -236,7 +236,8 @@ public: zoneId, (zoneEntry ? zoneEntry->area_name : unknown), areaId, (areaEntry ? areaEntry->area_name : unknown), object->GetPhaseMask(), - object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(), + object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation()); + handler->PSendSysMessage(LANG_GRID_POSITION, cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(), zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap, haveMMap); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp index 61dded05500..23bfd773a9b 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp @@ -255,12 +255,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript if (GetBossState(BOSS_VALKIRIES) == SPECIAL) state = DONE; break; - case DONE: - if (instance->GetPlayers().getFirst()->GetSource()->GetTeam() == ALLIANCE) - EventStage = 4020; - else - EventStage = 4030; - break; default: break; } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp index 16526b694e9..974bd4672f1 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp @@ -133,7 +133,7 @@ class npc_announcer_toc10 : public CreatureScript char const* _message = "We are ready!"; - if (player->IsInCombat() || instance->IsEncounterInProgress() || instance->GetData(TYPE_EVENT)) + if (player->IsInCombat() || instance->IsEncounterInProgress()) return true; uint8 i = 0; @@ -199,17 +199,11 @@ class npc_announcer_toc10 : public CreatureScript } else if (instance->GetBossState(BOSS_LICH_KING) != DONE) { - if (GameObject* floor = ObjectAccessor::GetGameObject(*player, instance->GetGuidData(GO_ARGENT_COLISEUM_FLOOR))) - floor->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); - - creature->CastSpell(creature, SPELL_CORPSE_TELEPORT, false); - creature->CastSpell(creature, SPELL_DESTROY_FLOOR_KNOCKUP, false); - - if (!ObjectAccessor::GetCreature(*creature, instance->GetGuidData(NPC_ANUBARAK))) - creature->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); - - if (creature->IsVisible()) - creature->SetVisible(false); + if (creature->GetMap()->GetPlayers().getFirst()->GetSource()->GetTeam() == ALLIANCE) + instance->SetData(TYPE_EVENT, 4020); + else + instance->SetData(TYPE_EVENT, 4030); + instance->SetBossState(BOSS_LICH_KING, NOT_STARTED); } creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); return true; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index 952e35642d0..49ed9609a03 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -16,6 +16,7 @@ */ #include "InstanceScript.h" +#include "Vehicle.h" #include "Player.h" #include "ScriptedCreature.h" #include "ScriptMgr.h" @@ -91,6 +92,7 @@ class instance_ulduar : public InstanceMapScript // Creatures ObjectGuid LeviathanGUID; + GuidVector LeviathanVehicleGUIDs; ObjectGuid IgnisGUID; ObjectGuid RazorscaleGUID; ObjectGuid RazorscaleController; @@ -217,6 +219,11 @@ class instance_ulduar : public InstanceMapScript case NPC_LEVIATHAN: LeviathanGUID = creature->GetGUID(); break; + case NPC_SALVAGED_DEMOLISHER: + case NPC_SALVAGED_SIEGE_ENGINE: + case NPC_SALVAGED_CHOPPER: + LeviathanVehicleGUIDs.push_back(creature->GetGUID()); + break; case NPC_IGNIS: IgnisGUID = creature->GetGUID(); break; @@ -682,6 +689,24 @@ class instance_ulduar : public InstanceMapScript switch (type) { case BOSS_LEVIATHAN: + if (state == DONE) + { + // Eject all players from vehicles and make them untargetable. + // They will be despawned after a while + for (auto const& vehicleGuid : LeviathanVehicleGUIDs) + { + if (Creature* vehicleCreature = instance->GetCreature(vehicleGuid)) + { + if (Vehicle* vehicle = vehicleCreature->GetVehicleKit()) + { + vehicle->RemoveAllPassengers(); + vehicleCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + vehicleCreature->DespawnOrUnsummon(5 * MINUTE * IN_MILLISECONDS); + } + } + } + } + break; case BOSS_IGNIS: case BOSS_RAZORSCALE: case BOSS_XT002: @@ -1143,6 +1168,34 @@ class instance_ulduar : public InstanceMapScript } } + void UpdateDoorState(GameObject* door) override + { + // Leviathan doors are set to DOOR_TYPE_ROOM except the one it uses to enter the room + // which has to be set to DOOR_TYPE_PASSAGE + if (door->GetEntry() == GO_LEVIATHAN_DOOR && door->GetPositionX() > 400.f) + door->SetGoState(GetBossState(BOSS_LEVIATHAN) == DONE ? GO_STATE_ACTIVE : GO_STATE_READY); + else + InstanceScript::UpdateDoorState(door); + } + + void AddDoor(GameObject* door, bool add) override + { + // Leviathan doors are South except the one it uses to enter the room + // which is North and should not be used for boundary checks in BossAI::CheckBoundary() + if (door->GetEntry() == GO_LEVIATHAN_DOOR && door->GetPositionX() > 400.f) + { + if (add) + GetBossInfo(BOSS_LEVIATHAN)->door[DOOR_TYPE_PASSAGE].insert(door->GetGUID()); + else + GetBossInfo(BOSS_LEVIATHAN)->door[DOOR_TYPE_PASSAGE].erase(door->GetGUID()); + + if (add) + UpdateDoorState(door); + } + else + InstanceScript::AddDoor(door, add); + } + private: EventMap _events; uint32 _algalonTimer; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h index ddf293dd8b8..d40fb698658 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h @@ -54,6 +54,7 @@ enum UlduarNPCs NPC_LEVIATHAN = 33113, NPC_SALVAGED_DEMOLISHER = 33109, NPC_SALVAGED_SIEGE_ENGINE = 33060, + NPC_SALVAGED_CHOPPER = 33062, NPC_IGNIS = 33118, NPC_RAZORSCALE = 33186, NPC_RAZORSCALE_CONTROLLER = 33233, diff --git a/src/server/shared/CMakeLists.txt b/src/server/shared/CMakeLists.txt index 5f319191c14..4be94e334da 100644 --- a/src/server/shared/CMakeLists.txt +++ b/src/server/shared/CMakeLists.txt @@ -21,6 +21,7 @@ file(GLOB_RECURSE sources_Logging Logging/*.cpp Logging/*.h) file(GLOB_RECURSE sources_Networking Networking/*.cpp Networking/*.h) file(GLOB_RECURSE sources_Packets Packets/*.cpp Packets/*.h) file(GLOB_RECURSE sources_Threading Threading/*.cpp Threading/*.h) +file(GLOB_RECURSE sources_Updater Updater/*.cpp Updater/*.h) file(GLOB_RECURSE sources_Utilities Utilities/*.cpp Utilities/*.h) file(GLOB sources_localdir *.cpp *.h) @@ -51,6 +52,7 @@ set(shared_STAT_SRCS ${sources_Networking} ${sources_Packets} ${sources_Threading} + ${sources_Updater} ${sources_Utilities} ${sources_localdir} ) @@ -61,6 +63,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/dep/SFMT ${CMAKE_SOURCE_DIR}/dep/cppformat ${CMAKE_SOURCE_DIR}/dep/utf8cpp + ${CMAKE_SOURCE_DIR}/dep/process ${CMAKE_SOURCE_DIR}/src/server ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/Configuration @@ -74,6 +77,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/Packets ${CMAKE_CURRENT_SOURCE_DIR}/Threading ${CMAKE_CURRENT_SOURCE_DIR}/Utilities + ${CMAKE_CURRENT_SOURCE_DIR}/Updater ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object ${MYSQL_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} diff --git a/src/server/shared/Database/DatabaseLoader.cpp b/src/server/shared/Database/DatabaseLoader.cpp new file mode 100644 index 00000000000..36ee4b12c83 --- /dev/null +++ b/src/server/shared/Database/DatabaseLoader.cpp @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2008-2015 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 "DatabaseLoader.h" +#include "DBUpdater.h" +#include "Config.h" + +#include + +DatabaseLoader::DatabaseLoader(std::string const& logger, uint32 const defaultUpdateMask) + : _logger(logger), _autoSetup(sConfigMgr->GetBoolDefault("Updates.AutoSetup", true)), + _updateFlags(sConfigMgr->GetIntDefault("Updates.EnableDatabases", defaultUpdateMask)) +{ +} + +template +DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool& pool, std::string const& name) +{ + bool const updatesEnabledForThis = DBUpdater::IsEnabled(_updateFlags); + + _open.push(std::make_pair([this, name, updatesEnabledForThis, &pool]() -> bool + { + std::string const dbString = sConfigMgr->GetStringDefault(name + "DatabaseInfo", ""); + if (dbString.empty()) + { + TC_LOG_ERROR(_logger.c_str(), "Database %s not specified in configuration file!", name.c_str()); + return false; + } + + uint8 const asyncThreads = uint8(sConfigMgr->GetIntDefault(name + "Database.WorkerThreads", 1)); + if (asyncThreads < 1 || asyncThreads > 32) + { + TC_LOG_ERROR(_logger.c_str(), "%s database: invalid number of worker threads specified. " + "Please pick a value between 1 and 32.", name.c_str()); + return false; + } + + uint8 const synchThreads = uint8(sConfigMgr->GetIntDefault(name + "Database.SynchThreads", 1)); + + pool.SetConnectionInfo(dbString, asyncThreads, synchThreads); + if (uint32 error = pool.Open()) + { + // Database does not exist + if ((error == ER_BAD_DB_ERROR) && updatesEnabledForThis && _autoSetup) + { + // Try to create the database and connect again if auto setup is enabled + if (DBUpdater::Create(pool) && (!pool.Open())) + error = 0; + } + + // If the error wasn't handled quit + if (error) + { + TC_LOG_ERROR("sql.driver", "\nDatabasePool %s NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile " + "for specific errors. Read wiki at http://collab.kpsn.org/display/tc/TrinityCore+Home", name.c_str()); + + return false; + } + } + return true; + }, + [&pool]() + { + pool.Close(); + })); + + // Populate and update only if updates are enabled for this pool + if (updatesEnabledForThis) + { + _populate.push([this, name, &pool]() -> bool + { + if (!DBUpdater::Populate(pool)) + { + TC_LOG_ERROR(_logger.c_str(), "Could not populate the %s database, see log for details.", name.c_str()); + return false; + } + return true; + }); + + _update.push([this, name, &pool]() -> bool + { + if (!DBUpdater::Update(pool)) + { + TC_LOG_ERROR(_logger.c_str(), "Could not update the %s database, see log for details.", name.c_str()); + return false; + } + return true; + }); + } + + _prepare.push([this, name, &pool]() -> bool + { + if (!pool.PrepareStatements()) + { + TC_LOG_ERROR(_logger.c_str(), "Could not prepare statements of the %s database, see log for details.", name.c_str()); + return false; + } + return true; + }); + + return *this; +} + +bool DatabaseLoader::Load() +{ + if (!OpenDatabases()) + return false; + + if (!PopulateDatabases()) + return false; + + if (!UpdateDatabases()) + return false; + + if (!PrepareStatements()) + return false; + + return true; +} + +bool DatabaseLoader::OpenDatabases() +{ + while (!_open.empty()) + { + std::pair> const load = _open.top(); + if (load.first()) + _close.push(load.second); + else + { + // Close all loaded databases + while (!_close.empty()) + { + _close.top()(); + _close.pop(); + } + return false; + } + + _open.pop(); + } + return true; +} + +// Processes the elements of the given stack until a predicate returned false. +bool DatabaseLoader::Process(std::stack& stack) +{ + while (!stack.empty()) + { + if (!stack.top()()) + return false; + + stack.pop(); + } + return true; +} + +bool DatabaseLoader::PopulateDatabases() +{ + return Process(_populate); +} + +bool DatabaseLoader::UpdateDatabases() +{ + return Process(_update); +} + +bool DatabaseLoader::PrepareStatements() +{ + return Process(_prepare); +} + +template +DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool& pool, std::string const& name); +template +DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool& pool, std::string const& name); +template +DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool& pool, std::string const& name); diff --git a/src/server/shared/Database/DatabaseLoader.h b/src/server/shared/Database/DatabaseLoader.h new file mode 100644 index 00000000000..d35597ba807 --- /dev/null +++ b/src/server/shared/Database/DatabaseLoader.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2008-2015 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 . + */ + +#ifndef DatabaseLoader_h__ +#define DatabaseLoader_h__ + +#include "DatabaseWorkerPool.h" +#include "DatabaseEnv.h" + +#include +#include + +// A helper class to initiate all database worker pools, +// handles updating, delays preparing of statements and cleans up on failure. +class DatabaseLoader +{ +public: + DatabaseLoader(std::string const& logger, uint32 const defaultUpdateMask); + + // Register a database to the loader (lazy implemented) + template + DatabaseLoader& AddDatabase(DatabaseWorkerPool& pool, std::string const& name); + + // Load all databases + bool Load(); + + enum DatabaseTypeFlags + { + DATABASE_NONE = 0, + + DATABASE_LOGIN = 1, + DATABASE_CHARACTER = 2, + DATABASE_WORLD = 4, + + DATABASE_MASK_ALL = DATABASE_LOGIN | DATABASE_CHARACTER | DATABASE_WORLD + }; + +private: + bool OpenDatabases(); + bool PopulateDatabases(); + bool UpdateDatabases(); + bool PrepareStatements(); + + using Predicate = std::function; + + static bool Process(std::stack& stack); + + std::string const _logger; + bool const _autoSetup; + uint32 const _updateFlags; + + std::stack>> _open; + std::stack> _close; + std::stack _populate, _update, _prepare; +}; + +#endif // DatabaseLoader_h__ diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index f0ddbe91ad8..deafbf3e80d 100644 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -30,6 +30,7 @@ #include "AdhocStatement.h" #include +#include #define MIN_MYSQL_SERVER_VERSION 50100u #define MIN_MYSQL_CLIENT_VERSION 50100u @@ -57,9 +58,9 @@ class DatabaseWorkerPool public: /* Activity state */ - DatabaseWorkerPool() : _connectionInfo(NULL) + DatabaseWorkerPool() : _queue(new ProducerConsumerQueue()), + _async_threads(0), _synch_threads(0) { - _queue = new ProducerConsumerQueue(); memset(_connectionCount, 0, sizeof(_connectionCount)); _connections.resize(IDX_SIZE); @@ -70,31 +71,37 @@ class DatabaseWorkerPool ~DatabaseWorkerPool() { _queue->Cancel(); - - delete _queue; - - delete _connectionInfo; } - bool Open(const std::string& infoString, uint8 async_threads, uint8 synch_threads) + void SetConnectionInfo(std::string const& infoString, uint8 const asyncThreads, uint8 const synchThreads) { - _connectionInfo = new MySQLConnectionInfo(infoString); + _connectionInfo.reset(new MySQLConnectionInfo(infoString)); + + _async_threads = asyncThreads; + _synch_threads = synchThreads; + } + + uint32 Open() + { + WPFatal(_connectionInfo.get(), "Connection info was not set!"); TC_LOG_INFO("sql.driver", "Opening DatabasePool '%s'. Asynchronous connections: %u, synchronous connections: %u.", - GetDatabaseName(), async_threads, synch_threads); + GetDatabaseName(), _async_threads, _synch_threads); - bool res = OpenConnections(IDX_ASYNC, async_threads); + uint32 error = OpenConnections(IDX_ASYNC, _async_threads); - if (!res) - return res; + if (error) + return error; - res = OpenConnections(IDX_SYNCH, synch_threads); + error = OpenConnections(IDX_SYNCH, _synch_threads); - if (res) + if (!error) + { TC_LOG_INFO("sql.driver", "DatabasePool '%s' opened successfully. %u total connections running.", GetDatabaseName(), (_connectionCount[IDX_SYNCH] + _connectionCount[IDX_ASYNC])); + } - return res; + return error; } void Close() @@ -120,6 +127,32 @@ class DatabaseWorkerPool TC_LOG_INFO("sql.driver", "All connections on DatabasePool '%s' closed.", GetDatabaseName()); } + //! Prepares all prepared statements + bool PrepareStatements() + { + for (uint8 i = 0; i < IDX_SIZE; ++i) + for (uint32 c = 0; c < _connectionCount[i]; ++c) + { + T* t = _connections[i][c]; + t->LockIfReady(); + if (!t->PrepareStatements()) + { + t->Unlock(); + Close(); + return false; + } + else + t->Unlock(); + } + + return true; + } + + inline MySQLConnectionInfo const* GetConnectionInfo() const + { + return _connectionInfo.get(); + } + /** Delayed one-way statement methods. */ @@ -461,7 +494,7 @@ class DatabaseWorkerPool } private: - bool OpenConnections(InternalIndex type, uint8 numConnections) + uint32 OpenConnections(InternalIndex type, uint8 numConnections) { _connections[type].resize(numConnections); for (uint8 i = 0; i < numConnections; ++i) @@ -469,7 +502,7 @@ class DatabaseWorkerPool T* t; if (type == IDX_ASYNC) - t = new T(_queue, *_connectionInfo); + t = new T(_queue.get(), *_connectionInfo); else if (type == IDX_SYNCH) t = new T(*_connectionInfo); else @@ -478,35 +511,32 @@ class DatabaseWorkerPool _connections[type][i] = t; ++_connectionCount[type]; - bool res = t->Open(); + uint32 error = t->Open(); - if (res) + if (!error) { if (mysql_get_server_version(t->GetHandle()) < MIN_MYSQL_SERVER_VERSION) { TC_LOG_ERROR("sql.driver", "TrinityCore does not support MySQL versions below 5.1"); - res = false; + error = 1; } } // Failed to open a connection or invalid version, abort and cleanup - if (!res) + if (error) { - TC_LOG_ERROR("sql.driver", "DatabasePool %s NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile " - "for specific errors. Read wiki at http://collab.kpsn.org/display/tc/TrinityCore+Home", GetDatabaseName()); - while (_connectionCount[type] != 0) { T* t = _connections[type][i--]; delete t; --_connectionCount[type]; } - - return false; + return error; } } - return true; + // Everything is fine + return 0; } unsigned long EscapeString(char *to, const char *from, unsigned long length) @@ -546,10 +576,13 @@ class DatabaseWorkerPool return _connectionInfo->database.c_str(); } - ProducerConsumerQueue* _queue; //! Queue shared by async worker threads. - std::vector< std::vector > _connections; - uint32 _connectionCount[2]; //! Counter of MySQL connections; - MySQLConnectionInfo* _connectionInfo; + //! Queue shared by async worker threads. + std::unique_ptr> _queue; + std::vector> _connections; + //! Counter of MySQL connections; + uint32 _connectionCount[IDX_SIZE]; + std::unique_ptr _connectionInfo; + uint8 _async_threads, _synch_threads; }; #endif diff --git a/src/server/shared/Database/MySQLConnection.cpp b/src/server/shared/Database/MySQLConnection.cpp index 1a9f973d47b..1fa3f01a5e1 100644 --- a/src/server/shared/Database/MySQLConnection.cpp +++ b/src/server/shared/Database/MySQLConnection.cpp @@ -72,7 +72,7 @@ void MySQLConnection::Close() delete this; } -bool MySQLConnection::Open() +uint32 MySQLConnection::Open() { MYSQL *mysqlInit; mysqlInit = mysql_init(NULL); @@ -137,13 +137,13 @@ bool MySQLConnection::Open() // set connection properties to UTF8 to properly handle locales for different // server configs - core sends data in UTF8, so MySQL must expect UTF8 too mysql_set_character_set(m_Mysql, "utf8"); - return PrepareStatements(); + return 0; } else { - TC_LOG_ERROR("sql.sql", "Could not connect to MySQL database at %s: %s\n", m_connectionInfo.host.c_str(), mysql_error(mysqlInit)); + TC_LOG_ERROR("sql.sql", "Could not connect to MySQL database at %s: %s", m_connectionInfo.host.c_str(), mysql_error(mysqlInit)); mysql_close(mysqlInit); - return false; + return mysql_errno(mysqlInit); } } diff --git a/src/server/shared/Database/MySQLConnection.h b/src/server/shared/Database/MySQLConnection.h index d486f5b4679..78d8d2fb5dd 100644 --- a/src/server/shared/Database/MySQLConnection.h +++ b/src/server/shared/Database/MySQLConnection.h @@ -72,9 +72,11 @@ class MySQLConnection MySQLConnection(ProducerConsumerQueue* queue, MySQLConnectionInfo& connInfo); //! Constructor for asynchronous connections. virtual ~MySQLConnection(); - virtual bool Open(); + virtual uint32 Open(); void Close(); + bool PrepareStatements(); + public: bool Execute(const char* sql); bool Execute(PreparedStatement* stmt); @@ -111,7 +113,6 @@ class MySQLConnection MySQLPreparedStatement* GetPreparedStatement(uint32 index); void PrepareStatement(uint32 index, const char* sql, ConnectionFlags flags); - bool PrepareStatements(); virtual void DoPrepareStatements() = 0; protected: diff --git a/src/server/shared/Updater/DBUpdater.cpp b/src/server/shared/Updater/DBUpdater.cpp new file mode 100644 index 00000000000..3c0ad4d1476 --- /dev/null +++ b/src/server/shared/Updater/DBUpdater.cpp @@ -0,0 +1,381 @@ +/* + * Copyright (C) 2008-2015 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 "DBUpdater.h" +#include "Log.h" +#include "revision.h" +#include "UpdateFetcher.h" +#include "DatabaseLoader.h" +#include "Config.h" + +#include +#include +#include +#include +#include +#include +#include + +using namespace boost::process; +using namespace boost::process::initializers; +using namespace boost::iostreams; + +template +std::string DBUpdater::GetSourceDirectory() +{ + std::string const entry = sConfigMgr->GetStringDefault("Updates.SourcePath", ""); + if (!entry.empty()) + return entry; + else + return _SOURCE_DIRECTORY; +} + +template +std::string DBUpdater::GetMySqlCli() +{ + std::string const entry = sConfigMgr->GetStringDefault("Updates.MySqlCLIPath", ""); + if (!entry.empty()) + return entry; + else + return _MYSQL_EXECUTABLE; +} + +// Auth Database +template<> +std::string DBUpdater::GetConfigEntry() +{ + return "Updates.Auth"; +} + +template<> +std::string DBUpdater::GetTableName() +{ + return "Auth"; +} + +template<> +std::string DBUpdater::GetBaseFile() +{ + return DBUpdater::GetSourceDirectory() + "/sql/base/auth_database.sql"; +} + +template<> +bool DBUpdater::IsEnabled(uint32 const updateMask) +{ + // This way silences warnings under msvc + return (updateMask & DatabaseLoader::DATABASE_LOGIN) ? true : false; +} + +// World Database +template<> +std::string DBUpdater::GetConfigEntry() +{ + return "Updates.World"; +} + +template<> +std::string DBUpdater::GetTableName() +{ + return "World"; +} + +template<> +std::string DBUpdater::GetBaseFile() +{ + return _FULL_DATABASE; +} + +template<> +bool DBUpdater::IsEnabled(uint32 const updateMask) +{ + // This way silences warnings under msvc + return (updateMask & DatabaseLoader::DATABASE_WORLD) ? true : false; +} + +template<> +BaseLocation DBUpdater::GetBaseLocationType() +{ + return LOCATION_DOWNLOAD; +} + +// Character Database +template<> +std::string DBUpdater::GetConfigEntry() +{ + return "Updates.Character"; +} + +template<> +std::string DBUpdater::GetTableName() +{ + return "Character"; +} + +template<> +std::string DBUpdater::GetBaseFile() +{ + return DBUpdater::GetSourceDirectory() + "/sql/base/characters_database.sql"; +} + +template<> +bool DBUpdater::IsEnabled(uint32 const updateMask) +{ + // This way silences warnings under msvc + return (updateMask & DatabaseLoader::DATABASE_CHARACTER) ? true : false; +} + +// All +template +BaseLocation DBUpdater::GetBaseLocationType() +{ + return LOCATION_REPOSITORY; +} + +template +bool DBUpdater::CheckExecutable() +{ + DBUpdater::Path const exe(DBUpdater::GetMySqlCli()); + if (!exists(exe)) + { + // Check for mysql in path + std::vector args = {"--version"}; + uint32 ret; + try + { + child c = execute(run_exe("mysql"), set_args(args), throw_on_error(), close_stdout()); + ret = wait_for_exit(c); + } + catch (boost::system::system_error&) + { + ret = EXIT_FAILURE; + } + + if (ret == EXIT_FAILURE) + { + TC_LOG_FATAL("sql.updates", "Didn't find executeable mysql binary at \'%s\', correct the path in the *.conf (\"Updates.MySqlCLIPath\").", + absolute(exe).generic_string().c_str()); + + return false; + } + } + return true; +} + +template +bool DBUpdater::Create(DatabaseWorkerPool& pool) +{ + TC_LOG_INFO("sql.updates", "Database \"%s\" does not exist, do you want to create it? [yes (default) / no]: ", + pool.GetConnectionInfo()->database.c_str()); + + std::string answer; + std::getline(std::cin, answer); + if (!answer.empty() && !(answer.substr(0, 1) == "y")) + return false; + + TC_LOG_INFO("sql.updates", "Creating database \"%s\"...", pool.GetConnectionInfo()->database.c_str()); + + // Path of temp file + static Path const temp("create_table.sql"); + + // Create temporary query to use external mysql cli + std::ofstream file(temp.generic_string()); + if (!file.is_open()) + { + TC_LOG_FATAL("sql.updates", "Failed to create temporary query file \"%s\"!", temp.generic_string().c_str()); + return false; + } + + file << "CREATE DATABASE `" << pool.GetConnectionInfo()->database << "` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci\n\n"; + + file.close(); + + try + { + DBUpdater::ApplyFile(pool, pool.GetConnectionInfo()->host, pool.GetConnectionInfo()->user, pool.GetConnectionInfo()->password, + pool.GetConnectionInfo()->port_or_socket, "", temp); + } + catch (UpdateException&) + { + TC_LOG_FATAL("sql.updates", "Failed to create database %s! Has the user `CREATE` priviliges?", pool.GetConnectionInfo()->database.c_str()); + boost::filesystem::remove(temp); + return false; + } + + TC_LOG_INFO("sql.updates", "Done."); + boost::filesystem::remove(temp); + return true; +} + +template +bool DBUpdater::Update(DatabaseWorkerPool& pool) +{ + if (!DBUpdater::CheckExecutable()) + return false; + + TC_LOG_INFO("sql.updates", "Updating %s database...", DBUpdater::GetTableName().c_str()); + + Path const sourceDirectory(GetSourceDirectory()); + + if (!is_directory(sourceDirectory)) + { + TC_LOG_ERROR("sql.updates", "DBUpdater: Given source directory %s does not exist, skipped!", sourceDirectory.generic_string().c_str()); + return false; + } + + UpdateFetcher updateFetcher(sourceDirectory, [&](std::string const& query) { DBUpdater::Apply(pool, query); }, + [&](Path const& file) { DBUpdater::ApplyFile(pool, file); }, + [&](std::string const& query) -> QueryResult { return DBUpdater::Retrieve(pool, query); }); + + uint32 const count = updateFetcher.Update( + sConfigMgr->GetBoolDefault("Updates.Redundancy", true), + sConfigMgr->GetBoolDefault("Updates.AllowRehash", true), + sConfigMgr->GetBoolDefault("Updates.ArchivedRedundancy", false), + sConfigMgr->GetBoolDefault("Updates.CleanDeadRef", true)); + + if (!count) + TC_LOG_INFO("sql.updates", ">> %s database is up-to-date!", DBUpdater::GetTableName().c_str()); + else + TC_LOG_INFO("sql.updates", ">> Applied %d %s.", count, count == 1 ? "query" : "queries"); + + return true; +} + +template +bool DBUpdater::Populate(DatabaseWorkerPool& pool) +{ + { + QueryResult const result = Retrieve(pool, "SHOW TABLES"); + if (result && (result->GetRowCount() > 0)) + return true; + } + + if (!DBUpdater::CheckExecutable()) + return false; + + TC_LOG_INFO("sql.updates", "Database %s is empty, auto populating it...", DBUpdater::GetTableName().c_str()); + + std::string const p = DBUpdater::GetBaseFile(); + if (p.empty()) + { + TC_LOG_INFO("sql.updates", ">> No base file provided, skipped!"); + return true; + } + + Path const base(p); + if (!exists(base)) + { + switch (DBUpdater::GetBaseLocationType()) + { + case LOCATION_REPOSITORY: + { + TC_LOG_ERROR("sql.updates", ">> Base file \"%s\" is missing, try to clone the source again.", + base.generic_string().c_str()); + + break; + } + case LOCATION_DOWNLOAD: + { + TC_LOG_ERROR("sql.updates", ">> File \"%s\" is missing, download it from \"http://www.trinitycore.org/f/files/category/1-database/\"" \ + " and place it in your server directory.", base.filename().generic_string().c_str()); + break; + } + } + return false; + } + + // Update database + TC_LOG_INFO("sql.updates", ">> Applying \'%s\'...", base.generic_string().c_str()); + ApplyFile(pool, base); + + TC_LOG_INFO("sql.updates", ">> Done!"); + return true; +} + +template +QueryResult DBUpdater::Retrieve(DatabaseWorkerPool& pool, std::string const& query) +{ + return pool.PQuery(query.c_str()); +} + +template +void DBUpdater::Apply(DatabaseWorkerPool& pool, std::string const& query) +{ + pool.DirectExecute(query.c_str()); +} + +template +void DBUpdater::ApplyFile(DatabaseWorkerPool& pool, Path const& path) +{ + DBUpdater::ApplyFile(pool, pool.GetConnectionInfo()->host, pool.GetConnectionInfo()->user, pool.GetConnectionInfo()->password, + pool.GetConnectionInfo()->port_or_socket, pool.GetConnectionInfo()->database, path); +} + +template +void DBUpdater::ApplyFile(DatabaseWorkerPool& pool, std::string const& host, std::string const& user, + std::string const& password, std::string const& port_or_socket, std::string const& database, Path const& path) +{ + std::vector args; + args.reserve(7); + + // CLI Client connection info + args.push_back("-h" + host); + args.push_back("-u" + user); + args.push_back("-p" + password); + args.push_back("-P" + port_or_socket); + + // Set the default charset to utf8 + args.push_back("--default-character-set=utf8"); + + // Set max allowed packet to 1 GB + args.push_back("--max-allowed-packet=1GB"); + + // Database + if (!database.empty()) + args.push_back(database); + + // ToDo: use the existing query in memory as virtual file if possible + file_descriptor_source source(path); + + uint32 ret; + try + { + child c = execute(run_exe(DBUpdater::GetMySqlCli().empty() ? "mysql" : + boost::filesystem::absolute(DBUpdater::GetMySqlCli()).generic_string()), + set_args(args), bind_stdin(source), throw_on_error()); + + ret = wait_for_exit(c); + } + catch (boost::system::system_error&) + { + ret = EXIT_FAILURE; + } + + source.close(); + + if (ret != EXIT_SUCCESS) + { + TC_LOG_FATAL("sql.updates", "Applying of file \'%s\' to database \'%s\' failed!" \ + " If you are an user pull the latest revision from the repository. If you are a developer fix your sql query.", + path.generic_string().c_str(), pool.GetConnectionInfo()->database.c_str()); + + throw UpdateException("update failed"); + } +} + +template class DBUpdater; +template class DBUpdater; +template class DBUpdater; diff --git a/src/server/shared/Updater/DBUpdater.h b/src/server/shared/Updater/DBUpdater.h new file mode 100644 index 00000000000..0caf8a438fb --- /dev/null +++ b/src/server/shared/Updater/DBUpdater.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2008-2015 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 . + */ + +#ifndef DBUpdater_h__ +#define DBUpdater_h__ + +#include "DatabaseEnv.h" + +#include +#include + +class UpdateException : public std::exception +{ +public: + UpdateException(std::string const& msg) : _msg(msg) { } + ~UpdateException() throw() { } + + char const* what() const throw() override { return _msg.c_str(); } + +private: + std::string const _msg; +}; + +enum BaseLocation +{ + LOCATION_REPOSITORY, + LOCATION_DOWNLOAD +}; + +template +class DBUpdater +{ +public: + using Path = boost::filesystem::path; + + static std::string GetSourceDirectory(); + + static inline std::string GetConfigEntry(); + + static inline std::string GetTableName(); + + static std::string GetBaseFile(); + + static bool IsEnabled(uint32 const updateMask); + + static BaseLocation GetBaseLocationType(); + + static bool Create(DatabaseWorkerPool& pool); + + static bool Update(DatabaseWorkerPool& pool); + + static bool Populate(DatabaseWorkerPool& pool); + +private: + static std::string GetMySqlCli(); + static bool CheckExecutable(); + + static QueryResult Retrieve(DatabaseWorkerPool& pool, std::string const& query); + static void Apply(DatabaseWorkerPool& pool, std::string const& query); + static void ApplyFile(DatabaseWorkerPool& pool, Path const& path); + static void ApplyFile(DatabaseWorkerPool& pool, std::string const& host, std::string const& user, + std::string const& password, std::string const& port_or_socket, std::string const& database, Path const& path); +}; + +#endif // DBUpdater_h__ diff --git a/src/server/shared/Updater/UpdateFetcher.cpp b/src/server/shared/Updater/UpdateFetcher.cpp new file mode 100644 index 00000000000..63e820c3de5 --- /dev/null +++ b/src/server/shared/Updater/UpdateFetcher.cpp @@ -0,0 +1,387 @@ +/* + * Copyright (C) 2008-2015 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 "UpdateFetcher.h" +#include "Log.h" +#include "Util.h" + +#include +#include +#include +#include +#include +#include +#include + +using namespace boost::filesystem; + +UpdateFetcher::UpdateFetcher(Path const& sourceDirectory, + std::function const& apply, + std::function const& applyFile, + std::function const& retrieve) : + _sourceDirectory(sourceDirectory), _apply(apply), _applyFile(applyFile), + _retrieve(retrieve) +{ +} + +UpdateFetcher::LocaleFileStorage UpdateFetcher::GetFileList() const +{ + LocaleFileStorage files; + DirectoryStorage directories = ReceiveIncludedDirectories(); + for (auto const& entry : directories) + FillFileListRecursively(entry.path, files, entry.state, 1); + + return files; +} + +void UpdateFetcher::FillFileListRecursively(Path const& path, LocaleFileStorage& storage, State const state, uint32 const depth) const +{ + static uint32 const MAX_DEPTH = 10; + static directory_iterator const end; + + for (directory_iterator itr(path); itr != end; ++itr) + { + if (is_directory(itr->path())) + { + if (depth < MAX_DEPTH) + FillFileListRecursively(itr->path(), storage, state, depth + 1); + } + else if (itr->path().extension() == ".sql") + { + TC_LOG_TRACE("sql.updates", "Added locale file \"%s\".", itr->path().filename().generic_string().c_str()); + + LocaleFileEntry const entry = { itr->path(), state }; + + // Check for doubled filenames + // Since elements are only compared through their filenames this is ok + if (storage.find(entry) != storage.end()) + { + TC_LOG_FATAL("sql.updates", "Duplicated filename occurred \"%s\", since updates are ordered " \ + "through its filename every name needs to be unique!", itr->path().generic_string().c_str()); + + throw UpdateException("Updating failed, see the log for details."); + } + + storage.insert(entry); + } + } +} + +UpdateFetcher::DirectoryStorage UpdateFetcher::ReceiveIncludedDirectories() const +{ + DirectoryStorage directories; + + QueryResult const result = _retrieve("SELECT `path`, `state` FROM `updates_include`"); + if (!result) + return directories; + + do + { + Field* fields = result->Fetch(); + + std::string path = fields[0].GetString(); + if (path.substr(0, 1) == "$") + path = _sourceDirectory.generic_string() + path.substr(1); + + Path const p(path); + + if (!is_directory(p)) + { + TC_LOG_ERROR("sql.updates", "DBUpdater: Given update include directory \"%s\" isn't existing, skipped!", p.generic_string().c_str()); + continue; + } + + DirectoryEntry const entry = { p, AppliedFileEntry::StateConvert(fields[1].GetString()) }; + directories.push_back(entry); + + TC_LOG_TRACE("sql.updates", "Added applied file \"%s\" from remote.", p.filename().generic_string().c_str()); + + } while (result->NextRow()); + + return directories; +} + +UpdateFetcher::AppliedFileStorage UpdateFetcher::ReceiveAppliedFiles() const +{ + AppliedFileStorage map; + + QueryResult result = _retrieve("SELECT `name`, `hash`, `state`, UNIX_TIMESTAMP(`timestamp`) FROM `updates` ORDER BY `name` ASC"); + if (!result) + return map; + + do + { + Field* fields = result->Fetch(); + + AppliedFileEntry const entry = { fields[0].GetString(), fields[1].GetString(), + AppliedFileEntry::StateConvert(fields[2].GetString()), fields[3].GetUInt64() }; + + map.insert(std::make_pair(entry.name, entry)); + } + while (result->NextRow()); + + return map; +} + +UpdateFetcher::SQLUpdate UpdateFetcher::ReadSQLUpdate(boost::filesystem::path const& file) const +{ + std::ifstream in(file.c_str()); + WPFatal(in.is_open(), "Could not read an update file."); + + auto const start_pos = in.tellg(); + in.ignore(std::numeric_limits::max()); + auto const char_count = in.gcount(); + in.seekg(start_pos); + + SQLUpdate const update(new std::string(char_count, char{})); + + in.read(&(*update)[0], update->size()); + in.close(); + return update; +} + +uint32 UpdateFetcher::Update(bool const redundancyChecks, bool const allowRehash, bool const archivedRedundancy, bool const cleanDeadReferences) const +{ + LocaleFileStorage const available = GetFileList(); + AppliedFileStorage applied = ReceiveAppliedFiles(); + + // Fill hash to name cache + HashToFileNameStorage hashToName; + for (auto entry : applied) + hashToName.insert(std::make_pair(entry.second.hash, entry.first)); + + uint32 importedUpdates = 0; + + for (auto const& availableQuery : available) + { + TC_LOG_DEBUG("sql.updates", "Checking update \"%s\"...", availableQuery.first.filename().generic_string().c_str()); + + AppliedFileStorage::const_iterator iter = applied.find(availableQuery.first.filename().string()); + if (iter != applied.end()) + { + // If redundancy is disabled skip it since the update is already applied. + if (!redundancyChecks) + { + TC_LOG_DEBUG("sql.updates", ">> Update is already applied, skipping redundancy checks."); + applied.erase(iter); + continue; + } + + // If the update is in an archived directory and is marked as archived in our database skip redundancy checks (archived updates never change). + if (!archivedRedundancy && (iter->second.state == ARCHIVED) && (availableQuery.second == ARCHIVED)) + { + TC_LOG_DEBUG("sql.updates", ">> Update is archived and marked as archived in database, skipping redundancy checks."); + applied.erase(iter); + continue; + } + } + + // Read update from file + SQLUpdate const update = ReadSQLUpdate(availableQuery.first); + + // Calculate hash + std::string const hash = CalculateHash(update); + + UpdateMode mode = MODE_APPLY; + + // Update is not in our applied list + if (iter == applied.end()) + { + // Catch renames (different filename but same hash) + HashToFileNameStorage::const_iterator const hashIter = hashToName.find(hash); + if (hashIter != hashToName.end()) + { + // Check if the original file was removed if not we've got a problem. + LocaleFileStorage::const_iterator localeIter; + // Push localeIter forward + for (localeIter = available.begin(); (localeIter != available.end()) && + (localeIter->first.filename().string() != hashIter->second); ++localeIter); + + // Conflict! + if (localeIter != available.end()) + { + TC_LOG_WARN("sql.updates", ">> Seems like update \"%s\" \'%s\' was renamed, but the old file is still there! " \ + "Trade it as a new file! (Probably its an unmodified copy of file \"%s\")", + availableQuery.first.filename().string().c_str(), hash.substr(0, 7).c_str(), + localeIter->first.filename().string().c_str()); + } + // Its save to trade the file as renamed here + else + { + TC_LOG_INFO("sql.updates", ">> Renaming update \"%s\" to \"%s\" \'%s\'.", + hashIter->second.c_str(), availableQuery.first.filename().string().c_str(), hash.substr(0, 7).c_str()); + + RenameEntry(hashIter->second, availableQuery.first.filename().string()); + applied.erase(hashIter->second); + continue; + } + } + // Apply the update if it was never seen before. + else + { + TC_LOG_INFO("sql.updates", ">> Applying update \"%s\" \'%s\'...", + availableQuery.first.filename().string().c_str(), hash.substr(0, 7).c_str()); + } + } + // Rehash the update entry if it is contained in our database but with an empty hash. + else if (allowRehash && iter->second.hash.empty()) + { + mode = MODE_REHASH; + + TC_LOG_INFO("sql.updates", ">> Re-hashing update \"%s\" \'%s\'...", availableQuery.first.filename().string().c_str(), + hash.substr(0, 7).c_str()); + } + else + { + // If the hash of the files differs from the one stored in our database reapply the update (because it was changed). + if (iter->second.hash != hash) + { + TC_LOG_INFO("sql.updates", ">> Reapplying update \"%s\" \'%s\' -> \'%s\' (it changed)...", availableQuery.first.filename().string().c_str(), + iter->second.hash.substr(0, 7).c_str(), hash.substr(0, 7).c_str()); + } + else + { + // If the file wasn't changed and just moved update its state if necessary. + if (iter->second.state != availableQuery.second) + { + TC_LOG_DEBUG("sql.updates", ">> Updating state of \"%s\" to \'%s\'...", + availableQuery.first.filename().string().c_str(), AppliedFileEntry::StateConvert(availableQuery.second).c_str()); + + UpdateState(availableQuery.first.filename().string(), availableQuery.second); + } + + TC_LOG_DEBUG("sql.updates", ">> Update is already applied and is matching hash \'%s\'.", hash.substr(0, 7).c_str()); + + applied.erase(iter); + continue; + } + } + + uint32 speed = 0; + AppliedFileEntry const file = { availableQuery.first.filename().string(), hash, availableQuery.second, 0 }; + + switch (mode) + { + case MODE_APPLY: + speed = Apply(availableQuery.first); + /*no break*/ + case MODE_REHASH: + UpdateEntry(file, speed); + break; + } + + if (iter != applied.end()) + applied.erase(iter); + + if (mode == MODE_APPLY) + ++importedUpdates; + } + + for (auto const& entry : applied) + { + TC_LOG_WARN("sql.updates", ">> File \'%s\' was applied to the database but is missing in" \ + " your update directory now!%s", entry.first.c_str(), cleanDeadReferences ? " Deleting orphaned entry..." : ""); + } + + if (cleanDeadReferences) + CleanUp(applied); + + return importedUpdates; +} + +std::string UpdateFetcher::CalculateHash(SQLUpdate const& query) const +{ + // Calculate a Sha1 hash based on query content. + unsigned char digest[SHA_DIGEST_LENGTH]; + SHA1((unsigned char*)query->c_str(), query->length(), (unsigned char*)&digest); + + return ByteArrayToHexStr(digest, SHA_DIGEST_LENGTH); +} + +uint32 UpdateFetcher::Apply(Path const& path) const +{ + using Time = std::chrono::high_resolution_clock; + using ms = std::chrono::milliseconds; + + // Benchmark query speed + auto const begin = Time::now(); + + // Update database + _applyFile(path); + + // Return time the query took to apply + return std::chrono::duration_cast(Time::now() - begin).count(); +} + +void UpdateFetcher::UpdateEntry(AppliedFileEntry const& entry, uint32 const speed) const +{ + std::string const update = "REPLACE INTO `updates` (`name`, `hash`, `state`, `speed`) VALUES (\"" + + entry.name + "\", \"" + entry.hash + "\", \'" + entry.GetStateAsString() + "\', " + std::to_string(speed) + ")"; + + // Update database + _apply(update); +} + +void UpdateFetcher::RenameEntry(std::string const& from, std::string const& to) const +{ + // Delete target if it exists + { + std::string const update = "DELETE FROM `updates` WHERE `name`=\"" + to + "\""; + + // Update database + _apply(update); + } + + // Rename + { + std::string const update = "UPDATE `updates` SET `name`=\"" + to + "\" WHERE `name`=\"" + from + "\""; + + // Update database + _apply(update); + } +} + +void UpdateFetcher::CleanUp(AppliedFileStorage const& storage) const +{ + if (storage.empty()) + return; + + std::stringstream update; + size_t remaining = storage.size(); + + update << "DELETE FROM `updates` WHERE `name` IN("; + + for (auto const& entry : storage) + { + update << "\"" << entry.first << "\""; + if ((--remaining) > 0) + update << ", "; + } + + update << ")"; + + // Update database + _apply(update.str()); +} + +void UpdateFetcher::UpdateState(std::string const& name, State const state) const +{ + std::string const update = "UPDATE `updates` SET `state`=\'" + AppliedFileEntry::StateConvert(state) + "\' WHERE `name`=\"" + name + "\""; + + // Update database + _apply(update); +} diff --git a/src/server/shared/Updater/UpdateFetcher.h b/src/server/shared/Updater/UpdateFetcher.h new file mode 100644 index 00000000000..f545c232a94 --- /dev/null +++ b/src/server/shared/Updater/UpdateFetcher.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2008-2015 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 . + */ + +#ifndef UpdateFetcher_h__ +#define UpdateFetcher_h__ + +#include + +#include +#include +#include +#include + +class UpdateFetcher +{ + using Path = boost::filesystem::path; + +public: + UpdateFetcher(Path const& updateDirectory, + std::function const& apply, + std::function const& applyFile, + std::function const& retrieve); + + uint32 Update(bool const redundancyChecks, bool const allowRehash, + bool const archivedRedundancy, bool const cleanDeadReferences) const; + +private: + enum UpdateMode + { + MODE_APPLY, + MODE_REHASH + }; + + enum State + { + RELEASED, + ARCHIVED + }; + + struct AppliedFileEntry + { + std::string const name; + + std::string const hash; + + State const state; + + uint64 const timestamp; + + static inline State StateConvert(std::string const& state) + { + return (state == "RELEASED") ? RELEASED : ARCHIVED; + } + + static inline std::string StateConvert(State const state) + { + return (state == RELEASED) ? "RELEASED" : "ARCHIVED"; + } + + std::string GetStateAsString() const + { + return StateConvert(state); + } + }; + + struct DirectoryEntry + { + Path const path; + + State const state; + }; + + using LocaleFileEntry = std::pair; + + struct PathCompare + { + inline bool operator() (LocaleFileEntry const& left, LocaleFileEntry const& right) const + { + return left.first.filename().string() < right.first.filename().string(); + } + }; + + using LocaleFileStorage = std::set; + using HashToFileNameStorage = std::unordered_map; + using AppliedFileStorage = std::unordered_map; + using DirectoryStorage = std::vector; + using SQLUpdate = std::shared_ptr; + + LocaleFileStorage GetFileList() const; + void FillFileListRecursively(Path const& path, LocaleFileStorage& storage, State const state, uint32 const depth) const; + + DirectoryStorage ReceiveIncludedDirectories() const; + AppliedFileStorage ReceiveAppliedFiles() const; + + SQLUpdate ReadSQLUpdate(Path const& file) const; + std::string CalculateHash(SQLUpdate const& query) const; + + uint32 Apply(Path const& path) const; + + void UpdateEntry(AppliedFileEntry const& entry, uint32 const speed = 0) const; + void RenameEntry(std::string const& from, std::string const& to) const; + void CleanUp(AppliedFileStorage const& storage) const; + + void UpdateState(std::string const& name, State const state) const; + + Path const _sourceDirectory; + + std::function const _apply; + std::function const _applyFile; + std::function const _retrieve; +}; + +#endif // UpdateFetcher_h__ diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt index ddf336388d3..a7ba5b29a7c 100644 --- a/src/server/worldserver/CMakeLists.txt +++ b/src/server/worldserver/CMakeLists.txt @@ -49,6 +49,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/dep/SFMT ${CMAKE_SOURCE_DIR}/dep/zmqpp ${CMAKE_SOURCE_DIR}/dep/cppformat + ${CMAKE_SOURCE_DIR}/dep/process ${CMAKE_SOURCE_DIR}/src/server/collision ${CMAKE_SOURCE_DIR}/src/server/collision/Management ${CMAKE_SOURCE_DIR}/src/server/collision/Models @@ -65,6 +66,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Networking ${CMAKE_SOURCE_DIR}/src/server/shared/Packets ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Updater ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities ${CMAKE_SOURCE_DIR}/src/server/ipc ${CMAKE_SOURCE_DIR}/src/server/game diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index e3a010fb517..21345b7a71f 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -457,80 +457,15 @@ bool StartDB() { MySQL::Library_Init(); - std::string dbString; - uint8 asyncThreads, synchThreads; + // Load databases + DatabaseLoader loader("server.worldserver", DatabaseLoader::DATABASE_NONE); + loader + .AddDatabase(WorldDatabase, "World") + .AddDatabase(CharacterDatabase, "Character") + .AddDatabase(LoginDatabase, "Login"); - dbString = sConfigMgr->GetStringDefault("WorldDatabaseInfo", ""); - if (dbString.empty()) - { - TC_LOG_ERROR("server.worldserver", "World database not specified in configuration file"); + if (!loader.Load()) return false; - } - - asyncThreads = uint8(sConfigMgr->GetIntDefault("WorldDatabase.WorkerThreads", 1)); - if (asyncThreads < 1 || asyncThreads > 32) - { - TC_LOG_ERROR("server.worldserver", "World database: invalid number of worker threads specified. " - "Please pick a value between 1 and 32."); - return false; - } - - synchThreads = uint8(sConfigMgr->GetIntDefault("WorldDatabase.SynchThreads", 1)); - ///- Initialize the world database - if (!WorldDatabase.Open(dbString, asyncThreads, synchThreads)) - { - TC_LOG_ERROR("server.worldserver", "Cannot connect to world database %s", dbString.c_str()); - return false; - } - - ///- Get character database info from configuration file - dbString = sConfigMgr->GetStringDefault("CharacterDatabaseInfo", ""); - if (dbString.empty()) - { - TC_LOG_ERROR("server.worldserver", "Character database not specified in configuration file"); - return false; - } - - asyncThreads = uint8(sConfigMgr->GetIntDefault("CharacterDatabase.WorkerThreads", 1)); - if (asyncThreads < 1 || asyncThreads > 32) - { - TC_LOG_ERROR("server.worldserver", "Character database: invalid number of worker threads specified. " - "Please pick a value between 1 and 32."); - return false; - } - - synchThreads = uint8(sConfigMgr->GetIntDefault("CharacterDatabase.SynchThreads", 2)); - - ///- Initialize the Character database - if (!CharacterDatabase.Open(dbString, asyncThreads, synchThreads)) - { - TC_LOG_ERROR("server.worldserver", "Cannot connect to Character database %s", dbString.c_str()); - return false; - } - - ///- Get login database info from configuration file - dbString = sConfigMgr->GetStringDefault("LoginDatabaseInfo", ""); - if (dbString.empty()) - { - TC_LOG_ERROR("server.worldserver", "Login database not specified in configuration file"); - return false; - } - - asyncThreads = uint8(sConfigMgr->GetIntDefault("LoginDatabase.WorkerThreads", 1)); - if (asyncThreads < 1 || asyncThreads > 32) - { - TC_LOG_ERROR("server.worldserver", "Login database: invalid number of worker threads specified. " - "Please pick a value between 1 and 32."); - return false; - } - - synchThreads = uint8(sConfigMgr->GetIntDefault("LoginDatabase.SynchThreads", 1)); - ///- Initialise the login database - if (!LoginDatabase.Open(dbString, asyncThreads, synchThreads)) - { - TC_LOG_ERROR("server.worldserver", "Cannot connect to login database %s", dbString.c_str()); - return false; - } ///- Get the realm Id from the configuration file realmHandle.Index = sConfigMgr->GetIntDefault("RealmID", 0); diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index afddb5a8ec9..5f76e3158a4 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -11,6 +11,7 @@ # PERFORMANCE SETTINGS # SERVER LOGGING # SERVER SETTINGS +# UPDATE SETTINGS # WARDEN SETTINGS # PLAYER INTERACTION # CREATURE SETTINGS @@ -1096,6 +1097,89 @@ BirthdayTime = 1222964635 # ################################################################################################### +################################################################################################### +# UPDATE SETTINGS +# +# Updates.EnableDatabases +# Description: A mask that describes which databases shall be updated. +# +# Following flags are available +# DATABASE_LOGIN = 1, // Auth database +# DATABASE_CHARACTER = 2, // Character database +# DATABASE_WORLD = 4, // World database +# +# Default: 0 - (All Disabled) +# 4 - (Enable world only) +# 7 - (All enabled) + +Updates.EnableDatabases = 0 + +# +# Updates.SourcePath +# Description: The path to your TrinityCore source directory. +# If the path is left empty, built-in CMAKE_SOURCE_DIR is used. +# Example: "../TrinityCore" +# Default: "" + +Updates.SourcePath = "" + +# +# Updates.SourcePath +# Description: The path to your mysql cli binary. +# If the path is left empty, built-in path from cmake is used. +# Example: "C:/Program Files/MySQL/MySQL Server 5.6/bin/mysql.exe" +# "mysql.exe" +# "/usr/bin/mysql" +# Default: "" + +Updates.MySqlCLIPath = "" + +# +# Updates.AutoSetup +# Description: Auto populate empty databases. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.AutoSetup = 1 + +# +# Updates.Redundancy +# Description: Perform data redundancy checks through hashing +# to detect changes on sql updates and reapply it. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.Redundancy = 1 + +# +# Updates.ArchivedRedundancy +# Description: Check hashes of archived updates (slows down startup). +# Default: 0 - (Disabled) +# 1 - (Enabled) + +Updates.ArchivedRedundancy = 0 + +# +# Updates.AllowRehash +# Description: Inserts the current file hash in the database if it is left empty. +# Useful if you want to mark a file as applied but you don't know its hash. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.AllowRehash = 1 + +# +# Updates.CleanDeadRef +# Description: Cleans dead/ orphaned references that occure if a update was deleted or renamed and edited. +# Disable this if you want to know if the database is in a possible "dirty state". +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.CleanDeadRef = 1 + +# +################################################################################################### + ################################################################################################### # WARDEN SETTINGS # @@ -3143,6 +3227,7 @@ Logger.root=5,Console Server Logger.server=3,Console Server Logger.commands.gm=3,Console GM Logger.sql.sql=5,Console DBErrors +Logger.sql.updates=3,Console Server #Logger.achievement=3,Console Server #Logger.ahbot=3,Console Server