aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--CMakeLists.txt7
-rw-r--r--cmake/compiler/clang/settings.cmake2
-rw-r--r--cmake/compiler/gcc/settings.cmake2
-rw-r--r--cmake/compiler/msvc/settings.cmake12
-rw-r--r--cmake/genrev.cmake2
-rw-r--r--cmake/macros/ConfigureScripts.cmake104
-rw-r--r--cmake/macros/FindPCHSupport.cmake2
-rw-r--r--cmake/options.cmake21
-rw-r--r--cmake/platform/win/settings.cmake21
-rw-r--r--cmake/showoptions.cmake20
-rw-r--r--dep/CMakeLists.txt6
-rw-r--r--dep/boost/CMakeLists.txt31
-rw-r--r--dep/efsw/CMakeLists.txt4
-rw-r--r--issue_template.md10
-rw-r--r--revision_data.h.in.cmake2
-rw-r--r--sql/base/auth_database.sql6
-rw-r--r--sql/base/characters_database.sql8
-rw-r--r--sql/base/dev/world_database.sql6
-rw-r--r--sql/old/3.3.5a/auth/60_2016_04_11/2015_11_07_00_auth.sql (renamed from sql/updates/auth/2015_11_07_00_auth.sql)0
-rw-r--r--sql/old/3.3.5a/auth/60_2016_04_11/2016_01_13_00_auth.sql (renamed from sql/updates/auth/2016_01_13_00_auth.sql)0
-rw-r--r--sql/old/3.3.5a/characters/60_2016_04_11/2015_11_07_00_characters.sql (renamed from sql/updates/characters/2015_11_07_00_characters.sql)0
-rw-r--r--sql/old/3.3.5a/characters/60_2016_04_11/2016_02_10_00_characters.sql (renamed from sql/updates/characters/2016_02_10_00_characters.sql)0
-rw-r--r--sql/old/3.3.5a/characters/60_2016_04_11/2016_03_13_2016_01_05_00_characters.sql (renamed from sql/updates/characters/2016_03_13_2016_01_05_00_characters.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_07_02_world.sql (renamed from sql/updates/world/2015_11_07_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_08_00_world.sql (renamed from sql/updates/world/2015_11_08_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_08_01_world.sql (renamed from sql/updates/world/2015_11_08_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_09_00_world.sql (renamed from sql/updates/world/2015_11_09_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_09_01_world.sql (renamed from sql/updates/world/2015_11_09_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_09_02_world_335.sql (renamed from sql/updates/world/2015_11_09_02_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_10_00_world.sql (renamed from sql/updates/world/2015_11_10_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_10_01_world.sql (renamed from sql/updates/world/2015_11_10_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_10_02_world.sql (renamed from sql/updates/world/2015_11_10_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_11_00_world.sql (renamed from sql/updates/world/2015_11_11_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_11_01_world.sql (renamed from sql/updates/world/2015_11_11_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_12_00_world.sql (renamed from sql/updates/world/2015_11_12_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_12_01_world.sql (renamed from sql/updates/world/2015_11_12_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_20_00_world.sql (renamed from sql/updates/world/2015_11_20_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_22_00_world.sql (renamed from sql/updates/world/2015_11_22_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_22_01_world.sql (renamed from sql/updates/world/2015_11_22_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_22_02_world.sql (renamed from sql/updates/world/2015_11_22_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_22_03_world_355.sql (renamed from sql/updates/world/2015_11_22_03_world_355.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_00_world_335.sql (renamed from sql/updates/world/2015_11_23_00_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_01_world_335.sql (renamed from sql/updates/world/2015_11_23_01_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_02_world_335.sql (renamed from sql/updates/world/2015_11_23_02_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_03_world_335.sql (renamed from sql/updates/world/2015_11_23_03_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_04_world_335.sql (renamed from sql/updates/world/2015_11_23_04_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_05_world.sql (renamed from sql/updates/world/2015_11_23_05_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_24_00_world_355.sql (renamed from sql/updates/world/2015_11_24_00_world_355.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_27_00_world.sql (renamed from sql/updates/world/2015_11_27_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_28_00_world.sql (renamed from sql/updates/world/2015_11_28_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_28_01_world_335.sql (renamed from sql/updates/world/2015_11_28_01_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_29_00_world.sql (renamed from sql/updates/world/2015_11_29_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_11_29_01_world.sql (renamed from sql/updates/world/2015_11_29_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_01_00_world.sql (renamed from sql/updates/world/2015_12_01_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_04_00_world.sql (renamed from sql/updates/world/2015_12_04_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_05_00_world.sql (renamed from sql/updates/world/2015_12_05_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_06_00_world.sql (renamed from sql/updates/world/2015_12_06_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_08_00_world_335.sql (renamed from sql/updates/world/2015_12_08_00_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_08_01_world.sql (renamed from sql/updates/world/2015_12_08_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_08_02_world.sql (renamed from sql/updates/world/2015_12_08_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_09_00_world.sql (renamed from sql/updates/world/2015_12_09_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_09_01_world.sql (renamed from sql/updates/world/2015_12_09_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_11_00_world.sql (renamed from sql/updates/world/2015_12_11_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_14_00_world.sql (renamed from sql/updates/world/2015_12_14_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_15_00_world.sql (renamed from sql/updates/world/2015_12_15_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_15_01_world.sql (renamed from sql/updates/world/2015_12_15_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_15_02_world.sql (renamed from sql/updates/world/2015_12_15_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_15_03_world.sql (renamed from sql/updates/world/2015_12_15_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_16_00_world.sql (renamed from sql/updates/world/2015_12_16_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_16_01_world.sql (renamed from sql/updates/world/2015_12_16_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_16_02_world_335.sql (renamed from sql/updates/world/2015_12_16_02_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_17_00_world.sql (renamed from sql/updates/world/2015_12_17_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_18_00_world_335.sql (renamed from sql/updates/world/2015_12_18_00_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_18_01_world.sql (renamed from sql/updates/world/2015_12_18_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_18_02_world.sql (renamed from sql/updates/world/2015_12_18_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_18_03_world_335.sql (renamed from sql/updates/world/2015_12_18_03_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_18_04_world.sql (renamed from sql/updates/world/2015_12_18_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_20_00_world.sql (renamed from sql/updates/world/2015_12_20_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_24_00_world.sql (renamed from sql/updates/world/2015_12_24_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_26_00_world.sql (renamed from sql/updates/world/2015_12_26_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_26_01_world.sql (renamed from sql/updates/world/2015_12_26_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_26_02_world.sql (renamed from sql/updates/world/2015_12_26_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_00_world.sql (renamed from sql/updates/world/2015_12_29_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_01_world.sql (renamed from sql/updates/world/2015_12_29_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_02_world.sql (renamed from sql/updates/world/2015_12_29_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_03_world.sql (renamed from sql/updates/world/2015_12_29_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_04_world.sql (renamed from sql/updates/world/2015_12_29_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_05_world.sql (renamed from sql/updates/world/2015_12_29_05_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_06_world.sql (renamed from sql/updates/world/2015_12_29_06_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_07_world.sql (renamed from sql/updates/world/2015_12_29_07_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_08_world.sql (renamed from sql/updates/world/2015_12_29_08_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_09_world.sql (renamed from sql/updates/world/2015_12_29_09_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_10_world.sql (renamed from sql/updates/world/2015_12_29_10_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_11_world.sql (renamed from sql/updates/world/2015_12_29_11_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_12_world.sql (renamed from sql/updates/world/2015_12_29_12_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_13_world.sql (renamed from sql/updates/world/2015_12_29_13_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_31_00_world.sql (renamed from sql/updates/world/2015_12_31_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2015_12_31_01_world.sql (renamed from sql/updates/world/2015_12_31_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_01_00_world.sql (renamed from sql/updates/world/2016_01_01_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_01_01_world.sql (renamed from sql/updates/world/2016_01_01_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_02_00_world_335.sql (renamed from sql/updates/world/2016_01_02_00_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_02_01_world.sql (renamed from sql/updates/world/2016_01_02_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_00_world_335.sql (renamed from sql/updates/world/2016_01_03_00_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_01_world.sql (renamed from sql/updates/world/2016_01_03_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_02_world.sql (renamed from sql/updates/world/2016_01_03_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_03_world.sql (renamed from sql/updates/world/2016_01_03_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_04_world.sql (renamed from sql/updates/world/2016_01_03_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_05_world.sql (renamed from sql/updates/world/2016_01_03_05_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_04_00_world.sql (renamed from sql/updates/world/2016_01_04_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_05_00_world.sql (renamed from sql/updates/world/2016_01_05_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_05_01_world.sql (renamed from sql/updates/world/2016_01_05_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_05_02_world.sql (renamed from sql/updates/world/2016_01_05_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_07_00_world.sql (renamed from sql/updates/world/2016_01_07_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_07_01_world.sql (renamed from sql/updates/world/2016_01_07_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_07_02_world.sql (renamed from sql/updates/world/2016_01_07_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_08_00_world.sql (renamed from sql/updates/world/2016_01_08_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_08_01_world.sql (renamed from sql/updates/world/2016_01_08_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_08_02_world.sql (renamed from sql/updates/world/2016_01_08_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_08_03_world.sql (renamed from sql/updates/world/2016_01_08_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_09_00_world.sql (renamed from sql/updates/world/2016_01_09_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_00_world.sql (renamed from sql/updates/world/2016_01_10_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_01_world.sql (renamed from sql/updates/world/2016_01_10_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_02_world.sql (renamed from sql/updates/world/2016_01_10_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_03_world.sql (renamed from sql/updates/world/2016_01_10_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_04_world.sql (renamed from sql/updates/world/2016_01_10_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_05_world_335.sql (renamed from sql/updates/world/2016_01_10_05_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_12_00_world.sql (renamed from sql/updates/world/2016_01_12_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_12_01_world_335.sql (renamed from sql/updates/world/2016_01_12_01_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_12_02_world_335.sql (renamed from sql/updates/world/2016_01_12_02_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_12_03_world.sql (renamed from sql/updates/world/2016_01_12_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_12_04_world.sql (renamed from sql/updates/world/2016_01_12_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_13_00_world.sql (renamed from sql/updates/world/2016_01_13_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_15_00_world.sql (renamed from sql/updates/world/2016_01_15_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_00_world_335.sql (renamed from sql/updates/world/2016_01_16_00_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_01_world.sql (renamed from sql/updates/world/2016_01_16_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_02_world.sql (renamed from sql/updates/world/2016_01_16_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_03_world.sql (renamed from sql/updates/world/2016_01_16_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_04_world.sql (renamed from sql/updates/world/2016_01_16_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_05_world.sql (renamed from sql/updates/world/2016_01_16_05_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_00_world_335.sql (renamed from sql/updates/world/2016_01_17_00_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_01_world.sql (renamed from sql/updates/world/2016_01_17_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_02_world.sql (renamed from sql/updates/world/2016_01_17_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_03_world.sql (renamed from sql/updates/world/2016_01_17_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_04_world.sql (renamed from sql/updates/world/2016_01_17_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_05_world.sql (renamed from sql/updates/world/2016_01_17_05_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_06_world.sql (renamed from sql/updates/world/2016_01_17_06_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_07_world.sql (renamed from sql/updates/world/2016_01_17_07_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_08_world.sql (renamed from sql/updates/world/2016_01_17_08_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_09_world.sql (renamed from sql/updates/world/2016_01_17_09_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_10_world.sql (renamed from sql/updates/world/2016_01_17_10_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_11_world.sql (renamed from sql/updates/world/2016_01_17_11_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_12_world.sql (renamed from sql/updates/world/2016_01_17_12_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_13_world.sql (renamed from sql/updates/world/2016_01_17_13_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_14_world.sql (renamed from sql/updates/world/2016_01_17_14_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_15_world.sql (renamed from sql/updates/world/2016_01_17_15_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_00_world.sql (renamed from sql/updates/world/2016_01_18_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_01_world.sql (renamed from sql/updates/world/2016_01_18_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_02_world.sql (renamed from sql/updates/world/2016_01_18_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_03_world.sql (renamed from sql/updates/world/2016_01_18_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_04_world.sql (renamed from sql/updates/world/2016_01_18_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_05_world.sql (renamed from sql/updates/world/2016_01_18_05_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_06_world.sql (renamed from sql/updates/world/2016_01_18_06_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_00_world.sql (renamed from sql/updates/world/2016_01_19_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_01_world.sql (renamed from sql/updates/world/2016_01_19_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_02_world.sql (renamed from sql/updates/world/2016_01_19_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_03_world.sql (renamed from sql/updates/world/2016_01_19_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_04_world.sql (renamed from sql/updates/world/2016_01_19_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_05_world.sql (renamed from sql/updates/world/2016_01_19_05_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_06_world.sql (renamed from sql/updates/world/2016_01_19_06_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_07_world.sql (renamed from sql/updates/world/2016_01_19_07_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_08_world.sql (renamed from sql/updates/world/2016_01_19_08_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_20_00_world.sql (renamed from sql/updates/world/2016_01_20_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_20_01_world.sql (renamed from sql/updates/world/2016_01_20_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_20_02_world.sql (renamed from sql/updates/world/2016_01_20_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_23_00_world.sql (renamed from sql/updates/world/2016_01_23_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_24_00_world.sql (renamed from sql/updates/world/2016_01_24_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_26_00_world.sql (renamed from sql/updates/world/2016_01_26_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_28_00_world_335.sql (renamed from sql/updates/world/2016_01_28_00_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_28_01_world.sql (renamed from sql/updates/world/2016_01_28_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_00_world_335.sql (renamed from sql/updates/world/2016_01_30_00_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_01_world.sql (renamed from sql/updates/world/2016_01_30_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_02_world.sql (renamed from sql/updates/world/2016_01_30_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_03_world.sql (renamed from sql/updates/world/2016_01_30_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_04_world.sql (renamed from sql/updates/world/2016_01_30_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_05_world.sql (renamed from sql/updates/world/2016_01_30_05_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_01_31_00_world.sql (renamed from sql/updates/world/2016_01_31_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_02_00_world.sql (renamed from sql/updates/world/2016_02_02_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_02_01_world.sql (renamed from sql/updates/world/2016_02_02_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_04_00_world.sql (renamed from sql/updates/world/2016_02_04_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_05_00_world.sql (renamed from sql/updates/world/2016_02_05_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_00_world.sql (renamed from sql/updates/world/2016_02_06_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_01_world.sql (renamed from sql/updates/world/2016_02_06_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_02_world.sql (renamed from sql/updates/world/2016_02_06_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_03_world.sql (renamed from sql/updates/world/2016_02_06_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_04_world.sql (renamed from sql/updates/world/2016_02_06_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_05_world.sql (renamed from sql/updates/world/2016_02_06_05_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_06_world.sql (renamed from sql/updates/world/2016_02_06_06_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_07_world.sql (renamed from sql/updates/world/2016_02_06_07_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_08_world.sql (renamed from sql/updates/world/2016_02_06_08_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_09_world.sql (renamed from sql/updates/world/2016_02_06_09_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_10_world.sql (renamed from sql/updates/world/2016_02_06_10_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_11_world.sql (renamed from sql/updates/world/2016_02_06_11_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_12_world.sql (renamed from sql/updates/world/2016_02_06_12_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_13_world_335.sql (renamed from sql/updates/world/2016_02_06_13_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_14_world.sql (renamed from sql/updates/world/2016_02_06_14_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_00_world.sql (renamed from sql/updates/world/2016_02_07_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_01_world_335.sql (renamed from sql/updates/world/2016_02_07_01_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_02_world_335.sql (renamed from sql/updates/world/2016_02_07_02_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_03_world_335.sql (renamed from sql/updates/world/2016_02_07_03_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_04_world.sql (renamed from sql/updates/world/2016_02_07_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_05_world_335.sql (renamed from sql/updates/world/2016_02_07_05_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_06_world.sql (renamed from sql/updates/world/2016_02_07_06_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_07_world_335.sql (renamed from sql/updates/world/2016_02_07_07_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_08_world_335.sql (renamed from sql/updates/world/2016_02_07_08_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_09_world.sql (renamed from sql/updates/world/2016_02_07_09_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_10_world.sql (renamed from sql/updates/world/2016_02_07_10_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_11_world.sql (renamed from sql/updates/world/2016_02_07_11_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_12_world.sql (renamed from sql/updates/world/2016_02_07_12_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_13_world.sql (renamed from sql/updates/world/2016_02_07_13_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_14_world.sql (renamed from sql/updates/world/2016_02_07_14_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_15_world.sql (renamed from sql/updates/world/2016_02_07_15_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_00_world_335.sql (renamed from sql/updates/world/2016_02_08_00_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_01_world.sql (renamed from sql/updates/world/2016_02_08_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_02_world.sql (renamed from sql/updates/world/2016_02_08_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_03_world.sql (renamed from sql/updates/world/2016_02_08_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_04_world.sql (renamed from sql/updates/world/2016_02_08_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_05_world.sql (renamed from sql/updates/world/2016_02_08_05_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_06_world.sql (renamed from sql/updates/world/2016_02_08_06_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_07_world.sql (renamed from sql/updates/world/2016_02_08_07_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_08_world.sql (renamed from sql/updates/world/2016_02_08_08_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_00_world.sql (renamed from sql/updates/world/2016_02_09_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_01_world.sql (renamed from sql/updates/world/2016_02_09_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_02_world.sql (renamed from sql/updates/world/2016_02_09_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_02_world_335.sql (renamed from sql/updates/world/2016_02_09_02_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_03_world.sql (renamed from sql/updates/world/2016_02_09_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_04_world.sql (renamed from sql/updates/world/2016_02_09_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_05_world.sql (renamed from sql/updates/world/2016_02_09_05_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_06_world.sql (renamed from sql/updates/world/2016_02_09_06_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_07_world.sql (renamed from sql/updates/world/2016_02_09_07_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_08_world.sql (renamed from sql/updates/world/2016_02_09_08_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_00_world.sql (renamed from sql/updates/world/2016_02_10_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_01_world.sql (renamed from sql/updates/world/2016_02_10_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_02_world.sql (renamed from sql/updates/world/2016_02_10_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_03_world.sql (renamed from sql/updates/world/2016_02_10_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_04_world.sql (renamed from sql/updates/world/2016_02_10_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_05_world.sql (renamed from sql/updates/world/2016_02_10_05_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_06_world.sql (renamed from sql/updates/world/2016_02_10_06_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_07_world.sql (renamed from sql/updates/world/2016_02_10_07_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_00_world.sql (renamed from sql/updates/world/2016_02_11_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_01_world.sql (renamed from sql/updates/world/2016_02_11_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_02_world.sql (renamed from sql/updates/world/2016_02_11_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_03_world.sql (renamed from sql/updates/world/2016_02_11_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_04_world.sql (renamed from sql/updates/world/2016_02_11_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_05_world.sql (renamed from sql/updates/world/2016_02_11_05_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_06_world.sql (renamed from sql/updates/world/2016_02_11_06_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_07_world.sql (renamed from sql/updates/world/2016_02_11_07_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_12_00_world.sql (renamed from sql/updates/world/2016_02_12_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_13_00_world.sql (renamed from sql/updates/world/2016_02_13_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_13_01_world.sql (renamed from sql/updates/world/2016_02_13_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_13_02_world.sql (renamed from sql/updates/world/2016_02_13_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_13_03_world.sql (renamed from sql/updates/world/2016_02_13_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_13_04_world.sql (renamed from sql/updates/world/2016_02_13_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_14_00_world.sql (renamed from sql/updates/world/2016_02_14_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_14_01_world.sql (renamed from sql/updates/world/2016_02_14_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_14_02_world.sql (renamed from sql/updates/world/2016_02_14_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_14_03_world.sql (renamed from sql/updates/world/2016_02_14_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_14_04_world.sql (renamed from sql/updates/world/2016_02_14_04_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_15_00_world.sql (renamed from sql/updates/world/2016_02_15_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_17_00_world.sql (renamed from sql/updates/world/2016_02_17_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_17_01_world.sql (renamed from sql/updates/world/2016_02_17_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_17_02_world.sql (renamed from sql/updates/world/2016_02_17_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_18_00_world.sql (renamed from sql/updates/world/2016_02_18_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_18_01_world.sql (renamed from sql/updates/world/2016_02_18_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_18_02_world.sql (renamed from sql/updates/world/2016_02_18_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_19_00_world.sql (renamed from sql/updates/world/2016_02_19_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_19_01_world_335.sql (renamed from sql/updates/world/2016_02_19_01_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_22_00_world.sql (renamed from sql/updates/world/2016_02_22_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_22_01_world.sql (renamed from sql/updates/world/2016_02_22_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_22_02_world.sql (renamed from sql/updates/world/2016_02_22_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_23_00_world.sql (renamed from sql/updates/world/2016_02_23_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_23_01_world.sql (renamed from sql/updates/world/2016_02_23_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_23_02_world.sql (renamed from sql/updates/world/2016_02_23_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_24_00_world.sql (renamed from sql/updates/world/2016_02_24_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_25_00_world.sql (renamed from sql/updates/world/2016_02_25_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_25_01_world_335.sql (renamed from sql/updates/world/2016_02_25_01_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_25_02_world.sql (renamed from sql/updates/world/2016_02_25_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_26_00_world.sql (renamed from sql/updates/world/2016_02_26_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_26_01_world.sql (renamed from sql/updates/world/2016_02_26_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_27_00_world.sql (renamed from sql/updates/world/2016_02_27_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_28_00_world.sql (renamed from sql/updates/world/2016_02_28_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_29_00_world.sql (renamed from sql/updates/world/2016_02_29_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_02_29_01_world.sql (renamed from sql/updates/world/2016_02_29_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_01_00_world_335.sql (renamed from sql/updates/world/2016_03_01_00_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_02_00_world_335.sql (renamed from sql/updates/world/2016_03_02_00_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_03_00_world.sql (renamed from sql/updates/world/2016_03_03_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_03_01_world.sql (renamed from sql/updates/world/2016_03_03_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_04_00_world.sql (renamed from sql/updates/world/2016_03_04_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_04_01_world.sql (renamed from sql/updates/world/2016_03_04_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_04_02_world_335.sql (renamed from sql/updates/world/2016_03_04_02_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_04_03_world.sql (renamed from sql/updates/world/2016_03_04_03_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_05_00_world.sql (renamed from sql/updates/world/2016_03_05_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_06_00_world.sql (renamed from sql/updates/world/2016_03_06_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_06_01_world.sql (renamed from sql/updates/world/2016_03_06_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_07_00_world.sql (renamed from sql/updates/world/2016_03_07_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_07_01_world.sql (renamed from sql/updates/world/2016_03_07_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_09_00_world.sql (renamed from sql/updates/world/2016_03_09_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_10_00_world.sql (renamed from sql/updates/world/2016_03_10_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_10_01_world.sql (renamed from sql/updates/world/2016_03_10_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_12_2015_11_14_00_world.sql (renamed from sql/updates/world/2016_03_12_2015_11_14_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_13_00_world.sql (renamed from sql/updates/world/2016_03_13_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_13_01_world.sql (renamed from sql/updates/world/2016_03_13_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_15_00_world.sql (renamed from sql/updates/world/2016_03_15_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_19_00_world.sql (renamed from sql/updates/world/2016_03_19_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_19_01_world.sql (renamed from sql/updates/world/2016_03_19_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_19_02_world.sql (renamed from sql/updates/world/2016_03_19_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_20_00_world.sql (renamed from sql/updates/world/2016_03_20_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_20_01_world.sql (renamed from sql/updates/world/2016_03_20_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_20_02_world.sql (renamed from sql/updates/world/2016_03_20_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_21_00_world.sql (renamed from sql/updates/world/2016_03_21_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_23_00_world.sql (renamed from sql/updates/world/2016_03_23_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_24_00_world_335.sql (renamed from sql/updates/world/2016_03_24_00_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_24_01_world_335.sql (renamed from sql/updates/world/2016_03_24_01_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_24_02_world.sql (renamed from sql/updates/world/2016_03_24_02_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_26_00_world.sql (renamed from sql/updates/world/2016_03_26_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_27_00_world.sql (renamed from sql/updates/world/2016_03_27_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_28_00_world.sql (renamed from sql/updates/world/2016_03_28_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_28_01_world.sql (renamed from sql/updates/world/2016_03_28_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_03_29_00_world_335.sql (renamed from sql/updates/world/2016_03_29_00_world_335.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_01_00_world.sql (renamed from sql/updates/world/2016_04_01_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_01_01_world.sql (renamed from sql/updates/world/2016_04_01_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_02_00_world.sql (renamed from sql/updates/world/2016_04_02_00_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_02_01_world.sql (renamed from sql/updates/world/2016_04_02_01_world.sql)0
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_02_02_world.sql3
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_03_00_world.sql2
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_03_01_world.sql36
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_03_02_world.sql2
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_04_00_world.sql149
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_05_00_world.sql2
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_05_01_world.sql2
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_08_00_world.sql133
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_00_world_2016_03_28_00_world.sql3
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_01_world.sql2
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_02_world.sql44
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_03_world.sql5
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_04_world.sql9
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_05_world.sql41
-rw-r--r--sql/old/3.3.5a/world/60_2016_04_11/2016_04_10_00_world.sql20
-rw-r--r--sql/updates/auth/2016_04_11_00_auth.sql1
-rw-r--r--sql/updates/characters/2016_04_11_00_characters.sql1
-rw-r--r--sql/updates/world/2016_04_11_00_world.sql3
-rw-r--r--sql/updates/world/2016_04_11_01_world_335.sql2
-rw-r--r--sql/updates/world/2016_04_11_02_world_335.sql2
-rw-r--r--sql/updates/world/2016_04_15_03_world_335.sql2
-rw-r--r--sql/updates/world/dummy0
-rw-r--r--src/common/CMakeLists.txt6
-rw-r--r--src/common/Collision/Management/MMapManager.h2
-rw-r--r--src/common/Common.h39
-rw-r--r--src/common/Logging/Appender.h2
-rw-r--r--src/common/Utilities/EventMap.h12
-rw-r--r--src/common/Utilities/MessageBuffer.h (renamed from src/server/shared/Networking/MessageBuffer.h)1
-rw-r--r--src/common/Utilities/StartProcess.cpp267
-rw-r--r--src/common/Utilities/StartProcess.h67
-rw-r--r--src/common/Utilities/TaskScheduler.h2
-rw-r--r--src/common/Utilities/Util.cpp46
-rw-r--r--src/common/Utilities/Util.h3
-rw-r--r--src/server/authserver/CMakeLists.txt2
-rw-r--r--src/server/authserver/Server/AuthSession.cpp2
-rw-r--r--src/server/authserver/authserver.conf.dist7
-rw-r--r--src/server/database/CMakeLists.txt3
-rw-r--r--src/server/database/Database/DatabaseWorkerPool.cpp2
-rw-r--r--src/server/database/Database/Field.h2
-rw-r--r--src/server/database/Database/PreparedStatement.cpp2
-rw-r--r--src/server/database/Database/QueryResult.cpp2
-rw-r--r--src/server/database/Updater/DBUpdater.cpp70
-rw-r--r--src/server/database/Updater/UpdateFetcher.cpp2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp2
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp2
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp45
-rw-r--r--src/server/game/CMakeLists.txt27
-rw-r--r--src/server/game/Chat/Chat.cpp26
-rw-r--r--src/server/game/Chat/Chat.h4
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp4
-rw-r--r--src/server/game/DataStores/DBCStores.cpp250
-rw-r--r--src/server/game/DataStores/DBCStores.h5
-rw-r--r--src/server/game/DataStores/DBCStructure.h12
-rw-r--r--src/server/game/DataStores/DBCfmt.h3
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.cpp4
-rw-r--r--src/server/game/DungeonFinding/LFGQueue.cpp12
-rw-r--r--src/server/game/DungeonFinding/LFGQueue.h3
-rw-r--r--src/server/game/DungeonFinding/LFGScripts.cpp6
-rw-r--r--src/server/game/DungeonFinding/LFGScripts.h2
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp32
-rw-r--r--src/server/game/Entities/Creature/Creature.h1
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp12
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h4
-rw-r--r--src/server/game/Entities/Object/Object.cpp23
-rw-r--r--src/server/game/Entities/Object/Object.h1
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp11
-rw-r--r--src/server/game/Entities/Player/Player.cpp322
-rw-r--r--src/server/game/Entities/Player/Player.h127
-rw-r--r--src/server/game/Entities/Unit/StatSystem.cpp4
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp20
-rw-r--r--src/server/game/Entities/Unit/Unit.h38
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp100
-rw-r--r--src/server/game/Globals/ObjectMgr.h3
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp25
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp12
-rw-r--r--src/server/game/Handlers/SpellHandler.cpp10
-rw-r--r--src/server/game/Instances/InstanceScript.cpp14
-rw-r--r--src/server/game/Instances/InstanceScript.h8
-rw-r--r--src/server/game/Loot/LootMgr.h4
-rw-r--r--src/server/game/Maps/AreaBoundary.h2
-rw-r--r--src/server/game/Maps/Map.cpp16
-rw-r--r--src/server/game/Maps/MapManager.cpp2
-rw-r--r--src/server/game/Maps/MapManager.h8
-rw-r--r--src/server/game/Maps/MapScripts.cpp (renamed from src/server/game/Scripting/MapScripts.cpp)7
-rw-r--r--src/server/game/Miscellaneous/Language.h4
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h2
-rw-r--r--src/server/game/Movement/MotionMaster.cpp21
-rw-r--r--src/server/game/Movement/MotionMaster.h6
-rw-r--r--src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp6
-rw-r--r--src/server/game/Quests/QuestDef.h2
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp1124
-rw-r--r--src/server/game/Scripting/ScriptMgr.h72
-rw-r--r--src/server/game/Scripting/ScriptReloadMgr.cpp1520
-rw-r--r--src/server/game/Scripting/ScriptReloadMgr.h81
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp28
-rw-r--r--src/server/game/Spells/Spell.cpp4
-rw-r--r--src/server/game/Spells/SpellEffects.cpp7
-rw-r--r--src/server/game/Spells/SpellHistory.cpp8
-rw-r--r--src/server/game/Spells/SpellMgr.h2
-rw-r--r--src/server/game/Spells/SpellScript.cpp7
-rw-r--r--src/server/game/Spells/SpellScript.h11
-rw-r--r--src/server/game/World/World.cpp18
-rw-r--r--src/server/game/World/World.h7
-rw-r--r--src/server/scripts/CMakeLists.txt253
-rw-r--r--src/server/scripts/Commands/cs_account.cpp10
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp17
-rw-r--r--src/server/scripts/Commands/cs_modify.cpp4
-rw-r--r--src/server/scripts/Commands/cs_reload.cpp10
-rw-r--r--src/server/scripts/Commands/cs_reset.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp2
-rw-r--r--src/server/scripts/Kalimdor/kalimdor_script_loader.cpp2
-rw-r--r--src/server/scripts/Kalimdor/zone_the_barrens.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp6
-rw-r--r--src/server/scripts/ScriptLoader.cpp51
-rw-r--r--src/server/scripts/ScriptLoader.cpp.in.cmake64
-rw-r--r--src/server/scripts/ScriptPCH.cpp (renamed from src/server/scripts/PrecompiledHeaders/ScriptPCH.cpp)0
-rw-r--r--src/server/scripts/ScriptPCH.h (renamed from src/server/scripts/PrecompiledHeaders/ScriptPCH.h)0
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp4
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp4
-rw-r--r--src/server/scripts/Spells/spell_holiday.cpp4
-rw-r--r--src/server/scripts/Spells/spell_hunter.cpp2
-rw-r--r--src/server/scripts/Spells/spell_mage.cpp4
-rw-r--r--src/server/scripts/Spells/spell_paladin.cpp2
-rw-r--r--src/server/scripts/Spells/spell_pet.cpp6
-rw-r--r--src/server/scripts/Spells/spell_priest.cpp2
-rw-r--r--src/server/scripts/Spells/spell_rogue.cpp2
-rw-r--r--src/server/scripts/Spells/spell_warlock.cpp4
-rw-r--r--src/server/scripts/Spells/spell_warrior.cpp2
-rw-r--r--src/server/scripts/World/duel_reset.cpp4
-rw-r--r--src/server/shared/CMakeLists.txt2
-rw-r--r--src/server/shared/DataStores/DBCStore.h115
-rw-r--r--src/server/shared/Packets/ByteBuffer.h9
-rw-r--r--src/server/shared/Realm/Realm.cpp35
-rw-r--r--src/server/shared/Realm/Realm.h24
-rw-r--r--src/server/shared/Realm/RealmList.cpp (renamed from src/server/authserver/Realms/RealmList.cpp)52
-rw-r--r--src/server/shared/Realm/RealmList.h (renamed from src/server/authserver/Realms/RealmList.h)12
-rw-r--r--src/server/worldserver/CMakeLists.txt8
-rw-r--r--src/server/worldserver/Main.cpp2
-rw-r--r--src/server/worldserver/worldserver.conf.dist75
-rw-r--r--src/tools/map_extractor/System.cpp74
477 files changed, 5357 insertions, 940 deletions
diff --git a/.travis.yml b/.travis.yml
index 894fedf4da6..80e237e4d12 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,12 +16,14 @@ before_install:
- sudo apt-get -qq install libssl-dev libmysqlclient-dev libmysql++-dev libreadline6-dev zlib1g-dev libbz2-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
- export CC=clang-3.5 CXX=clang++-3.5
+ - git config user.email "travis@build.bot" && git config user.name "Travis CI"
+ - git tag -a -m "Travis build" init
install:
- mysql -uroot -e 'create database test_mysql;'
- mkdir bin
- cd bin
- - cmake ../ -DWITH_WARNINGS=1 -DWITH_COREDEBUG=0 -DUSE_COREPCH=1 -DUSE_SCRIPTPCH=1 -DTOOLS=1 -DSCRIPTS=1 -DSERVERS=1 -DNOJEM=1 -DWITH_DYNAMIC_LINKING=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-Werror" -DCMAKE_CXX_FLAGS="-Werror" -DCMAKE_INSTALL_PREFIX=check_install
+ - cmake ../ -DWITH_WARNINGS=1 -DWITH_COREDEBUG=0 -DUSE_COREPCH=1 -DUSE_SCRIPTPCH=1 -DTOOLS=1 -DSCRIPTS="dynamic" -DSERVERS=1 -DNOJEM=1 -DWITH_DYNAMIC_LINKING=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-Werror" -DCMAKE_CXX_FLAGS="-Werror" -DCMAKE_INSTALL_PREFIX=check_install
- cd ..
- sudo chmod +x contrib/check_updates.sh
diff --git a/CMakeLists.txt b/CMakeLists.txt
index dda8f242feb..de08fe3181f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,7 +18,11 @@ project(TrinityCore)
cmake_policy(SET CMP0005 OLD)
if(POLICY CMP0043)
cmake_policy(SET CMP0043 OLD) # Disable 'Ignore COMPILE_DEFINITIONS_<Config> properties'
-endif(POLICY CMP0043)
+endif()
+
+if(POLICY CMP0054)
+ cmake_policy(SET CMP0054 NEW) # Only interpret if() arguments as variables or keywords when unquoted - prevents intepreting if (SOME_STRING_VARIABLE MATCHES "MSVC") as if (SOME_STRING_VARIABLE MATCHES "1")
+endif()
# add this options before PROJECT keyword
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
@@ -40,6 +44,7 @@ endif()
include(CheckCXXSourceRuns)
include(CheckIncludeFiles)
+include(ConfigureScripts)
# set default buildoptions and print them
include(cmake/options.cmake)
diff --git a/cmake/compiler/clang/settings.cmake b/cmake/compiler/clang/settings.cmake
index 9a8cb85275e..1cd95bbf703 100644
--- a/cmake/compiler/clang/settings.cmake
+++ b/cmake/compiler/clang/settings.cmake
@@ -19,7 +19,7 @@ endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-narrowing -Wno-deprecated-register")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG=1")
-if (WITH_DYNAMIC_LINKING)
+if (BUILD_SHARED_LIBS)
# -fPIC is needed to allow static linking in shared libs.
# -fvisibility=hidden sets the default visibility to hidden to prevent exporting of all symbols.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -fvisibility=hidden")
diff --git a/cmake/compiler/gcc/settings.cmake b/cmake/compiler/gcc/settings.cmake
index d9eda767b8e..c4f97f4ffd4 100644
--- a/cmake/compiler/gcc/settings.cmake
+++ b/cmake/compiler/gcc/settings.cmake
@@ -35,7 +35,7 @@ if( WITH_COREDEBUG )
message(STATUS "GCC: Debug-flags set (-g3)")
endif()
-if (WITH_DYNAMIC_LINKING)
+if (BUILD_SHARED_LIBS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -fvisibility=hidden -Wno-attributes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -fvisibility=hidden -Wno-attributes")
diff --git a/cmake/compiler/msvc/settings.cmake b/cmake/compiler/msvc/settings.cmake
index c2eda80512b..afde70b0f79 100644
--- a/cmake/compiler/msvc/settings.cmake
+++ b/cmake/compiler/msvc/settings.cmake
@@ -31,12 +31,18 @@ else()
endif()
# Set build-directive (used in core to tell which buildtype we used)
-add_definitions(-D_BUILD_DIRECTIVE=\\"$(ConfigurationName)\\")
+# msbuild/devenv don't set CMAKE_MAKE_PROGRAM, you can choose build type from a dropdown after generating projects
+if("${CMAKE_MAKE_PROGRAM}" MATCHES "MSBuild")
+ add_definitions(-D_BUILD_DIRECTIVE=\\"$(ConfigurationName)\\")
+else()
+ # while all make-like generators do (nmake, ninja)
+ add_definitions(-D_BUILD_DIRECTIVE=\\"${CMAKE_BUILD_TYPE}\\")
+endif()
# multithreaded compiling on VS
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
-if((PLATFORM EQUAL 64) OR (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0.23026.0) OR WITH_DYNAMIC_LINKING)
+if((PLATFORM EQUAL 64) OR (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0.23026.0) OR BUILD_SHARED_LIBS)
# Enable extended object support
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
message(STATUS "MSVC: Enabled increased number of sections in object files")
@@ -74,7 +80,7 @@ if(NOT WITH_WARNINGS)
message(STATUS "MSVC: Disabled generic compiletime warnings")
endif()
-if (WITH_DYNAMIC_LINKING)
+if (BUILD_SHARED_LIBS)
# C4251: needs to have dll-interface to be used by clients of class '...'
# C4275: non dll-interface class ...' used as base for dll-interface class '...'
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251 /wd4275")
diff --git a/cmake/genrev.cmake b/cmake/genrev.cmake
index 5c013756f09..d123153e975 100644
--- a/cmake/genrev.cmake
+++ b/cmake/genrev.cmake
@@ -24,7 +24,7 @@ else()
if(GIT_EXECUTABLE)
# Create a revision-string that we can use
execute_process(
- COMMAND "${GIT_EXECUTABLE}" describe --match init --dirty=+ --abbrev=12
+ COMMAND "${GIT_EXECUTABLE}" describe --long --match init --dirty=+ --abbrev=12
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE rev_info
OUTPUT_STRIP_TRAILING_WHITESPACE
diff --git a/cmake/macros/ConfigureScripts.cmake b/cmake/macros/ConfigureScripts.cmake
new file mode 100644
index 00000000000..5260d3a1afe
--- /dev/null
+++ b/cmake/macros/ConfigureScripts.cmake
@@ -0,0 +1,104 @@
+# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# Returns the base path to the script directory in the source directory
+function(WarnAboutSpacesInBuildPath)
+ # Only check win32 since unix doesn't allow spaces in paths
+ if (WIN32)
+ string(FIND "${CMAKE_BINARY_DIR}" " " SPACE_INDEX_POS)
+
+ if (SPACE_INDEX_POS GREATER -1)
+ message("")
+ message(WARNING " *** WARNING!\n"
+ " *** Your selected build directory contains spaces!\n"
+ " *** Please note that this will cause issues!")
+ endif()
+ endif()
+endfunction()
+
+# Returns the base path to the script directory in the source directory
+function(GetScriptsBasePath variable)
+ set(${variable} "${CMAKE_SOURCE_DIR}/src/server/scripts" PARENT_SCOPE)
+endfunction()
+
+# Stores the absolut path of the given module in the variable
+function(GetPathToScriptModule module variable)
+ GetScriptsBasePath(SCRIPTS_BASE_PATH)
+ set(${variable} "${SCRIPTS_BASE_PATH}/${module}" PARENT_SCOPE)
+endfunction()
+
+# Stores the project name of the given module in the variable
+function(GetProjectNameOfScriptModule module variable)
+ string(TOLOWER "scripts_${SCRIPT_MODULE}" GENERATED_NAME)
+ set(${variable} "${GENERATED_NAME}" PARENT_SCOPE)
+endfunction()
+
+# Creates a list of all script modules
+# and stores it in the given variable.
+function(GetScriptModuleList variable)
+ GetScriptsBasePath(BASE_PATH)
+ file(GLOB LOCALE_SCRIPT_MODULE_LIST RELATIVE
+ ${BASE_PATH}
+ ${BASE_PATH}/*)
+
+ set(${variable})
+ foreach(SCRIPT_MODULE ${LOCALE_SCRIPT_MODULE_LIST})
+ GetPathToScriptModule(${SCRIPT_MODULE} SCRIPT_MODULE_PATH)
+ if (IS_DIRECTORY ${SCRIPT_MODULE_PATH})
+ list(APPEND ${variable} ${SCRIPT_MODULE})
+ endif()
+ endforeach()
+ set(${variable} ${${variable}} PARENT_SCOPE)
+endfunction()
+
+# Converts the given script module name into it's
+# variable name which holds the linkage type.
+function(ScriptModuleNameToVariable module variable)
+ string(TOUPPER ${module} ${variable})
+ set(${variable} "SCRIPTS_${${variable}}")
+ set(${variable} ${${variable}} PARENT_SCOPE)
+endfunction()
+
+# Stores in the given variable whether dynamic linking is required
+function(IsDynamicLinkingRequired variable)
+ if(SCRIPTS MATCHES "dynamic")
+ set(IS_DEFAULT_VALUE_DYNAMIC ON)
+ endif()
+
+ GetScriptModuleList(SCRIPT_MODULE_LIST)
+ set(IS_REQUIRED OFF)
+ foreach(SCRIPT_MODULE ${SCRIPT_MODULE_LIST})
+ ScriptModuleNameToVariable(${SCRIPT_MODULE} SCRIPT_MODULE_VARIABLE)
+ if ((${SCRIPT_MODULE_VARIABLE} STREQUAL "dynamic") OR
+ (${SCRIPT_MODULE_VARIABLE} STREQUAL "default" AND IS_DEFAULT_VALUE_DYNAMIC))
+ set(IS_REQUIRED ON)
+ break()
+ endif()
+ endforeach()
+ set(${variable} ${IS_REQUIRED} PARENT_SCOPE)
+endfunction()
+
+# Stores the native variable name
+function(GetNativeSharedLibraryName module variable)
+ if(WIN32)
+ set(${variable} "${module}.dll" PARENT_SCOPE)
+ else()
+ set(${variable} "lib${module}.so" PARENT_SCOPE)
+ endif()
+endfunction()
+
+# Stores the native install path in the variable
+function(GetInstallOffset variable)
+ if(WIN32)
+ set(${variable} "${CMAKE_INSTALL_PREFIX}/scripts" PARENT_SCOPE)
+ else()
+ set(${variable} "${CMAKE_INSTALL_PREFIX}/bin/scripts" PARENT_SCOPE)
+ endif()
+endfunction()
diff --git a/cmake/macros/FindPCHSupport.cmake b/cmake/macros/FindPCHSupport.cmake
index 6edc8e92890..9cc39a13b04 100644
--- a/cmake/macros/FindPCHSupport.cmake
+++ b/cmake/macros/FindPCHSupport.cmake
@@ -143,7 +143,7 @@ FUNCTION(ADD_CXX_PCH_XCODE TARGET_NAME_LIST PCH_HEADER PCH_SOURCE)
ENDFUNCTION(ADD_CXX_PCH_XCODE)
FUNCTION(ADD_CXX_PCH TARGET_NAME_LIST PCH_HEADER PCH_SOURCE)
- IF (MSVC)
+ IF (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
ADD_CXX_PCH_MSVC("${TARGET_NAME_LIST}" ${PCH_HEADER} ${PCH_SOURCE})
ELSEIF ("${CMAKE_GENERATOR}" MATCHES "Xcode")
ADD_CXX_PCH_XCODE("${TARGET_NAME_LIST}" ${PCH_HEADER} ${PCH_SOURCE})
diff --git a/cmake/options.cmake b/cmake/options.cmake
index 62810b2d3f2..085a45fa03f 100644
--- a/cmake/options.cmake
+++ b/cmake/options.cmake
@@ -9,11 +9,30 @@
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
option(SERVERS "Build worldserver and authserver" 1)
-option(SCRIPTS "Build core with scripts included" 1)
+set(SCRIPTS "static" CACHE STRING "Build core with scripts")
+set_property(CACHE SCRIPTS PROPERTY STRINGS none static dynamic minimal-static minimal-dynamic)
+
+# Build a list of all script modules when -DSCRIPT="custom" is selected
+GetScriptModuleList(SCRIPT_MODULE_LIST)
+foreach(SCRIPT_MODULE ${SCRIPT_MODULE_LIST})
+ ScriptModuleNameToVariable(${SCRIPT_MODULE} SCRIPT_MODULE_VARIABLE)
+ set(${SCRIPT_MODULE_VARIABLE} "default" CACHE STRING "Build type of the ${SCRIPT_MODULE} module.")
+ set_property(CACHE ${SCRIPT_MODULE_VARIABLE} PROPERTY STRINGS default disabled static dynamic)
+endforeach()
+
option(TOOLS "Build map/vmap/mmap extraction/assembler tools" 0)
option(USE_SCRIPTPCH "Use precompiled headers when compiling scripts" 1)
option(USE_COREPCH "Use precompiled headers when compiling servers" 1)
option(WITH_DYNAMIC_LINKING "Enable dynamic library linking." 0)
+IsDynamicLinkingRequired(WITH_DYNAMIC_LINKING_FORCED)
+if (WITH_DYNAMIC_LINKING AND WITH_DYNAMIC_LINKING_FORCED)
+ set(WITH_DYNAMIC_LINKING_FORCED OFF)
+endif()
+if (WITH_DYNAMIC_LINKING OR WITH_DYNAMIC_LINKING_FORCED)
+ set(BUILD_SHARED_LIBS ON)
+else()
+ set(BUILD_SHARED_LIBS OFF)
+endif()
option(WITH_WARNINGS "Show all warnings during compile" 0)
option(WITH_COREDEBUG "Include additional debug-code in core" 0)
set(WITH_SOURCE_TREE "hierarchical" CACHE STRING "Build the source tree for IDE's.")
diff --git a/cmake/platform/win/settings.cmake b/cmake/platform/win/settings.cmake
index da66daf0832..0c1a103304a 100644
--- a/cmake/platform/win/settings.cmake
+++ b/cmake/platform/win/settings.cmake
@@ -1,20 +1,9 @@
-# check the CMake preload parameters (commented out by default)
+add_definitions(-D_WIN32_WINNT=0x0601)
-# overload CMAKE_INSTALL_PREFIX if not being set properly
-#if( WIN32 )
-# if( NOT CYGWIN )
-# if( NOT CMAKE_INSTALL_PREFIX )
-# set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/bin")
-# endif()
-# endif()
-#endif()
-
-if (WIN32)
- add_definitions(-D_WIN32_WINNT=0x0601)
-endif()
-
-if ( MSVC )
+if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
include(${CMAKE_SOURCE_DIR}/cmake/compiler/msvc/settings.cmake)
-elseif ( MINGW )
+elseif (CMAKE_CXX_PLATFORM_ID MATCHES "MinGW")
include(${CMAKE_SOURCE_DIR}/cmake/compiler/mingw/settings.cmake)
+elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ include(${CMAKE_SOURCE_DIR}/cmake/compiler/clang/settings.cmake)
endif()
diff --git a/cmake/showoptions.cmake b/cmake/showoptions.cmake
index e6d709207b3..9229590381a 100644
--- a/cmake/showoptions.cmake
+++ b/cmake/showoptions.cmake
@@ -23,9 +23,8 @@ else()
message("* Build world/authserver : No")
endif()
-if( SCRIPTS )
- message("* Build with scripts : Yes (default)")
- add_definitions(-DSCRIPTS)
+if(SCRIPTS AND (NOT SCRIPTS STREQUAL "none"))
+ message("* Build with scripts : Yes (${SCRIPTS})")
else()
message("* Build with scripts : No")
endif()
@@ -70,7 +69,7 @@ else()
endif()
if( NOT WITH_SOURCE_TREE STREQUAL "no" )
- message("* Show source tree : Yes - \"${WITH_SOURCE_TREE}\"")
+ message("* Show source tree : Yes (${WITH_SOURCE_TREE})")
else()
message("* Show source tree : No")
endif()
@@ -87,7 +86,7 @@ if ( WITHOUT_GIT )
message(" *** version of git for the revision-hash to work, and be allowede to ask for")
message(" *** support if needed.")
else()
- message("* Use GIT revision hash : Yes")
+ message("* Use GIT revision hash : Yes (default)")
endif()
if ( NOJEM )
@@ -113,15 +112,18 @@ if ( HELGRIND )
add_definitions(-DHELGRIND)
endif()
-if (WITH_DYNAMIC_LINKING)
+if (BUILD_SHARED_LIBS)
message("")
message(" *** WITH_DYNAMIC_LINKING - INFO!")
message(" *** Will link against shared libraries!")
message(" *** Please note that this is an experimental feature!")
+ if (WITH_DYNAMIC_LINKING_FORCED)
+ message("")
+ message(" *** Dynamic linking was enforced through a dynamic script module!")
+ endif()
add_definitions(-DTRINITY_API_USE_DYNAMIC_LINKING)
- set(BUILD_SHARED_LIBS ON)
-else()
- set(BUILD_SHARED_LIBS OFF)
+
+ WarnAboutSpacesInBuildPath()
endif()
message("")
diff --git a/dep/CMakeLists.txt b/dep/CMakeLists.txt
index 0932c7d4058..48be56bc9ef 100644
--- a/dep/CMakeLists.txt
+++ b/dep/CMakeLists.txt
@@ -8,7 +8,9 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-if( MSVC )
+if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+ string(REGEX REPLACE "/W[0-4] " "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+ string(REGEX REPLACE "/W[0-4] " "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
add_definitions(/W0)
else()
add_definitions(-w)
@@ -18,6 +20,7 @@ add_subdirectory(threads)
if(SERVERS OR TOOLS)
add_subdirectory(boost)
+ add_subdirectory(process)
add_subdirectory(zlib)
add_subdirectory(g3dlite)
add_subdirectory(recastnavigation)
@@ -33,7 +36,6 @@ if(SERVERS)
add_subdirectory(mysql)
add_subdirectory(readline)
add_subdirectory(gsoap)
- add_subdirectory(process)
add_subdirectory(efsw)
endif()
diff --git a/dep/boost/CMakeLists.txt b/dep/boost/CMakeLists.txt
index 118635c85bd..6cda5fbec4e 100644
--- a/dep/boost/CMakeLists.txt
+++ b/dep/boost/CMakeLists.txt
@@ -35,19 +35,14 @@ 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 <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
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)
- set(OPTIONAL_BOOST_NO_SCOPED_ENUMS -DBOOST_NO_CXX11_SCOPED_ENUMS)
-endif()
+unset(CMAKE_REQUIRED_INCLUDES)
+unset(CMAKE_REQUIRED_LIBRARIES)
+unset(CMAKE_REQUIRED_FLAGS)
add_library(boost INTERFACE)
@@ -59,9 +54,17 @@ target_include_directories(boost
INTERFACE
${Boost_INCLUDE_DIRS})
-target_compile_definitions(boost
- INTERFACE
- -DBOOST_DATE_TIME_NO_LIB
- -DBOOST_REGEX_NO_LIB
- -DBOOST_CHRONO_NO_LIB
- ${OPTIONAL_BOOST_NO_SCOPED_ENUMS})
+if (boost_filesystem_copy_links_without_NO_SCOPED_ENUM)
+ target_compile_definitions(boost
+ INTERFACE
+ -DBOOST_DATE_TIME_NO_LIB
+ -DBOOST_REGEX_NO_LIB
+ -DBOOST_CHRONO_NO_LIB)
+else()
+ target_compile_definitions(boost
+ INTERFACE
+ -DBOOST_DATE_TIME_NO_LIB
+ -DBOOST_REGEX_NO_LIB
+ -DBOOST_CHRONO_NO_LIB
+ -DBOOST_NO_CXX11_SCOPED_ENUMS)
+endif()
diff --git a/dep/efsw/CMakeLists.txt b/dep/efsw/CMakeLists.txt
index 81a1d20b204..eecc5531944 100644
--- a/dep/efsw/CMakeLists.txt
+++ b/dep/efsw/CMakeLists.txt
@@ -1,4 +1,4 @@
-if (WITH_DYNAMIC_LINKING)
+if (BUILD_SHARED_LIBS)
set(SRCS
src/efsw/DirectorySnapshot.cpp
src/efsw/DirectorySnapshotDiff.cpp
@@ -81,5 +81,5 @@ if (WITH_DYNAMIC_LINKING)
FOLDER
"dep")
else()
- add_library(efsw INTERFACE)
+ add_library(efsw INTERFACE IMPORTED GLOBAL)
endif()
diff --git a/issue_template.md b/issue_template.md
index fe090da2338..8653726f830 100644
--- a/issue_template.md
+++ b/issue_template.md
@@ -10,13 +10,15 @@
2.
3.
-**Branch(es)**: 335/6x
+**Branch(es)**: 335/6x
-**TC hash/commit**:
+**TC hash/commit**:
-**TDB version**:
+**TDB version**:
-**Operating system**:
+**Operating system**:
+
+**Linking model**: static/dynamic
[//]: # (This template is for problem reports, for other type of reports edit it accordingly)
diff --git a/revision_data.h.in.cmake b/revision_data.h.in.cmake
index 04c6e2008a1..14faa04a0bc 100644
--- a/revision_data.h.in.cmake
+++ b/revision_data.h.in.cmake
@@ -7,7 +7,7 @@
#define _SOURCE_DIRECTORY R"(@CMAKE_SOURCE_DIR@)"
#define _BUILD_DIRECTORY R"(@BUILDDIR@)"
#define _MYSQL_EXECUTABLE R"(@MYSQL_EXECUTABLE@)"
- #define _FULL_DATABASE "TDB_full_world_335.60_2015_11_07.sql"
+ #define _FULL_DATABASE "TDB_full_world_335.61_2016_04_11.sql"
#define VER_COMPANYNAME_STR "TrinityCore Developers"
#define VER_LEGALCOPYRIGHT_STR "(c)2008-2016 TrinityCore"
#define VER_FILEVERSION 0,0,0
diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql
index 0ac0ffaf9d1..6dc81ab211e 100644
--- a/sql/base/auth_database.sql
+++ b/sql/base/auth_database.sql
@@ -1,6 +1,6 @@
-- MySQL dump 10.13 Distrib 5.6.26, for Win64 (x86_64)
--
--- Host: localhost Database: auth335
+-- Host: localhost Database: auth
-- ------------------------------------------------------
-- Server version 5.6.26-log
@@ -486,7 +486,7 @@ CREATE 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),('2015_08_21_00_auth.sql','C31A9E1D28E11B60BE8F8198637DD51F6D75123F','ARCHIVED','2015-10-05 23:16:19',0),('2015_11_07_00_auth.sql','BAF9F6B8F97A30D04BDBBA8127A62A1720F9B904','RELEASED','2015-11-07 15:40:47',0),('2016_01_13_00_auth.sql','24615CC69B3CD7BB4699874647C35BA86E8A93FD','RELEASED','2016-01-13 00:00:00',0);
+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),('2015_08_21_00_auth.sql','C31A9E1D28E11B60BE8F8198637DD51F6D75123F','ARCHIVED','2015-10-05 23:16:19',0),('2015_11_07_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2016-04-11 00:42:36',92),('2016_01_13_00_auth.sql','24615CC69B3CD7BB4699874647C35BA86E8A93FD','ARCHIVED','2016-01-13 00:00:00',0),('2016_04_11_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','2016-04-11 03:18:17','2016-04-11 03:18:17',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;
@@ -549,4 +549,4 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
--- Dump completed on 2015-11-07 14:42:34
+-- Dump completed on 2016-04-11 2:32:16
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql
index 94841144017..1f071db3781 100644
--- a/sql/base/characters_database.sql
+++ b/sql/base/characters_database.sql
@@ -1,6 +1,6 @@
-- MySQL dump 10.13 Distrib 5.6.26, for Win64 (x86_64)
--
--- Host: localhost Database: characters335
+-- Host: localhost Database: characters
-- ------------------------------------------------------
-- Server version 5.6.26-log
@@ -783,7 +783,7 @@ CREATE TABLE `character_instance` (
`guid` int(10) unsigned NOT NULL DEFAULT '0',
`instance` int(10) unsigned NOT NULL DEFAULT '0',
`permanent` tinyint(3) unsigned NOT NULL DEFAULT '0',
- `extendState` TINYINT(2) UNSIGNED NOT NULL DEFAULT '1',
+ `extendState` tinyint(2) unsigned NOT NULL DEFAULT '1',
PRIMARY KEY (`guid`,`instance`),
KEY `instance` (`instance`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -2545,7 +2545,7 @@ CREATE 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),('2015_06_26_00_characters_335.sql','C2CC6E50AFA1ACCBEBF77CC519AAEB09F3BBAEBC','ARCHIVED','2015-07-13 23:49:22',0),('2015_09_28_00_characters_335.sql','F8682A431D50E54BDC4AC0E7DBED21AE8AAB6AD4','ARCHIVED','2015-09-28 21:00:00',0),('2015_08_26_00_characters_335.sql','C7D6A3A00FECA3EBFF1E71744CA40D3076582374','ARCHIVED','2015-08-26 21:00:00',0),('2015_10_06_00_characters.sql','16842FDD7E8547F2260D3312F53EFF8761EFAB35','ARCHIVED','2015-10-06 16:06:38',0),('2015_10_07_00_characters.sql','E15AB463CEBE321001D7BFDEA4B662FF618728FD','ARCHIVED','2015-10-07 23:32:00',0),('2015_10_12_00_characters.sql','D6F9927BDED72AD0A81D6EC2C6500CBC34A39FA2','ARCHIVED','2015-10-12 15:35:47',0),('2015_10_28_00_characters.sql','622A9CA8FCE690429EBE23BA071A37C7A007BF8B','ARCHIVED','2015-10-19 14:32:22',0),('2015_10_29_00_characters_335.sql','4555A7F35C107E54C13D74D20F141039ED42943E','ARCHIVED','2015-10-29 17:05:43',0),('2015_11_03_00_characters.sql','CC045717B8FDD9733351E52A5302560CD08AAD57','ARCHIVED','2015-10-12 15:23:33',0),('2015_11_07_00_characters.sql','BAF9F6B8F97A30D04BDBBA8127A62A1720F9B904','RELEASED','2015-11-07 15:40:47',0),('2016_02_10_00_characters.sql','F1B4DA202819CABC7319A4470A2D224A34609E97','RELEASED','2016-02-10 00:00:00',0),('2016_03_13_2016_01_05_00_characters.sql','0EAD24977F40DE2476B4567DA2B477867CC0DA1A','RELEASED','2016-03-13 20:03:56',0);
+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),('2015_06_26_00_characters_335.sql','C2CC6E50AFA1ACCBEBF77CC519AAEB09F3BBAEBC','ARCHIVED','2015-07-13 23:49:22',0),('2015_09_28_00_characters_335.sql','F8682A431D50E54BDC4AC0E7DBED21AE8AAB6AD4','ARCHIVED','2015-09-28 21:00:00',0),('2015_08_26_00_characters_335.sql','C7D6A3A00FECA3EBFF1E71744CA40D3076582374','ARCHIVED','2015-08-26 21:00:00',0),('2015_10_06_00_characters.sql','16842FDD7E8547F2260D3312F53EFF8761EFAB35','ARCHIVED','2015-10-06 16:06:38',0),('2015_10_07_00_characters.sql','E15AB463CEBE321001D7BFDEA4B662FF618728FD','ARCHIVED','2015-10-07 23:32:00',0),('2015_10_12_00_characters.sql','D6F9927BDED72AD0A81D6EC2C6500CBC34A39FA2','ARCHIVED','2015-10-12 15:35:47',0),('2015_10_28_00_characters.sql','622A9CA8FCE690429EBE23BA071A37C7A007BF8B','ARCHIVED','2015-10-19 14:32:22',0),('2015_10_29_00_characters_335.sql','4555A7F35C107E54C13D74D20F141039ED42943E','ARCHIVED','2015-10-29 17:05:43',0),('2015_11_03_00_characters.sql','CC045717B8FDD9733351E52A5302560CD08AAD57','ARCHIVED','2015-10-12 15:23:33',0),('2015_11_07_00_characters.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2016-04-11 00:42:36',94),('2016_02_10_00_characters.sql','F1B4DA202819CABC7319A4470A2D224A34609E97','ARCHIVED','2016-02-10 00:00:00',0),('2016_03_13_2016_01_05_00_characters.sql','0EAD24977F40DE2476B4567DA2B477867CC0DA1A','ARCHIVED','2016-03-13 20:03:56',0),('2016_04_11_00_characters.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','RELEASED','2016-04-11 03:18:17',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;
@@ -2630,4 +2630,4 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
--- Dump completed on 2015-11-07 14:42:34
+-- Dump completed on 2016-04-11 2:32:17
diff --git a/sql/base/dev/world_database.sql b/sql/base/dev/world_database.sql
index 02318987448..85e7c2391da 100644
--- a/sql/base/dev/world_database.sql
+++ b/sql/base/dev/world_database.sql
@@ -1,6 +1,6 @@
-- MySQL dump 10.13 Distrib 5.6.26, for Win64 (x86_64)
--
--- Host: localhost Database: world335
+-- Host: localhost Database: world
-- ------------------------------------------------------
-- Server version 5.6.26-log
@@ -1022,7 +1022,7 @@ CREATE TABLE `game_tele` (
`map` smallint(5) unsigned NOT NULL DEFAULT '0',
`name` varchar(100) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
-) ENGINE=MyISAM AUTO_INCREMENT=1425 DEFAULT CHARSET=utf8 COMMENT='Tele Command';
+) ENGINE=MyISAM AUTO_INCREMENT=1429 DEFAULT CHARSET=utf8 COMMENT='Tele Command';
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -3785,4 +3785,4 @@ CREATE TABLE `waypoints` (
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
--- Dump completed on 2015-11-07 14:42:45
+-- Dump completed on 2016-04-11 2:32:19
diff --git a/sql/updates/auth/2015_11_07_00_auth.sql b/sql/old/3.3.5a/auth/60_2016_04_11/2015_11_07_00_auth.sql
index be8a4d21b66..be8a4d21b66 100644
--- a/sql/updates/auth/2015_11_07_00_auth.sql
+++ b/sql/old/3.3.5a/auth/60_2016_04_11/2015_11_07_00_auth.sql
diff --git a/sql/updates/auth/2016_01_13_00_auth.sql b/sql/old/3.3.5a/auth/60_2016_04_11/2016_01_13_00_auth.sql
index c70d4c09468..c70d4c09468 100644
--- a/sql/updates/auth/2016_01_13_00_auth.sql
+++ b/sql/old/3.3.5a/auth/60_2016_04_11/2016_01_13_00_auth.sql
diff --git a/sql/updates/characters/2015_11_07_00_characters.sql b/sql/old/3.3.5a/characters/60_2016_04_11/2015_11_07_00_characters.sql
index be8a4d21b66..be8a4d21b66 100644
--- a/sql/updates/characters/2015_11_07_00_characters.sql
+++ b/sql/old/3.3.5a/characters/60_2016_04_11/2015_11_07_00_characters.sql
diff --git a/sql/updates/characters/2016_02_10_00_characters.sql b/sql/old/3.3.5a/characters/60_2016_04_11/2016_02_10_00_characters.sql
index d49ed155bc8..d49ed155bc8 100644
--- a/sql/updates/characters/2016_02_10_00_characters.sql
+++ b/sql/old/3.3.5a/characters/60_2016_04_11/2016_02_10_00_characters.sql
diff --git a/sql/updates/characters/2016_03_13_2016_01_05_00_characters.sql b/sql/old/3.3.5a/characters/60_2016_04_11/2016_03_13_2016_01_05_00_characters.sql
index 11850067be9..11850067be9 100644
--- a/sql/updates/characters/2016_03_13_2016_01_05_00_characters.sql
+++ b/sql/old/3.3.5a/characters/60_2016_04_11/2016_03_13_2016_01_05_00_characters.sql
diff --git a/sql/updates/world/2015_11_07_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_07_02_world.sql
index 3e23e0e629b..3e23e0e629b 100644
--- a/sql/updates/world/2015_11_07_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_07_02_world.sql
diff --git a/sql/updates/world/2015_11_08_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_08_00_world.sql
index fea6f43bc64..fea6f43bc64 100644
--- a/sql/updates/world/2015_11_08_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_08_00_world.sql
diff --git a/sql/updates/world/2015_11_08_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_08_01_world.sql
index f5642f73af4..f5642f73af4 100644
--- a/sql/updates/world/2015_11_08_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_08_01_world.sql
diff --git a/sql/updates/world/2015_11_09_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_09_00_world.sql
index 6fd5dec39b7..6fd5dec39b7 100644
--- a/sql/updates/world/2015_11_09_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_09_00_world.sql
diff --git a/sql/updates/world/2015_11_09_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_09_01_world.sql
index e9360cf8963..e9360cf8963 100644
--- a/sql/updates/world/2015_11_09_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_09_01_world.sql
diff --git a/sql/updates/world/2015_11_09_02_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_09_02_world_335.sql
index 84c0fd423ad..84c0fd423ad 100644
--- a/sql/updates/world/2015_11_09_02_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_09_02_world_335.sql
diff --git a/sql/updates/world/2015_11_10_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_10_00_world.sql
index 6e969f288f1..6e969f288f1 100644
--- a/sql/updates/world/2015_11_10_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_10_00_world.sql
diff --git a/sql/updates/world/2015_11_10_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_10_01_world.sql
index fe9c0b1b8e2..fe9c0b1b8e2 100644
--- a/sql/updates/world/2015_11_10_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_10_01_world.sql
diff --git a/sql/updates/world/2015_11_10_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_10_02_world.sql
index 8ff255defa4..8ff255defa4 100644
--- a/sql/updates/world/2015_11_10_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_10_02_world.sql
diff --git a/sql/updates/world/2015_11_11_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_11_00_world.sql
index 07393641f3f..07393641f3f 100644
--- a/sql/updates/world/2015_11_11_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_11_00_world.sql
diff --git a/sql/updates/world/2015_11_11_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_11_01_world.sql
index 3c1ce85ec17..3c1ce85ec17 100644
--- a/sql/updates/world/2015_11_11_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_11_01_world.sql
diff --git a/sql/updates/world/2015_11_12_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_12_00_world.sql
index 79c2461e5ff..79c2461e5ff 100644
--- a/sql/updates/world/2015_11_12_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_12_00_world.sql
diff --git a/sql/updates/world/2015_11_12_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_12_01_world.sql
index c08ebda2471..c08ebda2471 100644
--- a/sql/updates/world/2015_11_12_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_12_01_world.sql
diff --git a/sql/updates/world/2015_11_20_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_20_00_world.sql
index 7c5fe7ea426..7c5fe7ea426 100644
--- a/sql/updates/world/2015_11_20_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_20_00_world.sql
diff --git a/sql/updates/world/2015_11_22_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_22_00_world.sql
index 2b70a2c97b6..2b70a2c97b6 100644
--- a/sql/updates/world/2015_11_22_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_22_00_world.sql
diff --git a/sql/updates/world/2015_11_22_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_22_01_world.sql
index ba63c72ba16..ba63c72ba16 100644
--- a/sql/updates/world/2015_11_22_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_22_01_world.sql
diff --git a/sql/updates/world/2015_11_22_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_22_02_world.sql
index 7fcbc7ec9aa..7fcbc7ec9aa 100644
--- a/sql/updates/world/2015_11_22_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_22_02_world.sql
diff --git a/sql/updates/world/2015_11_22_03_world_355.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_22_03_world_355.sql
index 9bf71a146d0..9bf71a146d0 100644
--- a/sql/updates/world/2015_11_22_03_world_355.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_22_03_world_355.sql
diff --git a/sql/updates/world/2015_11_23_00_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_00_world_335.sql
index fffc4531e5e..fffc4531e5e 100644
--- a/sql/updates/world/2015_11_23_00_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_00_world_335.sql
diff --git a/sql/updates/world/2015_11_23_01_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_01_world_335.sql
index 8432c2d14fd..8432c2d14fd 100644
--- a/sql/updates/world/2015_11_23_01_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_01_world_335.sql
diff --git a/sql/updates/world/2015_11_23_02_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_02_world_335.sql
index ba569d1420f..ba569d1420f 100644
--- a/sql/updates/world/2015_11_23_02_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_02_world_335.sql
diff --git a/sql/updates/world/2015_11_23_03_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_03_world_335.sql
index 9ef011f551e..9ef011f551e 100644
--- a/sql/updates/world/2015_11_23_03_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_03_world_335.sql
diff --git a/sql/updates/world/2015_11_23_04_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_04_world_335.sql
index 845eefeb7ca..845eefeb7ca 100644
--- a/sql/updates/world/2015_11_23_04_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_04_world_335.sql
diff --git a/sql/updates/world/2015_11_23_05_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_05_world.sql
index 579af5a5ca1..579af5a5ca1 100644
--- a/sql/updates/world/2015_11_23_05_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_23_05_world.sql
diff --git a/sql/updates/world/2015_11_24_00_world_355.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_24_00_world_355.sql
index 0983d03e649..0983d03e649 100644
--- a/sql/updates/world/2015_11_24_00_world_355.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_24_00_world_355.sql
diff --git a/sql/updates/world/2015_11_27_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_27_00_world.sql
index 632dec537dd..632dec537dd 100644
--- a/sql/updates/world/2015_11_27_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_27_00_world.sql
diff --git a/sql/updates/world/2015_11_28_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_28_00_world.sql
index 0a1dd574fb4..0a1dd574fb4 100644
--- a/sql/updates/world/2015_11_28_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_28_00_world.sql
diff --git a/sql/updates/world/2015_11_28_01_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_28_01_world_335.sql
index 4bec178ecee..4bec178ecee 100644
--- a/sql/updates/world/2015_11_28_01_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_28_01_world_335.sql
diff --git a/sql/updates/world/2015_11_29_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_29_00_world.sql
index fd64b65bd02..fd64b65bd02 100644
--- a/sql/updates/world/2015_11_29_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_29_00_world.sql
diff --git a/sql/updates/world/2015_11_29_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_29_01_world.sql
index cd46800c5dd..cd46800c5dd 100644
--- a/sql/updates/world/2015_11_29_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_11_29_01_world.sql
diff --git a/sql/updates/world/2015_12_01_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_01_00_world.sql
index 1572245a517..1572245a517 100644
--- a/sql/updates/world/2015_12_01_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_01_00_world.sql
diff --git a/sql/updates/world/2015_12_04_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_04_00_world.sql
index ee721273bef..ee721273bef 100644
--- a/sql/updates/world/2015_12_04_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_04_00_world.sql
diff --git a/sql/updates/world/2015_12_05_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_05_00_world.sql
index c2c90164a4f..c2c90164a4f 100644
--- a/sql/updates/world/2015_12_05_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_05_00_world.sql
diff --git a/sql/updates/world/2015_12_06_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_06_00_world.sql
index b60d4d3e88c..b60d4d3e88c 100644
--- a/sql/updates/world/2015_12_06_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_06_00_world.sql
diff --git a/sql/updates/world/2015_12_08_00_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_08_00_world_335.sql
index e742130b1a4..e742130b1a4 100644
--- a/sql/updates/world/2015_12_08_00_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_08_00_world_335.sql
diff --git a/sql/updates/world/2015_12_08_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_08_01_world.sql
index 9e24acd91db..9e24acd91db 100644
--- a/sql/updates/world/2015_12_08_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_08_01_world.sql
diff --git a/sql/updates/world/2015_12_08_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_08_02_world.sql
index 375d0941adb..375d0941adb 100644
--- a/sql/updates/world/2015_12_08_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_08_02_world.sql
diff --git a/sql/updates/world/2015_12_09_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_09_00_world.sql
index 6ac4da31404..6ac4da31404 100644
--- a/sql/updates/world/2015_12_09_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_09_00_world.sql
diff --git a/sql/updates/world/2015_12_09_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_09_01_world.sql
index d27bc7ff49a..d27bc7ff49a 100644
--- a/sql/updates/world/2015_12_09_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_09_01_world.sql
diff --git a/sql/updates/world/2015_12_11_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_11_00_world.sql
index dc5fd8c40b6..dc5fd8c40b6 100644
--- a/sql/updates/world/2015_12_11_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_11_00_world.sql
diff --git a/sql/updates/world/2015_12_14_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_14_00_world.sql
index 85faf4448e2..85faf4448e2 100644
--- a/sql/updates/world/2015_12_14_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_14_00_world.sql
diff --git a/sql/updates/world/2015_12_15_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_15_00_world.sql
index f27bb448bbd..f27bb448bbd 100644
--- a/sql/updates/world/2015_12_15_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_15_00_world.sql
diff --git a/sql/updates/world/2015_12_15_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_15_01_world.sql
index 86fbec83c38..86fbec83c38 100644
--- a/sql/updates/world/2015_12_15_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_15_01_world.sql
diff --git a/sql/updates/world/2015_12_15_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_15_02_world.sql
index eda5c26550f..eda5c26550f 100644
--- a/sql/updates/world/2015_12_15_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_15_02_world.sql
diff --git a/sql/updates/world/2015_12_15_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_15_03_world.sql
index 99cc9e14646..99cc9e14646 100644
--- a/sql/updates/world/2015_12_15_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_15_03_world.sql
diff --git a/sql/updates/world/2015_12_16_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_16_00_world.sql
index 62d640117f7..62d640117f7 100644
--- a/sql/updates/world/2015_12_16_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_16_00_world.sql
diff --git a/sql/updates/world/2015_12_16_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_16_01_world.sql
index 73c9675e5be..73c9675e5be 100644
--- a/sql/updates/world/2015_12_16_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_16_01_world.sql
diff --git a/sql/updates/world/2015_12_16_02_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_16_02_world_335.sql
index 20c1ac94a39..20c1ac94a39 100644
--- a/sql/updates/world/2015_12_16_02_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_16_02_world_335.sql
diff --git a/sql/updates/world/2015_12_17_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_17_00_world.sql
index 8419473b203..8419473b203 100644
--- a/sql/updates/world/2015_12_17_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_17_00_world.sql
diff --git a/sql/updates/world/2015_12_18_00_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_18_00_world_335.sql
index 3fb3e5a6e1e..3fb3e5a6e1e 100644
--- a/sql/updates/world/2015_12_18_00_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_18_00_world_335.sql
diff --git a/sql/updates/world/2015_12_18_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_18_01_world.sql
index 2ccc93def23..2ccc93def23 100644
--- a/sql/updates/world/2015_12_18_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_18_01_world.sql
diff --git a/sql/updates/world/2015_12_18_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_18_02_world.sql
index f590d18a8ab..f590d18a8ab 100644
--- a/sql/updates/world/2015_12_18_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_18_02_world.sql
diff --git a/sql/updates/world/2015_12_18_03_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_18_03_world_335.sql
index de778343a0e..de778343a0e 100644
--- a/sql/updates/world/2015_12_18_03_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_18_03_world_335.sql
diff --git a/sql/updates/world/2015_12_18_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_18_04_world.sql
index c8c3352319c..c8c3352319c 100644
--- a/sql/updates/world/2015_12_18_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_18_04_world.sql
diff --git a/sql/updates/world/2015_12_20_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_20_00_world.sql
index 7c658877f13..7c658877f13 100644
--- a/sql/updates/world/2015_12_20_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_20_00_world.sql
diff --git a/sql/updates/world/2015_12_24_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_24_00_world.sql
index 52d83bb63c3..52d83bb63c3 100644
--- a/sql/updates/world/2015_12_24_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_24_00_world.sql
diff --git a/sql/updates/world/2015_12_26_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_26_00_world.sql
index 02c0acbedae..02c0acbedae 100644
--- a/sql/updates/world/2015_12_26_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_26_00_world.sql
diff --git a/sql/updates/world/2015_12_26_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_26_01_world.sql
index 92a9d21af25..92a9d21af25 100644
--- a/sql/updates/world/2015_12_26_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_26_01_world.sql
diff --git a/sql/updates/world/2015_12_26_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_26_02_world.sql
index 021dec0be80..021dec0be80 100644
--- a/sql/updates/world/2015_12_26_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_26_02_world.sql
diff --git a/sql/updates/world/2015_12_29_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_00_world.sql
index da6de123190..da6de123190 100644
--- a/sql/updates/world/2015_12_29_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_00_world.sql
diff --git a/sql/updates/world/2015_12_29_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_01_world.sql
index 24b201b4d06..24b201b4d06 100644
--- a/sql/updates/world/2015_12_29_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_01_world.sql
diff --git a/sql/updates/world/2015_12_29_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_02_world.sql
index 3bfd0ba2a25..3bfd0ba2a25 100644
--- a/sql/updates/world/2015_12_29_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_02_world.sql
diff --git a/sql/updates/world/2015_12_29_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_03_world.sql
index f928061c269..f928061c269 100644
--- a/sql/updates/world/2015_12_29_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_03_world.sql
diff --git a/sql/updates/world/2015_12_29_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_04_world.sql
index 22a1ee3edcf..22a1ee3edcf 100644
--- a/sql/updates/world/2015_12_29_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_04_world.sql
diff --git a/sql/updates/world/2015_12_29_05_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_05_world.sql
index 056ea4fe230..056ea4fe230 100644
--- a/sql/updates/world/2015_12_29_05_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_05_world.sql
diff --git a/sql/updates/world/2015_12_29_06_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_06_world.sql
index 167c4c23005..167c4c23005 100644
--- a/sql/updates/world/2015_12_29_06_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_06_world.sql
diff --git a/sql/updates/world/2015_12_29_07_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_07_world.sql
index ec71d28c787..ec71d28c787 100644
--- a/sql/updates/world/2015_12_29_07_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_07_world.sql
diff --git a/sql/updates/world/2015_12_29_08_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_08_world.sql
index ce874d7a8d2..ce874d7a8d2 100644
--- a/sql/updates/world/2015_12_29_08_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_08_world.sql
diff --git a/sql/updates/world/2015_12_29_09_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_09_world.sql
index d57785e8d88..d57785e8d88 100644
--- a/sql/updates/world/2015_12_29_09_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_09_world.sql
diff --git a/sql/updates/world/2015_12_29_10_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_10_world.sql
index 919309dd558..919309dd558 100644
--- a/sql/updates/world/2015_12_29_10_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_10_world.sql
diff --git a/sql/updates/world/2015_12_29_11_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_11_world.sql
index 930baf15f78..930baf15f78 100644
--- a/sql/updates/world/2015_12_29_11_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_11_world.sql
diff --git a/sql/updates/world/2015_12_29_12_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_12_world.sql
index c065e1d6a18..c065e1d6a18 100644
--- a/sql/updates/world/2015_12_29_12_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_12_world.sql
diff --git a/sql/updates/world/2015_12_29_13_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_13_world.sql
index fc182ae49fb..fc182ae49fb 100644
--- a/sql/updates/world/2015_12_29_13_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_29_13_world.sql
diff --git a/sql/updates/world/2015_12_31_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_31_00_world.sql
index b7c310323ed..b7c310323ed 100644
--- a/sql/updates/world/2015_12_31_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_31_00_world.sql
diff --git a/sql/updates/world/2015_12_31_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_31_01_world.sql
index 3bee62963ef..3bee62963ef 100644
--- a/sql/updates/world/2015_12_31_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2015_12_31_01_world.sql
diff --git a/sql/updates/world/2016_01_01_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_01_00_world.sql
index 38991837113..38991837113 100644
--- a/sql/updates/world/2016_01_01_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_01_00_world.sql
diff --git a/sql/updates/world/2016_01_01_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_01_01_world.sql
index 025f2c07f9c..025f2c07f9c 100644
--- a/sql/updates/world/2016_01_01_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_01_01_world.sql
diff --git a/sql/updates/world/2016_01_02_00_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_02_00_world_335.sql
index b46a41bc6e9..b46a41bc6e9 100644
--- a/sql/updates/world/2016_01_02_00_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_02_00_world_335.sql
diff --git a/sql/updates/world/2016_01_02_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_02_01_world.sql
index b862cc0e644..b862cc0e644 100644
--- a/sql/updates/world/2016_01_02_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_02_01_world.sql
diff --git a/sql/updates/world/2016_01_03_00_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_00_world_335.sql
index 658b180a41a..658b180a41a 100644
--- a/sql/updates/world/2016_01_03_00_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_00_world_335.sql
diff --git a/sql/updates/world/2016_01_03_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_01_world.sql
index 3ddb56a9c72..3ddb56a9c72 100644
--- a/sql/updates/world/2016_01_03_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_01_world.sql
diff --git a/sql/updates/world/2016_01_03_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_02_world.sql
index 79eba012e41..79eba012e41 100644
--- a/sql/updates/world/2016_01_03_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_02_world.sql
diff --git a/sql/updates/world/2016_01_03_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_03_world.sql
index 1b1766ee557..1b1766ee557 100644
--- a/sql/updates/world/2016_01_03_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_03_world.sql
diff --git a/sql/updates/world/2016_01_03_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_04_world.sql
index ffe8eb07fd5..ffe8eb07fd5 100644
--- a/sql/updates/world/2016_01_03_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_04_world.sql
diff --git a/sql/updates/world/2016_01_03_05_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_05_world.sql
index 4c2fe0817f0..4c2fe0817f0 100644
--- a/sql/updates/world/2016_01_03_05_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_03_05_world.sql
diff --git a/sql/updates/world/2016_01_04_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_04_00_world.sql
index 57236a6f66e..57236a6f66e 100644
--- a/sql/updates/world/2016_01_04_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_04_00_world.sql
diff --git a/sql/updates/world/2016_01_05_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_05_00_world.sql
index 3f7f01449fc..3f7f01449fc 100644
--- a/sql/updates/world/2016_01_05_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_05_00_world.sql
diff --git a/sql/updates/world/2016_01_05_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_05_01_world.sql
index dc1064a75b9..dc1064a75b9 100644
--- a/sql/updates/world/2016_01_05_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_05_01_world.sql
diff --git a/sql/updates/world/2016_01_05_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_05_02_world.sql
index 64909129e60..64909129e60 100644
--- a/sql/updates/world/2016_01_05_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_05_02_world.sql
diff --git a/sql/updates/world/2016_01_07_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_07_00_world.sql
index d36dda80e50..d36dda80e50 100644
--- a/sql/updates/world/2016_01_07_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_07_00_world.sql
diff --git a/sql/updates/world/2016_01_07_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_07_01_world.sql
index 4a15aa405ec..4a15aa405ec 100644
--- a/sql/updates/world/2016_01_07_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_07_01_world.sql
diff --git a/sql/updates/world/2016_01_07_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_07_02_world.sql
index 7724b42ac9d..7724b42ac9d 100644
--- a/sql/updates/world/2016_01_07_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_07_02_world.sql
diff --git a/sql/updates/world/2016_01_08_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_08_00_world.sql
index 55ed3ddf336..55ed3ddf336 100644
--- a/sql/updates/world/2016_01_08_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_08_00_world.sql
diff --git a/sql/updates/world/2016_01_08_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_08_01_world.sql
index ebf4560d326..ebf4560d326 100644
--- a/sql/updates/world/2016_01_08_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_08_01_world.sql
diff --git a/sql/updates/world/2016_01_08_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_08_02_world.sql
index 28e55dfba3b..28e55dfba3b 100644
--- a/sql/updates/world/2016_01_08_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_08_02_world.sql
diff --git a/sql/updates/world/2016_01_08_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_08_03_world.sql
index 2899c6e06eb..2899c6e06eb 100644
--- a/sql/updates/world/2016_01_08_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_08_03_world.sql
diff --git a/sql/updates/world/2016_01_09_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_09_00_world.sql
index 534e17ccb00..534e17ccb00 100644
--- a/sql/updates/world/2016_01_09_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_09_00_world.sql
diff --git a/sql/updates/world/2016_01_10_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_00_world.sql
index 83ed21c8489..83ed21c8489 100644
--- a/sql/updates/world/2016_01_10_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_00_world.sql
diff --git a/sql/updates/world/2016_01_10_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_01_world.sql
index c79c157a1a1..c79c157a1a1 100644
--- a/sql/updates/world/2016_01_10_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_01_world.sql
diff --git a/sql/updates/world/2016_01_10_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_02_world.sql
index eca8ef07849..eca8ef07849 100644
--- a/sql/updates/world/2016_01_10_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_02_world.sql
diff --git a/sql/updates/world/2016_01_10_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_03_world.sql
index 5ac352ffe10..5ac352ffe10 100644
--- a/sql/updates/world/2016_01_10_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_03_world.sql
diff --git a/sql/updates/world/2016_01_10_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_04_world.sql
index da6eed191ad..da6eed191ad 100644
--- a/sql/updates/world/2016_01_10_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_04_world.sql
diff --git a/sql/updates/world/2016_01_10_05_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_05_world_335.sql
index 7fb021cc9dd..7fb021cc9dd 100644
--- a/sql/updates/world/2016_01_10_05_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_10_05_world_335.sql
diff --git a/sql/updates/world/2016_01_12_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_12_00_world.sql
index 8ed4099450b..8ed4099450b 100644
--- a/sql/updates/world/2016_01_12_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_12_00_world.sql
diff --git a/sql/updates/world/2016_01_12_01_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_12_01_world_335.sql
index c3206e70ac4..c3206e70ac4 100644
--- a/sql/updates/world/2016_01_12_01_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_12_01_world_335.sql
diff --git a/sql/updates/world/2016_01_12_02_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_12_02_world_335.sql
index 354d0bc129d..354d0bc129d 100644
--- a/sql/updates/world/2016_01_12_02_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_12_02_world_335.sql
diff --git a/sql/updates/world/2016_01_12_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_12_03_world.sql
index 6ff3a769918..6ff3a769918 100644
--- a/sql/updates/world/2016_01_12_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_12_03_world.sql
diff --git a/sql/updates/world/2016_01_12_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_12_04_world.sql
index 7cee9220060..7cee9220060 100644
--- a/sql/updates/world/2016_01_12_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_12_04_world.sql
diff --git a/sql/updates/world/2016_01_13_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_13_00_world.sql
index cba5d3a18a1..cba5d3a18a1 100644
--- a/sql/updates/world/2016_01_13_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_13_00_world.sql
diff --git a/sql/updates/world/2016_01_15_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_15_00_world.sql
index b5f3da2dd99..b5f3da2dd99 100644
--- a/sql/updates/world/2016_01_15_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_15_00_world.sql
diff --git a/sql/updates/world/2016_01_16_00_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_00_world_335.sql
index 14362432555..14362432555 100644
--- a/sql/updates/world/2016_01_16_00_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_00_world_335.sql
diff --git a/sql/updates/world/2016_01_16_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_01_world.sql
index 235378a7a84..235378a7a84 100644
--- a/sql/updates/world/2016_01_16_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_01_world.sql
diff --git a/sql/updates/world/2016_01_16_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_02_world.sql
index b36d7d69ff6..b36d7d69ff6 100644
--- a/sql/updates/world/2016_01_16_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_02_world.sql
diff --git a/sql/updates/world/2016_01_16_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_03_world.sql
index 5a06cfaecca..5a06cfaecca 100644
--- a/sql/updates/world/2016_01_16_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_03_world.sql
diff --git a/sql/updates/world/2016_01_16_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_04_world.sql
index a6bb7ae185c..a6bb7ae185c 100644
--- a/sql/updates/world/2016_01_16_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_04_world.sql
diff --git a/sql/updates/world/2016_01_16_05_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_05_world.sql
index 46511cb0de8..46511cb0de8 100644
--- a/sql/updates/world/2016_01_16_05_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_16_05_world.sql
diff --git a/sql/updates/world/2016_01_17_00_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_00_world_335.sql
index abb3579fb07..abb3579fb07 100644
--- a/sql/updates/world/2016_01_17_00_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_00_world_335.sql
diff --git a/sql/updates/world/2016_01_17_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_01_world.sql
index 8e5bcd22a07..8e5bcd22a07 100644
--- a/sql/updates/world/2016_01_17_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_01_world.sql
diff --git a/sql/updates/world/2016_01_17_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_02_world.sql
index f019b927228..f019b927228 100644
--- a/sql/updates/world/2016_01_17_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_02_world.sql
diff --git a/sql/updates/world/2016_01_17_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_03_world.sql
index cf43c650888..cf43c650888 100644
--- a/sql/updates/world/2016_01_17_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_03_world.sql
diff --git a/sql/updates/world/2016_01_17_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_04_world.sql
index 6d72807e0b1..6d72807e0b1 100644
--- a/sql/updates/world/2016_01_17_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_04_world.sql
diff --git a/sql/updates/world/2016_01_17_05_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_05_world.sql
index 2d253bae713..2d253bae713 100644
--- a/sql/updates/world/2016_01_17_05_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_05_world.sql
diff --git a/sql/updates/world/2016_01_17_06_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_06_world.sql
index 659f146845a..659f146845a 100644
--- a/sql/updates/world/2016_01_17_06_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_06_world.sql
diff --git a/sql/updates/world/2016_01_17_07_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_07_world.sql
index df588168d38..df588168d38 100644
--- a/sql/updates/world/2016_01_17_07_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_07_world.sql
diff --git a/sql/updates/world/2016_01_17_08_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_08_world.sql
index 48cd420a242..48cd420a242 100644
--- a/sql/updates/world/2016_01_17_08_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_08_world.sql
diff --git a/sql/updates/world/2016_01_17_09_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_09_world.sql
index 85e6f535866..85e6f535866 100644
--- a/sql/updates/world/2016_01_17_09_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_09_world.sql
diff --git a/sql/updates/world/2016_01_17_10_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_10_world.sql
index 0fdc04eb60f..0fdc04eb60f 100644
--- a/sql/updates/world/2016_01_17_10_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_10_world.sql
diff --git a/sql/updates/world/2016_01_17_11_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_11_world.sql
index 9ab963a2ff2..9ab963a2ff2 100644
--- a/sql/updates/world/2016_01_17_11_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_11_world.sql
diff --git a/sql/updates/world/2016_01_17_12_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_12_world.sql
index e4e8ab5e9e2..e4e8ab5e9e2 100644
--- a/sql/updates/world/2016_01_17_12_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_12_world.sql
diff --git a/sql/updates/world/2016_01_17_13_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_13_world.sql
index 163aa3fb659..163aa3fb659 100644
--- a/sql/updates/world/2016_01_17_13_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_13_world.sql
diff --git a/sql/updates/world/2016_01_17_14_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_14_world.sql
index c8b9405abff..c8b9405abff 100644
--- a/sql/updates/world/2016_01_17_14_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_14_world.sql
diff --git a/sql/updates/world/2016_01_17_15_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_15_world.sql
index da949d7100d..da949d7100d 100644
--- a/sql/updates/world/2016_01_17_15_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_17_15_world.sql
diff --git a/sql/updates/world/2016_01_18_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_00_world.sql
index 85f41cfc0c5..85f41cfc0c5 100644
--- a/sql/updates/world/2016_01_18_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_00_world.sql
diff --git a/sql/updates/world/2016_01_18_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_01_world.sql
index 9768ecda6c0..9768ecda6c0 100644
--- a/sql/updates/world/2016_01_18_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_01_world.sql
diff --git a/sql/updates/world/2016_01_18_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_02_world.sql
index ec9a8748cc8..ec9a8748cc8 100644
--- a/sql/updates/world/2016_01_18_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_02_world.sql
diff --git a/sql/updates/world/2016_01_18_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_03_world.sql
index 4b8eb4ae0c9..4b8eb4ae0c9 100644
--- a/sql/updates/world/2016_01_18_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_03_world.sql
diff --git a/sql/updates/world/2016_01_18_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_04_world.sql
index 28ab2d96731..28ab2d96731 100644
--- a/sql/updates/world/2016_01_18_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_04_world.sql
diff --git a/sql/updates/world/2016_01_18_05_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_05_world.sql
index 0d28cd17642..0d28cd17642 100644
--- a/sql/updates/world/2016_01_18_05_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_05_world.sql
diff --git a/sql/updates/world/2016_01_18_06_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_06_world.sql
index f8b90c15f54..f8b90c15f54 100644
--- a/sql/updates/world/2016_01_18_06_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_18_06_world.sql
diff --git a/sql/updates/world/2016_01_19_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_00_world.sql
index f210b95c13a..f210b95c13a 100644
--- a/sql/updates/world/2016_01_19_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_00_world.sql
diff --git a/sql/updates/world/2016_01_19_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_01_world.sql
index a10bc7e278f..a10bc7e278f 100644
--- a/sql/updates/world/2016_01_19_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_01_world.sql
diff --git a/sql/updates/world/2016_01_19_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_02_world.sql
index 7c71156b248..7c71156b248 100644
--- a/sql/updates/world/2016_01_19_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_02_world.sql
diff --git a/sql/updates/world/2016_01_19_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_03_world.sql
index 0d559ace044..0d559ace044 100644
--- a/sql/updates/world/2016_01_19_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_03_world.sql
diff --git a/sql/updates/world/2016_01_19_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_04_world.sql
index f4fe95f5539..f4fe95f5539 100644
--- a/sql/updates/world/2016_01_19_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_04_world.sql
diff --git a/sql/updates/world/2016_01_19_05_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_05_world.sql
index 5afd9e2b8a5..5afd9e2b8a5 100644
--- a/sql/updates/world/2016_01_19_05_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_05_world.sql
diff --git a/sql/updates/world/2016_01_19_06_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_06_world.sql
index cece0c623bf..cece0c623bf 100644
--- a/sql/updates/world/2016_01_19_06_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_06_world.sql
diff --git a/sql/updates/world/2016_01_19_07_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_07_world.sql
index e1a72398a5f..e1a72398a5f 100644
--- a/sql/updates/world/2016_01_19_07_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_07_world.sql
diff --git a/sql/updates/world/2016_01_19_08_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_08_world.sql
index d078c059201..d078c059201 100644
--- a/sql/updates/world/2016_01_19_08_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_19_08_world.sql
diff --git a/sql/updates/world/2016_01_20_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_20_00_world.sql
index 26ce069edd8..26ce069edd8 100644
--- a/sql/updates/world/2016_01_20_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_20_00_world.sql
diff --git a/sql/updates/world/2016_01_20_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_20_01_world.sql
index b1c6e0de756..b1c6e0de756 100644
--- a/sql/updates/world/2016_01_20_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_20_01_world.sql
diff --git a/sql/updates/world/2016_01_20_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_20_02_world.sql
index d026c3cb478..d026c3cb478 100644
--- a/sql/updates/world/2016_01_20_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_20_02_world.sql
diff --git a/sql/updates/world/2016_01_23_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_23_00_world.sql
index 02eaa7c370d..02eaa7c370d 100644
--- a/sql/updates/world/2016_01_23_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_23_00_world.sql
diff --git a/sql/updates/world/2016_01_24_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_24_00_world.sql
index a28b3fa25b8..a28b3fa25b8 100644
--- a/sql/updates/world/2016_01_24_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_24_00_world.sql
diff --git a/sql/updates/world/2016_01_26_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_26_00_world.sql
index 71fe8dc21e3..71fe8dc21e3 100644
--- a/sql/updates/world/2016_01_26_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_26_00_world.sql
diff --git a/sql/updates/world/2016_01_28_00_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_28_00_world_335.sql
index 64b32cb2d89..64b32cb2d89 100644
--- a/sql/updates/world/2016_01_28_00_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_28_00_world_335.sql
diff --git a/sql/updates/world/2016_01_28_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_28_01_world.sql
index 3c4cadb310d..3c4cadb310d 100644
--- a/sql/updates/world/2016_01_28_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_28_01_world.sql
diff --git a/sql/updates/world/2016_01_30_00_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_00_world_335.sql
index 43025f581d7..43025f581d7 100644
--- a/sql/updates/world/2016_01_30_00_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_00_world_335.sql
diff --git a/sql/updates/world/2016_01_30_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_01_world.sql
index c9405c4ee61..c9405c4ee61 100644
--- a/sql/updates/world/2016_01_30_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_01_world.sql
diff --git a/sql/updates/world/2016_01_30_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_02_world.sql
index 25325dddd7a..25325dddd7a 100644
--- a/sql/updates/world/2016_01_30_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_02_world.sql
diff --git a/sql/updates/world/2016_01_30_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_03_world.sql
index 06c4b0826c0..06c4b0826c0 100644
--- a/sql/updates/world/2016_01_30_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_03_world.sql
diff --git a/sql/updates/world/2016_01_30_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_04_world.sql
index b90e7b95810..b90e7b95810 100644
--- a/sql/updates/world/2016_01_30_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_04_world.sql
diff --git a/sql/updates/world/2016_01_30_05_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_05_world.sql
index 1e341506dfc..1e341506dfc 100644
--- a/sql/updates/world/2016_01_30_05_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_30_05_world.sql
diff --git a/sql/updates/world/2016_01_31_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_31_00_world.sql
index f64d9182784..f64d9182784 100644
--- a/sql/updates/world/2016_01_31_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_01_31_00_world.sql
diff --git a/sql/updates/world/2016_02_02_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_02_00_world.sql
index ce561af3a61..ce561af3a61 100644
--- a/sql/updates/world/2016_02_02_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_02_00_world.sql
diff --git a/sql/updates/world/2016_02_02_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_02_01_world.sql
index f1b181a29e3..f1b181a29e3 100644
--- a/sql/updates/world/2016_02_02_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_02_01_world.sql
diff --git a/sql/updates/world/2016_02_04_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_04_00_world.sql
index 758286544af..758286544af 100644
--- a/sql/updates/world/2016_02_04_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_04_00_world.sql
diff --git a/sql/updates/world/2016_02_05_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_05_00_world.sql
index 46f2b488b9a..46f2b488b9a 100644
--- a/sql/updates/world/2016_02_05_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_05_00_world.sql
diff --git a/sql/updates/world/2016_02_06_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_00_world.sql
index d303a8b5b85..d303a8b5b85 100644
--- a/sql/updates/world/2016_02_06_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_00_world.sql
diff --git a/sql/updates/world/2016_02_06_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_01_world.sql
index 6812c4af52e..6812c4af52e 100644
--- a/sql/updates/world/2016_02_06_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_01_world.sql
diff --git a/sql/updates/world/2016_02_06_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_02_world.sql
index b9fd7cd9d63..b9fd7cd9d63 100644
--- a/sql/updates/world/2016_02_06_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_02_world.sql
diff --git a/sql/updates/world/2016_02_06_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_03_world.sql
index 85f8d3c6ae7..85f8d3c6ae7 100644
--- a/sql/updates/world/2016_02_06_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_03_world.sql
diff --git a/sql/updates/world/2016_02_06_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_04_world.sql
index 188b3b5f2a7..188b3b5f2a7 100644
--- a/sql/updates/world/2016_02_06_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_04_world.sql
diff --git a/sql/updates/world/2016_02_06_05_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_05_world.sql
index 823a8abaca6..823a8abaca6 100644
--- a/sql/updates/world/2016_02_06_05_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_05_world.sql
diff --git a/sql/updates/world/2016_02_06_06_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_06_world.sql
index 37df2ef0868..37df2ef0868 100644
--- a/sql/updates/world/2016_02_06_06_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_06_world.sql
diff --git a/sql/updates/world/2016_02_06_07_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_07_world.sql
index c5d6434321a..c5d6434321a 100644
--- a/sql/updates/world/2016_02_06_07_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_07_world.sql
diff --git a/sql/updates/world/2016_02_06_08_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_08_world.sql
index f0855ba348a..f0855ba348a 100644
--- a/sql/updates/world/2016_02_06_08_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_08_world.sql
diff --git a/sql/updates/world/2016_02_06_09_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_09_world.sql
index bf92b89e1c2..bf92b89e1c2 100644
--- a/sql/updates/world/2016_02_06_09_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_09_world.sql
diff --git a/sql/updates/world/2016_02_06_10_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_10_world.sql
index 291bd0bb333..291bd0bb333 100644
--- a/sql/updates/world/2016_02_06_10_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_10_world.sql
diff --git a/sql/updates/world/2016_02_06_11_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_11_world.sql
index cea352fec36..cea352fec36 100644
--- a/sql/updates/world/2016_02_06_11_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_11_world.sql
diff --git a/sql/updates/world/2016_02_06_12_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_12_world.sql
index df550156bc1..df550156bc1 100644
--- a/sql/updates/world/2016_02_06_12_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_12_world.sql
diff --git a/sql/updates/world/2016_02_06_13_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_13_world_335.sql
index 22bd5596d98..22bd5596d98 100644
--- a/sql/updates/world/2016_02_06_13_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_13_world_335.sql
diff --git a/sql/updates/world/2016_02_06_14_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_14_world.sql
index 7bf05b61c71..7bf05b61c71 100644
--- a/sql/updates/world/2016_02_06_14_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_06_14_world.sql
diff --git a/sql/updates/world/2016_02_07_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_00_world.sql
index 5a49f8fd310..5a49f8fd310 100644
--- a/sql/updates/world/2016_02_07_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_00_world.sql
diff --git a/sql/updates/world/2016_02_07_01_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_01_world_335.sql
index 5f1d5f4280e..5f1d5f4280e 100644
--- a/sql/updates/world/2016_02_07_01_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_01_world_335.sql
diff --git a/sql/updates/world/2016_02_07_02_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_02_world_335.sql
index ea4608f3a6b..ea4608f3a6b 100644
--- a/sql/updates/world/2016_02_07_02_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_02_world_335.sql
diff --git a/sql/updates/world/2016_02_07_03_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_03_world_335.sql
index 8322ff59c4c..8322ff59c4c 100644
--- a/sql/updates/world/2016_02_07_03_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_03_world_335.sql
diff --git a/sql/updates/world/2016_02_07_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_04_world.sql
index 3a3a7a393d7..3a3a7a393d7 100644
--- a/sql/updates/world/2016_02_07_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_04_world.sql
diff --git a/sql/updates/world/2016_02_07_05_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_05_world_335.sql
index 794b3d80411..794b3d80411 100644
--- a/sql/updates/world/2016_02_07_05_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_05_world_335.sql
diff --git a/sql/updates/world/2016_02_07_06_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_06_world.sql
index 31ecf826660..31ecf826660 100644
--- a/sql/updates/world/2016_02_07_06_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_06_world.sql
diff --git a/sql/updates/world/2016_02_07_07_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_07_world_335.sql
index af323a47bda..af323a47bda 100644
--- a/sql/updates/world/2016_02_07_07_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_07_world_335.sql
diff --git a/sql/updates/world/2016_02_07_08_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_08_world_335.sql
index 2b78a317f95..2b78a317f95 100644
--- a/sql/updates/world/2016_02_07_08_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_08_world_335.sql
diff --git a/sql/updates/world/2016_02_07_09_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_09_world.sql
index 8057534fbb8..8057534fbb8 100644
--- a/sql/updates/world/2016_02_07_09_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_09_world.sql
diff --git a/sql/updates/world/2016_02_07_10_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_10_world.sql
index c2e59c15d9c..c2e59c15d9c 100644
--- a/sql/updates/world/2016_02_07_10_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_10_world.sql
diff --git a/sql/updates/world/2016_02_07_11_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_11_world.sql
index c40b663c205..c40b663c205 100644
--- a/sql/updates/world/2016_02_07_11_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_11_world.sql
diff --git a/sql/updates/world/2016_02_07_12_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_12_world.sql
index c85265d857d..c85265d857d 100644
--- a/sql/updates/world/2016_02_07_12_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_12_world.sql
diff --git a/sql/updates/world/2016_02_07_13_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_13_world.sql
index 612fef2274d..612fef2274d 100644
--- a/sql/updates/world/2016_02_07_13_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_13_world.sql
diff --git a/sql/updates/world/2016_02_07_14_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_14_world.sql
index 6550e53f9c9..6550e53f9c9 100644
--- a/sql/updates/world/2016_02_07_14_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_14_world.sql
diff --git a/sql/updates/world/2016_02_07_15_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_15_world.sql
index ceec02f881b..ceec02f881b 100644
--- a/sql/updates/world/2016_02_07_15_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_07_15_world.sql
diff --git a/sql/updates/world/2016_02_08_00_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_00_world_335.sql
index 83091035e3c..83091035e3c 100644
--- a/sql/updates/world/2016_02_08_00_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_00_world_335.sql
diff --git a/sql/updates/world/2016_02_08_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_01_world.sql
index 9f8fa3dc4ed..9f8fa3dc4ed 100644
--- a/sql/updates/world/2016_02_08_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_01_world.sql
diff --git a/sql/updates/world/2016_02_08_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_02_world.sql
index 0f22abafe8e..0f22abafe8e 100644
--- a/sql/updates/world/2016_02_08_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_02_world.sql
diff --git a/sql/updates/world/2016_02_08_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_03_world.sql
index fe429cf42c8..fe429cf42c8 100644
--- a/sql/updates/world/2016_02_08_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_03_world.sql
diff --git a/sql/updates/world/2016_02_08_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_04_world.sql
index f8a9e2c776a..f8a9e2c776a 100644
--- a/sql/updates/world/2016_02_08_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_04_world.sql
diff --git a/sql/updates/world/2016_02_08_05_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_05_world.sql
index d2cc597a6ac..d2cc597a6ac 100644
--- a/sql/updates/world/2016_02_08_05_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_05_world.sql
diff --git a/sql/updates/world/2016_02_08_06_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_06_world.sql
index c9e93889790..c9e93889790 100644
--- a/sql/updates/world/2016_02_08_06_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_06_world.sql
diff --git a/sql/updates/world/2016_02_08_07_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_07_world.sql
index 1d90630d829..1d90630d829 100644
--- a/sql/updates/world/2016_02_08_07_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_07_world.sql
diff --git a/sql/updates/world/2016_02_08_08_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_08_world.sql
index ae4f454bc91..ae4f454bc91 100644
--- a/sql/updates/world/2016_02_08_08_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_08_08_world.sql
diff --git a/sql/updates/world/2016_02_09_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_00_world.sql
index c93a1d8fed1..c93a1d8fed1 100644
--- a/sql/updates/world/2016_02_09_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_00_world.sql
diff --git a/sql/updates/world/2016_02_09_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_01_world.sql
index 7878ea7faa2..7878ea7faa2 100644
--- a/sql/updates/world/2016_02_09_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_01_world.sql
diff --git a/sql/updates/world/2016_02_09_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_02_world.sql
index 891c8c2ff4b..891c8c2ff4b 100644
--- a/sql/updates/world/2016_02_09_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_02_world.sql
diff --git a/sql/updates/world/2016_02_09_02_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_02_world_335.sql
index a8612c5d88d..a8612c5d88d 100644
--- a/sql/updates/world/2016_02_09_02_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_02_world_335.sql
diff --git a/sql/updates/world/2016_02_09_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_03_world.sql
index bd012f0d172..bd012f0d172 100644
--- a/sql/updates/world/2016_02_09_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_03_world.sql
diff --git a/sql/updates/world/2016_02_09_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_04_world.sql
index 015ab519557..015ab519557 100644
--- a/sql/updates/world/2016_02_09_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_04_world.sql
diff --git a/sql/updates/world/2016_02_09_05_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_05_world.sql
index 3612c270d02..3612c270d02 100644
--- a/sql/updates/world/2016_02_09_05_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_05_world.sql
diff --git a/sql/updates/world/2016_02_09_06_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_06_world.sql
index 03fe998cca5..03fe998cca5 100644
--- a/sql/updates/world/2016_02_09_06_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_06_world.sql
diff --git a/sql/updates/world/2016_02_09_07_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_07_world.sql
index 84d65e2eda5..84d65e2eda5 100644
--- a/sql/updates/world/2016_02_09_07_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_07_world.sql
diff --git a/sql/updates/world/2016_02_09_08_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_08_world.sql
index 307a9f9a0b3..307a9f9a0b3 100644
--- a/sql/updates/world/2016_02_09_08_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_09_08_world.sql
diff --git a/sql/updates/world/2016_02_10_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_00_world.sql
index 872861b08dc..872861b08dc 100644
--- a/sql/updates/world/2016_02_10_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_00_world.sql
diff --git a/sql/updates/world/2016_02_10_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_01_world.sql
index 9ffe2e81c1c..9ffe2e81c1c 100644
--- a/sql/updates/world/2016_02_10_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_01_world.sql
diff --git a/sql/updates/world/2016_02_10_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_02_world.sql
index 92ee165dd83..92ee165dd83 100644
--- a/sql/updates/world/2016_02_10_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_02_world.sql
diff --git a/sql/updates/world/2016_02_10_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_03_world.sql
index f52872c3431..f52872c3431 100644
--- a/sql/updates/world/2016_02_10_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_03_world.sql
diff --git a/sql/updates/world/2016_02_10_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_04_world.sql
index 1349b83f442..1349b83f442 100644
--- a/sql/updates/world/2016_02_10_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_04_world.sql
diff --git a/sql/updates/world/2016_02_10_05_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_05_world.sql
index c19dd8feb06..c19dd8feb06 100644
--- a/sql/updates/world/2016_02_10_05_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_05_world.sql
diff --git a/sql/updates/world/2016_02_10_06_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_06_world.sql
index 9e24ab31ce1..9e24ab31ce1 100644
--- a/sql/updates/world/2016_02_10_06_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_06_world.sql
diff --git a/sql/updates/world/2016_02_10_07_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_07_world.sql
index 5feb4f44163..5feb4f44163 100644
--- a/sql/updates/world/2016_02_10_07_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_10_07_world.sql
diff --git a/sql/updates/world/2016_02_11_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_00_world.sql
index b130133a2ca..b130133a2ca 100644
--- a/sql/updates/world/2016_02_11_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_00_world.sql
diff --git a/sql/updates/world/2016_02_11_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_01_world.sql
index ec1c98659e1..ec1c98659e1 100644
--- a/sql/updates/world/2016_02_11_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_01_world.sql
diff --git a/sql/updates/world/2016_02_11_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_02_world.sql
index 9228e2d99d7..9228e2d99d7 100644
--- a/sql/updates/world/2016_02_11_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_02_world.sql
diff --git a/sql/updates/world/2016_02_11_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_03_world.sql
index 4dfefb12281..4dfefb12281 100644
--- a/sql/updates/world/2016_02_11_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_03_world.sql
diff --git a/sql/updates/world/2016_02_11_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_04_world.sql
index 41f648b5f6e..41f648b5f6e 100644
--- a/sql/updates/world/2016_02_11_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_04_world.sql
diff --git a/sql/updates/world/2016_02_11_05_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_05_world.sql
index 76b59765d08..76b59765d08 100644
--- a/sql/updates/world/2016_02_11_05_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_05_world.sql
diff --git a/sql/updates/world/2016_02_11_06_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_06_world.sql
index bbf9880dca9..bbf9880dca9 100644
--- a/sql/updates/world/2016_02_11_06_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_06_world.sql
diff --git a/sql/updates/world/2016_02_11_07_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_07_world.sql
index e34106cb44c..e34106cb44c 100644
--- a/sql/updates/world/2016_02_11_07_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_11_07_world.sql
diff --git a/sql/updates/world/2016_02_12_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_12_00_world.sql
index af599148e04..af599148e04 100644
--- a/sql/updates/world/2016_02_12_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_12_00_world.sql
diff --git a/sql/updates/world/2016_02_13_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_13_00_world.sql
index 2341e33a8b5..2341e33a8b5 100644
--- a/sql/updates/world/2016_02_13_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_13_00_world.sql
diff --git a/sql/updates/world/2016_02_13_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_13_01_world.sql
index 29f94a9f41d..29f94a9f41d 100644
--- a/sql/updates/world/2016_02_13_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_13_01_world.sql
diff --git a/sql/updates/world/2016_02_13_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_13_02_world.sql
index 5a4633fee41..5a4633fee41 100644
--- a/sql/updates/world/2016_02_13_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_13_02_world.sql
diff --git a/sql/updates/world/2016_02_13_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_13_03_world.sql
index 136a068bd9e..136a068bd9e 100644
--- a/sql/updates/world/2016_02_13_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_13_03_world.sql
diff --git a/sql/updates/world/2016_02_13_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_13_04_world.sql
index 83d95745052..83d95745052 100644
--- a/sql/updates/world/2016_02_13_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_13_04_world.sql
diff --git a/sql/updates/world/2016_02_14_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_14_00_world.sql
index 961ecd74d4d..961ecd74d4d 100644
--- a/sql/updates/world/2016_02_14_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_14_00_world.sql
diff --git a/sql/updates/world/2016_02_14_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_14_01_world.sql
index 2ce06020621..2ce06020621 100644
--- a/sql/updates/world/2016_02_14_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_14_01_world.sql
diff --git a/sql/updates/world/2016_02_14_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_14_02_world.sql
index 1459b702cf0..1459b702cf0 100644
--- a/sql/updates/world/2016_02_14_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_14_02_world.sql
diff --git a/sql/updates/world/2016_02_14_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_14_03_world.sql
index 9a0237725c0..9a0237725c0 100644
--- a/sql/updates/world/2016_02_14_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_14_03_world.sql
diff --git a/sql/updates/world/2016_02_14_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_14_04_world.sql
index 58e0aaee311..58e0aaee311 100644
--- a/sql/updates/world/2016_02_14_04_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_14_04_world.sql
diff --git a/sql/updates/world/2016_02_15_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_15_00_world.sql
index 43c2ae69382..43c2ae69382 100644
--- a/sql/updates/world/2016_02_15_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_15_00_world.sql
diff --git a/sql/updates/world/2016_02_17_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_17_00_world.sql
index 8f22aaa3e4e..8f22aaa3e4e 100644
--- a/sql/updates/world/2016_02_17_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_17_00_world.sql
diff --git a/sql/updates/world/2016_02_17_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_17_01_world.sql
index 20f3605b197..20f3605b197 100644
--- a/sql/updates/world/2016_02_17_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_17_01_world.sql
diff --git a/sql/updates/world/2016_02_17_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_17_02_world.sql
index 6590396b7d9..6590396b7d9 100644
--- a/sql/updates/world/2016_02_17_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_17_02_world.sql
diff --git a/sql/updates/world/2016_02_18_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_18_00_world.sql
index c20196ddc80..c20196ddc80 100644
--- a/sql/updates/world/2016_02_18_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_18_00_world.sql
diff --git a/sql/updates/world/2016_02_18_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_18_01_world.sql
index c3ffdbb6344..c3ffdbb6344 100644
--- a/sql/updates/world/2016_02_18_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_18_01_world.sql
diff --git a/sql/updates/world/2016_02_18_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_18_02_world.sql
index 414c6fd9c3a..414c6fd9c3a 100644
--- a/sql/updates/world/2016_02_18_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_18_02_world.sql
diff --git a/sql/updates/world/2016_02_19_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_19_00_world.sql
index bee93f7bdd4..bee93f7bdd4 100644
--- a/sql/updates/world/2016_02_19_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_19_00_world.sql
diff --git a/sql/updates/world/2016_02_19_01_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_19_01_world_335.sql
index f7fee657170..f7fee657170 100644
--- a/sql/updates/world/2016_02_19_01_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_19_01_world_335.sql
diff --git a/sql/updates/world/2016_02_22_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_22_00_world.sql
index d92ea91681a..d92ea91681a 100644
--- a/sql/updates/world/2016_02_22_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_22_00_world.sql
diff --git a/sql/updates/world/2016_02_22_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_22_01_world.sql
index b1345bb1aab..b1345bb1aab 100644
--- a/sql/updates/world/2016_02_22_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_22_01_world.sql
diff --git a/sql/updates/world/2016_02_22_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_22_02_world.sql
index dd62e6dce29..dd62e6dce29 100644
--- a/sql/updates/world/2016_02_22_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_22_02_world.sql
diff --git a/sql/updates/world/2016_02_23_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_23_00_world.sql
index 871ce608f1c..871ce608f1c 100644
--- a/sql/updates/world/2016_02_23_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_23_00_world.sql
diff --git a/sql/updates/world/2016_02_23_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_23_01_world.sql
index 0773487dbc7..0773487dbc7 100644
--- a/sql/updates/world/2016_02_23_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_23_01_world.sql
diff --git a/sql/updates/world/2016_02_23_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_23_02_world.sql
index 9e2c550dd65..9e2c550dd65 100644
--- a/sql/updates/world/2016_02_23_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_23_02_world.sql
diff --git a/sql/updates/world/2016_02_24_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_24_00_world.sql
index 06c7c29bd72..06c7c29bd72 100644
--- a/sql/updates/world/2016_02_24_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_24_00_world.sql
diff --git a/sql/updates/world/2016_02_25_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_25_00_world.sql
index 346c77bee43..346c77bee43 100644
--- a/sql/updates/world/2016_02_25_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_25_00_world.sql
diff --git a/sql/updates/world/2016_02_25_01_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_25_01_world_335.sql
index 473cbd506ce..473cbd506ce 100644
--- a/sql/updates/world/2016_02_25_01_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_25_01_world_335.sql
diff --git a/sql/updates/world/2016_02_25_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_25_02_world.sql
index c5355b13c29..c5355b13c29 100644
--- a/sql/updates/world/2016_02_25_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_25_02_world.sql
diff --git a/sql/updates/world/2016_02_26_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_26_00_world.sql
index d08d5055089..d08d5055089 100644
--- a/sql/updates/world/2016_02_26_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_26_00_world.sql
diff --git a/sql/updates/world/2016_02_26_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_26_01_world.sql
index b30b3cba35f..b30b3cba35f 100644
--- a/sql/updates/world/2016_02_26_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_26_01_world.sql
diff --git a/sql/updates/world/2016_02_27_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_27_00_world.sql
index b9288b2ddfb..b9288b2ddfb 100644
--- a/sql/updates/world/2016_02_27_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_27_00_world.sql
diff --git a/sql/updates/world/2016_02_28_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_28_00_world.sql
index 5a5694e0320..5a5694e0320 100644
--- a/sql/updates/world/2016_02_28_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_28_00_world.sql
diff --git a/sql/updates/world/2016_02_29_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_29_00_world.sql
index 280f2f901ef..280f2f901ef 100644
--- a/sql/updates/world/2016_02_29_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_29_00_world.sql
diff --git a/sql/updates/world/2016_02_29_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_29_01_world.sql
index 40343440d9a..40343440d9a 100644
--- a/sql/updates/world/2016_02_29_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_02_29_01_world.sql
diff --git a/sql/updates/world/2016_03_01_00_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_01_00_world_335.sql
index 36c48379190..36c48379190 100644
--- a/sql/updates/world/2016_03_01_00_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_01_00_world_335.sql
diff --git a/sql/updates/world/2016_03_02_00_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_02_00_world_335.sql
index e7a9f60e790..e7a9f60e790 100644
--- a/sql/updates/world/2016_03_02_00_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_02_00_world_335.sql
diff --git a/sql/updates/world/2016_03_03_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_03_00_world.sql
index 473bac4708a..473bac4708a 100644
--- a/sql/updates/world/2016_03_03_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_03_00_world.sql
diff --git a/sql/updates/world/2016_03_03_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_03_01_world.sql
index a242d26efe1..a242d26efe1 100644
--- a/sql/updates/world/2016_03_03_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_03_01_world.sql
diff --git a/sql/updates/world/2016_03_04_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_04_00_world.sql
index f338d6d0043..f338d6d0043 100644
--- a/sql/updates/world/2016_03_04_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_04_00_world.sql
diff --git a/sql/updates/world/2016_03_04_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_04_01_world.sql
index b02c2eb4e79..b02c2eb4e79 100644
--- a/sql/updates/world/2016_03_04_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_04_01_world.sql
diff --git a/sql/updates/world/2016_03_04_02_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_04_02_world_335.sql
index db8ca3a9178..db8ca3a9178 100644
--- a/sql/updates/world/2016_03_04_02_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_04_02_world_335.sql
diff --git a/sql/updates/world/2016_03_04_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_04_03_world.sql
index 4d148adde55..4d148adde55 100644
--- a/sql/updates/world/2016_03_04_03_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_04_03_world.sql
diff --git a/sql/updates/world/2016_03_05_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_05_00_world.sql
index 8dde060140d..8dde060140d 100644
--- a/sql/updates/world/2016_03_05_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_05_00_world.sql
diff --git a/sql/updates/world/2016_03_06_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_06_00_world.sql
index e991023e514..e991023e514 100644
--- a/sql/updates/world/2016_03_06_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_06_00_world.sql
diff --git a/sql/updates/world/2016_03_06_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_06_01_world.sql
index 183121d6735..183121d6735 100644
--- a/sql/updates/world/2016_03_06_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_06_01_world.sql
diff --git a/sql/updates/world/2016_03_07_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_07_00_world.sql
index b9df4d07bb9..b9df4d07bb9 100644
--- a/sql/updates/world/2016_03_07_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_07_00_world.sql
diff --git a/sql/updates/world/2016_03_07_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_07_01_world.sql
index d74f4296903..d74f4296903 100644
--- a/sql/updates/world/2016_03_07_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_07_01_world.sql
diff --git a/sql/updates/world/2016_03_09_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_09_00_world.sql
index d3ebf1af0ff..d3ebf1af0ff 100644
--- a/sql/updates/world/2016_03_09_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_09_00_world.sql
diff --git a/sql/updates/world/2016_03_10_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_10_00_world.sql
index e3170b27499..e3170b27499 100644
--- a/sql/updates/world/2016_03_10_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_10_00_world.sql
diff --git a/sql/updates/world/2016_03_10_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_10_01_world.sql
index 80b23be82c2..80b23be82c2 100644
--- a/sql/updates/world/2016_03_10_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_10_01_world.sql
diff --git a/sql/updates/world/2016_03_12_2015_11_14_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_12_2015_11_14_00_world.sql
index b3e49eb1114..b3e49eb1114 100644
--- a/sql/updates/world/2016_03_12_2015_11_14_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_12_2015_11_14_00_world.sql
diff --git a/sql/updates/world/2016_03_13_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_13_00_world.sql
index 0c45636d945..0c45636d945 100644
--- a/sql/updates/world/2016_03_13_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_13_00_world.sql
diff --git a/sql/updates/world/2016_03_13_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_13_01_world.sql
index 12bc205f125..12bc205f125 100644
--- a/sql/updates/world/2016_03_13_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_13_01_world.sql
diff --git a/sql/updates/world/2016_03_15_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_15_00_world.sql
index 69e2e3a873b..69e2e3a873b 100644
--- a/sql/updates/world/2016_03_15_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_15_00_world.sql
diff --git a/sql/updates/world/2016_03_19_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_19_00_world.sql
index ce96286d585..ce96286d585 100644
--- a/sql/updates/world/2016_03_19_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_19_00_world.sql
diff --git a/sql/updates/world/2016_03_19_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_19_01_world.sql
index 79452fdf43c..79452fdf43c 100644
--- a/sql/updates/world/2016_03_19_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_19_01_world.sql
diff --git a/sql/updates/world/2016_03_19_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_19_02_world.sql
index a0a6ff3619c..a0a6ff3619c 100644
--- a/sql/updates/world/2016_03_19_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_19_02_world.sql
diff --git a/sql/updates/world/2016_03_20_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_20_00_world.sql
index 8120f1be86f..8120f1be86f 100644
--- a/sql/updates/world/2016_03_20_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_20_00_world.sql
diff --git a/sql/updates/world/2016_03_20_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_20_01_world.sql
index f59710f1e32..f59710f1e32 100644
--- a/sql/updates/world/2016_03_20_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_20_01_world.sql
diff --git a/sql/updates/world/2016_03_20_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_20_02_world.sql
index 9b03a9cdea3..9b03a9cdea3 100644
--- a/sql/updates/world/2016_03_20_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_20_02_world.sql
diff --git a/sql/updates/world/2016_03_21_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_21_00_world.sql
index 55f6cceaed8..55f6cceaed8 100644
--- a/sql/updates/world/2016_03_21_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_21_00_world.sql
diff --git a/sql/updates/world/2016_03_23_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_23_00_world.sql
index 9195b652288..9195b652288 100644
--- a/sql/updates/world/2016_03_23_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_23_00_world.sql
diff --git a/sql/updates/world/2016_03_24_00_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_24_00_world_335.sql
index 4d69d8fd3f2..4d69d8fd3f2 100644
--- a/sql/updates/world/2016_03_24_00_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_24_00_world_335.sql
diff --git a/sql/updates/world/2016_03_24_01_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_24_01_world_335.sql
index 01d7857519e..01d7857519e 100644
--- a/sql/updates/world/2016_03_24_01_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_24_01_world_335.sql
diff --git a/sql/updates/world/2016_03_24_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_24_02_world.sql
index 199582eb4a0..199582eb4a0 100644
--- a/sql/updates/world/2016_03_24_02_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_24_02_world.sql
diff --git a/sql/updates/world/2016_03_26_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_26_00_world.sql
index 58a42dc214d..58a42dc214d 100644
--- a/sql/updates/world/2016_03_26_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_26_00_world.sql
diff --git a/sql/updates/world/2016_03_27_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_27_00_world.sql
index 9421881c88a..9421881c88a 100644
--- a/sql/updates/world/2016_03_27_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_27_00_world.sql
diff --git a/sql/updates/world/2016_03_28_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_28_00_world.sql
index b4a7e2d5a36..b4a7e2d5a36 100644
--- a/sql/updates/world/2016_03_28_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_28_00_world.sql
diff --git a/sql/updates/world/2016_03_28_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_28_01_world.sql
index b4a24b011b3..b4a24b011b3 100644
--- a/sql/updates/world/2016_03_28_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_28_01_world.sql
diff --git a/sql/updates/world/2016_03_29_00_world_335.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_29_00_world_335.sql
index e3851e59c8e..e3851e59c8e 100644
--- a/sql/updates/world/2016_03_29_00_world_335.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_03_29_00_world_335.sql
diff --git a/sql/updates/world/2016_04_01_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_01_00_world.sql
index 024bbb6fa5a..024bbb6fa5a 100644
--- a/sql/updates/world/2016_04_01_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_01_00_world.sql
diff --git a/sql/updates/world/2016_04_01_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_01_01_world.sql
index 38a13f0ea84..38a13f0ea84 100644
--- a/sql/updates/world/2016_04_01_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_01_01_world.sql
diff --git a/sql/updates/world/2016_04_02_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_02_00_world.sql
index dc8f4375da0..dc8f4375da0 100644
--- a/sql/updates/world/2016_04_02_00_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_02_00_world.sql
diff --git a/sql/updates/world/2016_04_02_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_02_01_world.sql
index 4bcca1d6250..4bcca1d6250 100644
--- a/sql/updates/world/2016_04_02_01_world.sql
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_02_01_world.sql
diff --git a/sql/old/3.3.5a/world/60_2016_04_11/2016_04_02_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_02_02_world.sql
new file mode 100644
index 00000000000..89b8032be10
--- /dev/null
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_02_02_world.sql
@@ -0,0 +1,3 @@
+DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=63277;
+INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES
+(63277,65269,2,'General Vezax - Shadow Crash - Haste and reduced mana cost');
diff --git a/sql/old/3.3.5a/world/60_2016_04_11/2016_04_03_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_03_00_world.sql
new file mode 100644
index 00000000000..8344df664f2
--- /dev/null
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_03_00_world.sql
@@ -0,0 +1,2 @@
+-- Remove duplicate spawn of "Big Roy" (24785)
+DELETE FROM `creature` WHERE `guid`=203496 AND `id`=24785;
diff --git a/sql/old/3.3.5a/world/60_2016_04_11/2016_04_03_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_03_01_world.sql
new file mode 100644
index 00000000000..a150fe2d69e
--- /dev/null
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_03_01_world.sql
@@ -0,0 +1,36 @@
+DELETE FROM `smart_scripts` WHERE `entryorguid`=24713 AND `source_type`=0 AND `id`>1;
+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
+(24713, 0, 2, 3, 62, 0, 100, 0, 9335, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, '"Crowleg" Dan - On Gossip Option Select - Close Gossip'),
+(24713, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, '"Crowleg" Dan - On Gossip Option Select - Start Attack');
+
+DELETE FROM `gossip_menu_option` WHERE `menu_id`=9335;
+INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`, `option_text`, `OptionBroadcastTextID`, `option_id`, `npc_option_npcflag`, `action_menu_id`, `action_poi_id`, `box_coded`, `box_money`, `box_text`, `BoxBroadcastTextID`) VALUES
+(9335, 0, 0, 'Ummm... the frog says you''re a traitor, "matey."', 25738, 1, 1, 0, 0, 0, 0, NULL, 0);
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9335;
+
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(15, 9335, 0, 0, 0, 9, 0, 11479, 0, 0, 0, 0, 0, '', 'Crowleg" Dan - Only show Gossip if player is on quest');
+
+UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI', scriptname='' WHERE `entry` =186944;
+DELETE FROM `smart_scripts` WHERE `entryorguid` =186944 AND `source_type`=1;
+
+
+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
+(186944, 1, 0, 1, 70, 0, 100, 0, 2, 0, 0, 0, 105, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Dirt Mound - On State Changed - Add Go Flag '),
+(186944, 1, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 12, 24790, 1, 120000, 1, 0, 0, 8, 0, 0, 0, 688.9122, -3377.737, 67.87585, 1.291544, 'Dirt Mound - On State Changed - Summon Black Conrads Ghost'),
+(186944, 1, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 12, 24796, 1, 120000, 1, 0, 0, 8, 0, 0, 0, 691.5706, -3375.863, 68.09953, 1.308997, 'Dirt Mound - On State Changed - Summon Spectral Sailor'),
+(186944, 1, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 12, 24796, 1, 120000, 1, 0, 0, 8, 0, 0, 0, 687.27, -3374.881, 67.92136, 1.047198, 'Dirt Mound - On State Changed - Summon Spectral Sailor');
+
+DELETE FROM `creature` WHERE `guid`=116177;
+UPDATE `gameobject` SET `spawntimesecs`=120 WHERE `guid`=5842;
+
+DELETE FROM `smart_scripts` WHERE `entryorguid`=23777 AND `source_type`=0 AND `id`IN(6,7);
+
+UPDATE `smart_scripts` SET `link`=6 WHERE `entryorguid`=23777 AND `source_type`=0 AND `id`=1 AND `link`=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
+(23777, 0, 6, 7, 61, 0, 100, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Proto-Drake Egg - On Reset - Set Passive'),
+(23777, 0, 7, 0, 61, 0, 100, 0, 0, 0, 0, 0, 94, 24, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Proto-Drake Egg - On Reset - Set Dynamic Flags');
+
+
+UPDATE `creature_template` SET `unit_flags`=0 WHERE `entry`=23777;
diff --git a/sql/old/3.3.5a/world/60_2016_04_11/2016_04_03_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_03_02_world.sql
new file mode 100644
index 00000000000..1a408d3ec6a
--- /dev/null
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_03_02_world.sql
@@ -0,0 +1,2 @@
+-- Fix respawn time for quest loot GO "Daggerfen Poison Manual"
+UPDATE `gameobject` SET `spawntimesecs`=2 WHERE `guid`=22662;
diff --git a/sql/old/3.3.5a/world/60_2016_04_11/2016_04_04_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_04_00_world.sql
new file mode 100644
index 00000000000..69da8a7d699
--- /dev/null
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_04_00_world.sql
@@ -0,0 +1,149 @@
+UPDATE `quest_template_addon` SET `RequiredMinRepValue`=9000 WHERE `ID`=9729;
+
+DELETE FROM `creature_text` WHERE `entry`=17877;
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
+(17877, 0, 0, 'Fhwoor go now, $n. Get ark, come back.', 12, 0, 100, 0, 0, 0, 16439, 0, 'Fhwoor'),
+(17877, 1, 0, 'Take moment... get ready.', 12, 0, 100, 0, 0, 0, 16440, 0, 'Fhwoor'),
+(17877, 2, 0, 'We go!', 12, 0, 100, 0, 0, 0, 16441, 0, 'Fhwoor'),
+(17877, 3, 0, '%s lifts the Ark of Ssslith with ease.', 16, 0, 100, 0, 0, 0, 16442, 0, 'Fhwoor'),
+(17877, 4, 0, 'Uh oh...', 12, 0, 100, 0, 0, 0, 16443, 0, 'Fhwoor'),
+(17877, 5, 0, 'Ha ha, squishy naga!', 12, 0, 100, 0, 0, 0, 16444, 0, 'Fhwoor'),
+(17877, 6, 0, '%s places the Ark of Ssslith on the ground.', 16, 0, 100, 0, 0, 0, 16445, 0, 'Fhwoor'),
+(17877, 7, 0, 'Fhwoor do good!', 16, 0, 100, 0, 0, 0, 16446, 0, 'Fhwoor');
+
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`IN(18154,17877);
+
+DELETE FROM `smart_scripts` WHERE `entryorguid`IN(17877,18154) AND `source_type`=0;
+DELETE FROM `smart_scripts` WHERE `entryorguid`IN(1787700,1787701) AND `source_type`=9;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=18089 AND `source_type`=0 AND `id`>0;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=18088 AND `source_type`=0 AND `id`>1;
+
+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
+(18154, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 53, 0, 18154, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 'Ssslith - On Just Summoned - Start WP'),
+(18088, 0, 2, 0, 54, 0, 100, 0, 0, 0, 0, 0, 53, 0, 18088, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 'Bloodscale Enchantress - On Just Summoned - Start WP'),
+(18089, 0, 1, 0, 54, 0, 100, 0, 0, 0, 0, 0, 53, 0, 18089, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 'Bloodscale Slavedriver - On Just Summoned - Start WP'),
+(18154, 0, 1, 0, 40, 0, 100, 0, 12, 18154, 0, 0, 66, 0, 0, 0, 0, 0, 0, 19, 17877, 0, 0, 0, 0, 0, 0, 'Ssslith - On Reached WP12 - Face Fhwoor'),
+(18088, 0, 3, 0, 40, 0, 100, 0, 6, 18088, 0, 0, 66, 0, 0, 0, 0, 0, 0, 19, 17877, 0, 0, 0, 0, 0, 0, 'Bloodscale Enchantress - On Reached WP12 - Face Fhwoor'),
+(18089, 0, 2, 0, 40, 0, 100, 0, 8, 18089, 0, 0, 66, 0, 0, 0, 0, 0, 0, 19, 17877, 0, 0, 0, 0, 0, 0, 'Bloodscale Slavedriver - On Reached WP12 - Face Fhwoor'),
+(17877, 0, 0, 1, 19, 0, 100, 0, 9729, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Quest Accept (Fhwoor Smash) - Store Targetlist'),
+(17877, 0, 1, 18, 61, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Quest Accept (Fhwoor Smash) - Say Line 0'),
+(17877, 0, 2, 0, 6, 0, 100, 0, 0, 0, 0, 0, 6, 9729, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Death - Fail Quest Fhwoor Smash'),
+(17877, 0, 3, 4, 40, 0, 100, 0, 11, 17877, 0, 0, 1, 1, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Reached WP11 - Say Line 1'),
+(17877, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 54, 20000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Reached WP11 - Pause WP (20 seconds)'),
+(17877, 0, 5, 0, 40, 0, 100, 0, 12, 17877, 0, 0, 1, 2, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Reached WP12 - Say Line 2'),
+(17877, 0, 6, 7, 40, 0, 100, 0, 27, 17877, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Reached WP27 - Say Line 3'),
+(17877, 0, 7, 8, 61, 0, 100, 0, 0, 0, 0, 0, 54, 5000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Reached WP27 - Pause WP (5 seconds)'),
+(17877, 0, 8, 0, 61, 0, 100, 0, 0, 0, 0, 0, 70, 120, 0, 0, 0, 0, 0, 20, 182082, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Reached WP27 - Despawn The Ark of Ssslith'),
+(17877, 0, 9, 10, 40, 0, 100, 0, 43, 17877, 0, 0, 1, 4, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Reached WP43 - Say Line 4'),
+(17877, 0, 10, 11, 61, 0, 100, 0, 0, 0, 0, 0, 54, 20000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Reached WP43 - Pause WP (20 seconds)'),
+(17877, 0, 11, 12, 61, 0, 100, 0, 0, 0, 0, 0, 12, 18154, 1, 300000, 0, 0, 0, 8, 0, 0, 0, 168.5472, 8207.521, 22.9772, 4.467648, 'Fhwoor - On Reached WP43 - Summon Ssslith'),
+(17877, 0, 12, 13, 61, 0, 100, 0, 0, 0, 0, 0, 12, 18088, 1, 300000, 0, 0, 0, 8, 0, 0, 0, 172.8663, 8214.886, 22.31137, 4.198237, 'Fhwoor - On Reached WP43 - Summon Bloodscale Enchantress'),
+(17877, 0, 13, 0, 61, 0, 100, 0, 0, 0, 0, 0, 12, 18089, 1, 300000, 0, 0, 0, 8, 0, 0, 0, 166.7656, 8215.018, 22.63307, 4.604752, 'Fhwoor - On Reached WP43 - Summon Bloodscale Slavedriver'),
+(17877, 0, 14, 0, 11, 0, 100, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Spawn Set Active'),
+(17877, 0, 15, 0, 40, 0, 100, 0, 44, 17877, 0, 0, 1, 5, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Reached WP44 - Say Line 5'),
+(17877, 0, 16, 0, 40, 0, 100, 0, 45, 17877, 0, 0, 59, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Reached WP45 - Set Run On'),
+(17877, 0, 17, 0, 40, 0, 100, 0, 60, 17877, 0, 0, 80, 1787701, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Reached WP60 - Run Script 2'),
+(17877, 0, 18, 0, 61, 0, 100, 0, 0, 0, 0, 0, 80, 1787700, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Quest Accept - Run Script 1'),
+(17877, 0, 19, 20, 40, 0, 100, 0, 61, 17877, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 2.042035, 'Fhwoor - On Reached WP61 - Set Orientation'),
+(17877, 0, 20, 21, 61, 0, 100, 0, 0, 0, 0, 0, 81, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Reached WP61 - Set Npc Flags'),
+(17877, 0, 21, 22, 61, 0, 100, 0, 0, 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Reached WP61 - Turn Run Off'),
+(17877, 0, 22, 23, 61, 0, 100, 0, 0, 0, 0, 0, 1, 7, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Reached WP61 - Say Line 7'),
+(17877, 0, 23, 24, 61, 0, 100, 0, 0, 0, 0, 0, 2, 1709, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Reached WP61 - Set Faction'),
+(17877, 0, 24, 0, 61, 0, 100, 0, 0, 0, 0, 0, 15, 9729, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Reached WP61 - Complete Quest'),
+(17877, 0, 25, 0, 9, 0, 100, 0, 0, 10, 20000, 30000, 11, 31277, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - On Range - Cast Stomp'),
+(1787700, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - Script - Set NPC Flags'),
+(1787700, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 2, 250, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - Script - Set Faction'),
+(1787700, 9, 2, 0, 0, 0, 100, 0, 10000, 10000, 0, 0, 53, 0, 17877, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - Script - Start WP'),
+(1787701, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 54, 5000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - Script 2 - Pause WP (5 Seconds)'),
+(1787701, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 1, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Fhwoor - Script 2 - Say Line 6'),
+(1787701, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 50, 182082, 180, 0, 0, 0, 0, 8, 0, 0, 0, 249.717, 8482.185, 22.96521, 3.159062, 'Fhwoor - Script 2 - Summon The Ark of Ssslith');
+
+DELETE FROM `waypoints` WHERE `entry`IN(17877,18154,18088,18089);
+INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `point_comment`) VALUES
+(17877, 1, 213.6417, 8469.281, 23.52778, 'Fhwoor'),
+(17877, 2, 194.8211, 8448.552, 24.48719, 'Fhwoor'),
+(17877, 3, 181.9171, 8416.949, 23.39253, 'Fhwoor'),
+(17877, 4, 162.9771, 8387.255, 22.28007, 'Fhwoor'),
+(17877, 5, 169.1168, 8353.966, 21.07829, 'Fhwoor'),
+(17877, 6, 179.16, 8325.873, 20.83087, 'Fhwoor'),
+(17877, 7, 170.3557, 8302.857, 21.0235, 'Fhwoor'),
+(17877, 8, 182.7192, 8270.847, 18.91084, 'Fhwoor'),
+(17877, 9, 220.4595, 8241.914, 20.72861, 'Fhwoor'),
+(17877, 10, 248.3627, 8210.217, 19.54621, 'Fhwoor'),
+(17877, 11, 283.827, 8203.188, 22.15056, 'Fhwoor'),
+(17877, 12, 299.8667, 8188.261, 21.42571, 'Fhwoor'),
+(17877, 13, 318.4961, 8184.514, 18.0551, 'Fhwoor'),
+(17877, 14, 333.9666, 8178.852, 17.66307, 'Fhwoor'),
+(17877, 15, 349.5377, 8179.188, 18.45091, 'Fhwoor'),
+(17877, 16, 366.4365, 8187.577, 21.90989, 'Fhwoor'),
+(17877, 17, 378.7538, 8190.383, 23.30309, 'Fhwoor'),
+(17877, 18, 396.7187, 8184.856, 19.38158, 'Fhwoor'),
+(17877, 19, 416.5232, 8164.166, 18.35449, 'Fhwoor'),
+(17877, 20, 436.7097, 8153.245, 21.59639, 'Fhwoor'),
+(17877, 21, 451.9413, 8151.88, 23.76729, 'Fhwoor'),
+(17877, 22, 467.4153, 8152.104, 22.10491, 'Fhwoor'),
+(17877, 23, 485.0933, 8148.362, 20.20708, 'Fhwoor'),
+(17877, 24, 500.4597, 8146.723, 20.18372, 'Fhwoor'),
+(17877, 25, 517.5106, 8156.078, 22.14917, 'Fhwoor'),
+(17877, 26, 536.4334, 8157.974, 23.6155, 'Fhwoor'),
+(17877, 27, 558.9749, 8159.831, 23.83816, 'Fhwoor'),
+(17877, 28, 522.1965, 8135.454, 21.15369, 'Fhwoor'),
+(17877, 29, 498.0764, 8136.04, 20.90411, 'Fhwoor'),
+(17877, 30, 477.8418, 8127.26, 22.5633, 'Fhwoor'),
+(17877, 31, 450.433, 8131.167, 21.50137, 'Fhwoor'),
+(17877, 32, 431.7549, 8121.7, 18.242, 'Fhwoor'),
+(17877, 33, 416.2102, 8120.498, 17.59649, 'Fhwoor'),
+(17877, 34, 394.6256, 8120.143, 17.94713, 'Fhwoor'),
+(17877, 35, 379.7412, 8113.295, 17.7740, 'Fhwoor'),
+(17877, 36, 364.4443, 8105.485, 18.17426, 'Fhwoor'),
+(17877, 37, 350.215, 8106.762, 17.74799, 'Fhwoor'),
+(17877, 38, 335.0946, 8119.199, 17.49909, 'Fhwoor'),
+(17877, 39, 328.1111, 8135.518, 18.31635, 'Fhwoor'),
+(17877, 40, 305.7509, 8149.812, 20.04914, 'Fhwoor'),
+(17877, 41, 275.4078, 8161.027, 17.7491, 'Fhwoor'),
+(17877, 42, 247.4046, 8177.393, 17.72273, 'Fhwoor'),
+(17877, 43, 220.5886, 8180.784, 19.78761, 'Fhwoor'),
+(17877, 44, 205.7915, 8183.323, 23.08216, 'Fhwoor'),
+(17877, 45, 203.9108, 8206.521, 22.37668, 'Fhwoor'),
+(17877, 46, 200.2505, 8229.313, 24.96921, 'Fhwoor'),
+(17877, 47, 201.1895, 8251.09, 21.10947, 'Fhwoor'),
+(17877, 48, 190.4957, 8267.601, 18.47761, 'Fhwoor'),
+(17877, 49, 175.0741, 8288.405, 18.58564, 'Fhwoor'),
+(17877, 50, 182.4148, 8311.77, 21.29364, 'Fhwoor'),
+(17877, 51, 182.5205, 8333.074, 19.87689, 'Fhwoor'),
+(17877, 52, 175.5308, 8357.185, 18.46842, 'Fhwoor'),
+(17877, 53, 183.5543, 8381.03, 16.24468, 'Fhwoor'),
+(17877, 54, 195.2988, 8399.357, 16.50945, 'Fhwoor'),
+(17877, 55, 208.5941, 8413.654, 18.89419, 'Fhwoor'),
+(17877, 56, 221.3398, 8432.104, 20.17568, 'Fhwoor'),
+(17877, 57, 230.968, 8446.415, 21.99157, 'Fhwoor'),
+(17877, 58, 227.1291, 8465.446, 19.64525, 'Fhwoor'),
+(17877, 59, 231.5279, 8479.356, 17.87813, 'Fhwoor'),
+(17877, 60, 246.9482, 8481.803, 22.1418, 'Fhwoor'),
+(17877, 61, 231.4028, 8479.942, 18.03377, 'Fhwoor'),
+(18154, 1, 169.4304, 8210.07, 22.51478, 'Ssslith'),
+(18154, 2, 169.5868, 8209.083, 22.51478, 'Ssslith'),
+(18154, 3, 168.75, 8208.333, 22.80278, 'Ssslith'),
+(18154, 4, 168.0234, 8205.424, 23.42778, 'Ssslith'),
+(18154, 5, 167.709, 8204.166, 23.80278, 'Ssslith'),
+(18154, 6, 167.709, 8202.083, 23.80278, 'Ssslith'),
+(18154, 7, 167.709, 8200, 23.60022, 'Ssslith'),
+(18154, 8, 170.3105, 8196.961, 22.97522, 'Ssslith'),
+(18154, 9, 170.834, 8196.354, 22.85022, 'Ssslith'),
+(18154, 10, 171.2306, 8194.351, 22.48486, 'Ssslith'),
+(18154, 11, 182.8383, 8183.431, 23.90405, 'Ssslith'),
+(18154, 12, 188.6353, 8182.512, 23.86377, 'Ssslith'),
+(18088, 1, 172.8497, 8215.886, 22.30278, 'Bloodscale Enchantress'),
+(18088, 2, 172.8672, 8214.886, 22.30278, 'Bloodscale Enchantress'),
+(18088, 3, 172.0461, 8213.434, 22.35161, 'Bloodscale Enchantress'),
+(18088, 4, 176.9391, 8193.834, 23.09314, 'Bloodscale Enchantress'),
+(18088, 5, 181.4677, 8187.228, 23.00415, 'Bloodscale Enchantress'),
+(18088, 6, 185.6965, 8186.558, 23.32629, 'Bloodscale Enchantress'),
+(18089, 1, 166.6959, 8216.016, 22.55278, 'Bloodscale Slavedriver'),
+(18089, 2, 166.7656, 8215.018, 22.55278, 'Bloodscale Slavedriver'),
+(18089, 3, 165.9063, 8207.064, 23.10177, 'Bloodscale Slavedriver'),
+(18089, 4, 165.6914, 8205.076, 23.72677, 'Bloodscale Slavedriver'),
+(18089, 5, 164.922, 8197.819, 23.50668, 'Bloodscale Slavedriver'),
+(18089, 6, 172.0933, 8188.685, 22.47522, 'Bloodscale Slavedriver'),
+(18089, 7, 180.3612, 8180.244, 24.05603, 'Bloodscale Slavedriver'),
+(18089, 8, 184.59, 8179.574, 24.47522, 'Bloodscale Slavedriver');
diff --git a/sql/old/3.3.5a/world/60_2016_04_11/2016_04_05_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_05_00_world.sql
new file mode 100644
index 00000000000..f59e70ddb34
--- /dev/null
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_05_00_world.sql
@@ -0,0 +1,2 @@
+UPDATE `quest_template_addon` SET `RequiredMinRepValue`=42000 WHERE `ID`=9729;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=11937 AND `source_type`=0 AND `id`=1 AND `link`=0;
diff --git a/sql/old/3.3.5a/world/60_2016_04_11/2016_04_05_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_05_01_world.sql
new file mode 100644
index 00000000000..eb2609af74d
--- /dev/null
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_05_01_world.sql
@@ -0,0 +1,2 @@
+--
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceGroup`=1 AND `SourceEntry`=47320;
diff --git a/sql/old/3.3.5a/world/60_2016_04_11/2016_04_08_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_08_00_world.sql
new file mode 100644
index 00000000000..930e599396f
--- /dev/null
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_08_00_world.sql
@@ -0,0 +1,133 @@
+SET @CGUID := 78642;
+
+DELETE FROM `creature` WHERE `id` IN(17417,17418,17404,17405);
+INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `MovementType`) VALUES
+(@CGUID+0, 17417, 530, 1, 1, 214.6568, 4122.551, 79.8511, 2.251475, 120, 0, 0), -- 17417 (Area: 0) (possible waypoints or random movement)
+(@CGUID+1, 17417, 530, 1, 1, 216.0346, 4125.61, 80.22345, 2.251475, 120, 0, 0), -- 17417 (Area: 0) (possible waypoints or random movement)
+(@CGUID+2, 17404, 530, 1, 1, 211.6765, 4126.361, 79.04578, 2.391101, 120, 0, 0), -- 17404 (Area: 0) (possible waypoints or random movement)
+(@CGUID+3, 17418, 530, 1, 1, 261.5179, 4106.813, 93.315, 2.663978, 120, 0, 0), -- 17418 (Area: 0)
+(@CGUID+4, 17418, 530, 1, 1, 260.6302, 4103.529, 93.33371, 2.60972, 120, 0, 0), -- 17418 (Area: 0)
+(@CGUID+5, 17405, 530, 1, 1, 230.5075, 4118.714, 83.56195, 2.949606, 120, 0, 0); -- 17405 (Area: 0) (possible waypoints or random movement)
+
+UPDATE `creature` SET `equipment_id`=1 WHERE `id` IN(17417,17418,17404,17405);
+
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`IN(17413,17417,17404,17418,17405);
+
+DELETE FROM `smart_scripts` WHERE `entryorguid`IN(17413,17417,17404,17418,17405) AND `source_type`=0;
+
+DELETE FROM `smart_scripts` WHERE `entryorguid`IN(1740400,1740500) AND `source_type`=9;
+
+
+DELETE FROM `smart_scripts` WHERE `entryorguid`IN(-@CGUID-0,-@CGUID-1,-@CGUID-2,-@CGUID-3,-@CGUID-4,-@CGUID-5) 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
+(-@CGUID-0, 0, 0, 1, 11, 0, 100, 0, 0, 0, 0, 0, 18, 512, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mag har Escort (1) - On Respawn - Set Immune'),
+(-@CGUID-0, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mag har Escort (1) - On Respawn - Set Invisible'),
+(-@CGUID-0, 0, 1, 2, 38, 0, 100, 1, 1, 1, 0, 0, 19, 512, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mag har Escort (1) - On Data Set - Set Immune'),
+(-@CGUID-0, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mag har Escort (1) - On Data Set - Set visible'),
+(-@CGUID-0, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 53, 0, 1741700, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mag har Escort (1) - On Respawn - Start WP'),
+(-@CGUID-0, 0, 4, 5, 40, 0, 100, 0, 2, 1741700, 0, 0, 54, 5000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mag har Escort (1) - On Reached WP3 - Pause WP'),
+(-@CGUID-0, 0, 5, 6, 61, 0, 100, 0, 0, 0, 0, 0, 11, 30460, 2, 0, 0, 0, 0, 19, 17404, 0, 0, 0, 0, 0, 0, 'Mag har Escort (1) - On Reached WP3 - Cast Kick'),
+(-@CGUID-0, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 45, 2, 2, 0, 0, 0, 0, 19, 17404, 0, 0, 0, 0, 0, 0, 'Mag har Escort (1) - On Reached WP3 - Set Data on Sedei'),
+(-@CGUID-0, 0, 7, 8, 40, 0, 100, 0, 5, 1741700, 0, 0, 45, 3, 3, 0, 0, 0, 0, 10, @CGUID+3, 17418, 0, 0, 0, 0, 0, 'Mag har Escort (1) - On Reached WP6 - Start Attack'),
+(-@CGUID-0, 0, 8, 0, 61, 0, 100, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 10, @CGUID+3, 17418, 0, 0, 0, 0, 0, 'Mag har Escort (2) - On Reached WP12 - Start Attack'),
+(-@CGUID-0, 0, 9, 0, 0, 0, 100, 1, 3000, 3000, 0, 0, 45, 4, 4, 0, 0, 0, 0, 10, @CGUID+3, 17418, 0, 0, 0, 0, 0, 'Mag har Escort (2) - IC - Set Data'),
+
+(-@CGUID-1, 0, 0, 1, 11, 0, 100, 0, 0, 0, 0, 0, 18, 512, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mag har Escort (2) - On Respawn - Set Immune'),
+(-@CGUID-1, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mag har Escort (2) - On Respawn - Set Invisible'),
+(-@CGUID-1, 0, 1, 2, 38, 0, 100, 1, 1, 1, 0, 0, 19, 512, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mag har Escort (2) - On Data Set - Set Immune'),
+(-@CGUID-1, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mag har Escort (2) - On Data Set - Set visible'),
+(-@CGUID-1, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 53, 0, 1741701, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mag har Escort (2) - On Respawn - Start WP'),
+(-@CGUID-1, 0, 4, 5, 40, 0, 100, 0, 3, 1741701, 0, 0, 54, 5000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mag har Escort (2) - On Reached WP9 - Pause WP'),
+(-@CGUID-1, 0, 5, 0, 61, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mag har Escort (2) - On Reached WP9 - Say'),
+(-@CGUID-1, 0, 6, 7, 40, 0, 100, 0, 10, 1741701, 0, 0, 45, 3, 3, 0, 0, 0, 0, 10, @CGUID+4, 17418, 0, 0, 0, 0, 0, 'Mag har Escort (2) - On Reached WP12 - Start Attack'),
+(-@CGUID-1, 0, 7, 0, 61, 0, 100, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 10, @CGUID+4, 17418, 0, 0, 0, 0, 0, 'Mag har Escort (2) - On Reached WP12 - Start Attack'),
+(-@CGUID-1, 0, 8, 0, 0, 0, 100, 1, 3000, 3000, 0, 0, 45, 4, 4, 0, 0, 0, 0, 10, @CGUID+4, 17418, 0, 0, 0, 0, 0, 'Mag har Escort (2) - IC - Set Data'),
+
+(-@CGUID-2, 0, 0, 1, 11, 0, 100, 0, 0, 0, 0, 0, 18, 512, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Vindicator Sedai - On Respawn - Set Immune'),
+(-@CGUID-2, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Vindicator Sedai - On Respawn - Set Invisible'),
+(-@CGUID-2, 0, 1, 2, 38, 0, 100, 1, 1, 1, 0, 0, 19, 512, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Vindicator Sedai - On Data Set - Set Immune'),
+(-@CGUID-2, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Vindicator Sedai - On Data Set - Set visible'),
+(-@CGUID-2, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 53, 0, 17404, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Vindicator Sedai - On Respawn - Start WP'),
+(-@CGUID-2, 0, 4, 0, 38, 0, 100, 0, 2, 2, 0, 0, 80, 1740400, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Vindicator Sedai - On Data Set - Run Script'),
+(-@CGUID-2, 0, 5, 0, 40, 0, 100, 0, 3, 17404, 0, 0, 54, 21000, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Vindicator Sedai - On Reached WP3 - Pause WP'),
+(-@CGUID-2, 0, 6, 0, 40, 0, 100, 0, 5, 17404, 0, 0, 54, 18000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Vindicator Sedai - On Reached WP5 - Pause WP'),
+
+(-@CGUID-3, 0, 0, 1, 11, 0, 100, 0, 0, 0, 0, 0, 18, 512, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Laughing Skull Ambusher (1) - On Respawn - Set Immune'),
+(-@CGUID-3, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Laughing Skull Ambusher (1) - On Respawn - Set Invisible'),
+(-@CGUID-3, 0, 2, 3, 38, 0, 100, 1, 1, 1, 0, 0, 19, 512, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Laughing Skull Ambusher (1) - On Data Set - Set Immune'),
+(-@CGUID-3, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Laughing Skull Ambusher (1) - On Data Set - Set visible'),
+(-@CGUID-3, 0, 5, 0, 38, 0, 100, 0, 3, 3, 0, 0, 49, 0, 0, 0, 0, 0, 0, 19, 17417, 0, 0, 0, 0, 0, 0, 'Laughing Skull Ambusher (1) - On Data Set - Start Attack'),
+
+(-@CGUID-4, 0, 0, 1, 11, 0, 100, 0, 0, 0, 0, 0, 18, 512, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Laughing Skull Ambusher (2) - On Respawn - Set Immune'),
+(-@CGUID-4, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Laughing Skull Ambusher (2) - On Respawn - Set Invisible'),
+(-@CGUID-4, 0, 2, 3, 38, 0, 100, 1, 1, 1, 0, 0, 19, 512, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Laughing Skull Ambusher (2) - On Data Set - Set Immune'),
+(-@CGUID-4, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Laughing Skull Ambusher (2) - On Data Set - Set visible'),
+(-@CGUID-4, 0, 5, 0, 38, 0, 100, 0, 3, 3, 0, 0, 49, 0, 0, 0, 0, 0, 0, 19, 17417, 0, 0, 0, 0, 0, 0, 'Laughing Skull Ambusher (2) - On Data Set - Start Attack'),
+
+(-@CGUID-5, 0, 0, 1, 11, 0, 100, 0, 0, 0, 0, 0, 18, 512, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Krun Spinebreaker - On Respawn - Set Immune'),
+(-@CGUID-5, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Krun Spinebreaker - On Respawn - Set Invisible'),
+(-@CGUID-5, 0, 1, 2, 38, 0, 100, 1, 1, 1, 0, 0, 19, 512, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Krun Spinebreaker - On Data Set - Set Immune'),
+(-@CGUID-5, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Krun Spinebreaker - On Data Set - Set visible'),
+(-@CGUID-5, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 53, 1, 17405, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Krun Spinebreaker - On Respawn - Start WP'),
+(-@CGUID-5, 0, 4, 0, 40, 0, 100, 0, 3, 17405, 0, 0, 80, 1740500, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Krun Spinebreaker - On Reached WP3 - Run Script'),
+
+(1740400, 9, 0, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 45, 1, 1, 0, 0, 0, 0, 10, @CGUID+3, 17418, 0, 0, 0, 0, 0, 'Vindicator Sedai - Script - Set Data'),
+(1740400, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 10, @CGUID+4, 17418, 0, 0, 0, 0, 0, 'Vindicator Sedai - Script - Say'),
+(1740400, 9, 2, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Vindicator Sedai - Script - Say'),
+(1740400, 9, 3, 0, 0, 0, 100, 0, 15000, 15000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Vindicator Sedai - Script - Say'),
+(1740400, 9, 4, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Vindicator Sedai - Script - Say'),
+(1740400, 9, 5, 0, 0, 0, 100, 0, 18000, 18000, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Vindicator Sedai - Script - Say'),
+(1740400, 9, 6, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 45, 1, 1, 0, 0, 0, 0, 10, @CGUID+5, 17405, 0, 0, 0, 0, 0, 'Vindicator Sedai - Script - Say'),
+
+(1740500, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 11, 30462, 2, 0, 0, 0, 0, 19, 17404, 0, 0, 0, 0, 0, 0, 'Krun Spinebreaker - Script - Cast Execute Sedei'),
+(1740500, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Krun Spinebreaker - Script - Say'),
+(1740500, 9, 2, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 41, 0, 0, 0, 0, 0, 0, 10, @CGUID+0, 17417, 0, 0, 0, 0, 0, 'Krun Spinebreaker - Script - Despawn Mag har Escort'),
+(1740500, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 10, @CGUID+1, 17417, 0, 0, 0, 0, 0, 'Krun Spinebreaker - Script - Despawn Mag har Escort'),
+(1740500, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 10, @CGUID+2, 17404, 0, 0, 0, 0, 0, 'Krun Spinebreaker - Script - Despawn Vindicator Sedai'),
+(1740500, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 10, @CGUID+3, 17418, 0, 0, 0, 0, 0, 'Krun Spinebreaker - Script - Despawn Laughing Skull Ambusher'),
+(1740500, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 10, @CGUID+4, 17418, 0, 0, 0, 0, 0, 'Krun Spinebreaker - Script - Despawn'),
+(1740500, 9, 7, 0, 0, 0, 100, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Krun Spinebreaker - Script - Despawn'),
+
+(17413, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 10, @CGUID+0, 17417, 0, 0, 0, 0, 0, 'Sedai Quest Credit Marker - On Just Summoned - Set Data on Mag har Escort'),
+(17413, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 10, @CGUID+1, 17417, 0, 0, 0, 0, 0, 'Sedai Quest Credit Marker - On Just Summoned - Set Data on Mag har Escort'),
+(17413, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 10, @CGUID+2, 17404, 0, 0, 0, 0, 0, 'Sedai Quest Credit Marker - On Just Summoned - Set Data on Vindicator Sedei');
+
+
+DELETE FROM `waypoints` WHERE `entry`IN(17404,17405,1741700,1741701,1741800,1741801);
+INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `point_comment`) VALUES
+(1741700, 1, 206.7916, 4132.612, 77.49819, 'Mag har Escort (1)'),
+(1741700, 2, 199.061, 4142.329, 75.17587, 'Mag har Escort (1)'), -- Kick
+(1741700, 3, 203.75, 4134.571, 76.52649, 'Mag har Escort (1)'),
+(1741700, 4, 211.582, 4128.351, 79.12319, 'Mag har Escort (1)'),
+(1741700, 5, 219.5054, 4125.231, 80.99819, 'Mag har Escort (1)'),
+(1741701, 1, 206.2685, 4128.42, 77.62319, 'Mag har Escort (2)'),
+(1741701, 2, 200.5664, 4136.248, 75.65149, 'Mag har Escort (2)'),
+(1741701, 3, 196.179, 4141.198, 74.30087, 'Mag har Escort (2)'), -- say
+(1741701, 4, 203.9766, 4138.813, 76.40149, 'Mag har Escort (2)'),
+(1741701, 5, 206.5171, 4135.979, 77.40149, 'Mag har Escort (2)'),
+(1741701, 6, 209.2334, 4134.047, 78.15149, 'Mag har Escort (2)'),
+(1741701, 7, 209.2334, 4134.047, 78.15149, 'Mag har Escort (2)'),
+(1741701, 8, 211.4904, 4132.254, 79.12319, 'Mag har Escort (2)'),
+(1741701, 9, 214.5568, 4129.819, 79.74819, 'Mag har Escort (2)'),
+(1741701, 10, 219.3728, 4128.506, 81.12319, 'Mag har Escort (2)'),
+(17404, 1, 204.9158, 4134.23, 76.90149, 'Vindicator Sedai'),
+(17404, 2, 200.7516, 4138.94, 75.52649, 'Vindicator Sedai'),
+(17404, 3, 196.6698, 4143.903, 74.30087, 'Vindicator Sedai'), -- Event
+(17404, 4, 201.4514, 4139.023, 75.90149, 'Vindicator Sedai'),
+(17404, 5, 202.2026, 4138.024, 76.15149, 'Vindicator Sedai'),
+(17404, 6, 198.0219, 4143.623, 74.92587, 'Vindicator Sedai'),
+(17404, 7, 192.3438, 4150.61, 73.67587, 'Vindicator Sedai'),
+(17405, 1, 213.5774, 4129.949, 79.74819, 'Krun Spinebreaker'),
+(17405, 2, 203.9323, 4137.877, 76.40149, 'Krun Spinebreaker'),
+(17405, 3, 193.1504, 4149.705, 73.80087, 'Krun Spinebreaker'); -- Assasinate
+
+
+DELETE FROM `creature_text` WHERE `entry`IN(17417,17404,17405);
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
+(17417, 0, 0, 'Do not return, draenei scum. Next time we won''t spare your life, unarmed or not!', 12, 0, 100, 0, 0, 0, 13986, 0, 'Mag har Escort'), -- 21:04:49.000
+(17404, 0, 0, 'I''ve failed... peace is impossible.', 12, 0, 100, 0, 0, 0, 13982, 0, 'Vindicator Sedai'), -- 21:04:58.000
+(17404, 1, 0, 'What in the Light''s name...?', 12, 0, 100, 0, 0, 0, 13983, 0, 'Vindicator Sedai'), -- 21:05:13.000
+(17404, 2, 0, 'Fel orcs!', 12, 0, 100, 0, 0, 0, 13984, 0, 'Vindicator Sedai'), -- 21:05:18.000
+(17404, 3, 0, 'The cycle of bloodshed is unending... Is there nothing I can do?', 12, 0, 100, 0, 0, 0, 13985, 0, 'Vindicator Sedai'), -- 21:05:36.000
+(17405, 0, 0, 'You can die!', 12, 0, 100, 0, 0, 0, 13988, 0, 'Krun Spinebreaer'); -- 21:05:48.000
diff --git a/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_00_world_2016_03_28_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_00_world_2016_03_28_00_world.sql
new file mode 100644
index 00000000000..0fc505965a3
--- /dev/null
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_00_world_2016_03_28_00_world.sql
@@ -0,0 +1,3 @@
+DELETE FROM `trinity_string` WHERE `entry`=1030;
+INSERT INTO `trinity_string` (`entry`,`content_default`) VALUES
+(1030,'Account name cannot contain ''@'' character.');
diff --git a/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_01_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_01_world.sql
new file mode 100644
index 00000000000..0c01492d746
--- /dev/null
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_01_world.sql
@@ -0,0 +1,2 @@
+--
+DELETE FROM `creature_addon` WHERE `guid`=203496;
diff --git a/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_02_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_02_world.sql
new file mode 100644
index 00000000000..60ae64d1715
--- /dev/null
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_02_world.sql
@@ -0,0 +1,44 @@
+--
+/* Spell Bonus Data */
+-- Enchants
+DELETE FROM `spell_bonus_data` WHERE `entry` IN (6297,13897,13907,20004,20006,20007,28005,44525,44578,46579,64442,64569);
+INSERT INTO `spell_bonus_data` (`entry`,`direct_bonus`,`dot_bonus`,`ap_bonus`,`ap_dot_bonus`,`comments`) VALUES
+( 6297, 0, 0, -1, -1, 'Fiery Blaze'),
+(13897, 0, 0, -1, -1, 'Fiery Weapon - Fiery Weapon'),
+(13907, 0, 0, -1, -1, 'Demonslaying - Smite Demon'),
+(20004, 0, 0, -1, -1, 'Lifestealing - Life Steal'),
+(20006, 0, 0, -1, -1, 'Unholy Weapon - Unholy Curse'),
+(20007, 0, 0, -1, -1, 'Crusader - Holy Strength'),
+(28005, 0, 0, -1, -1, 'Battlemaster - Battlemaster'),
+(44525, 0, 0, -1, -1, 'Icebreaker - Icebreaker'),
+(44578, 0, 0, -1, -1, 'Lifeward - Lifeward'),
+(46579, 0, 0, -1, -1, 'Deathfrost - Deathfrost'),
+(64442, 0, 0, -1, -1, 'Blade Warding - Blade Warding'),
+(64569, 0, 0, -1, -1, 'Blood Draining - Blood Reserve');
+
+-- Items
+DELETE FROM `spell_bonus_data` WHERE `entry` IN (7712,7714,10577,16614,17484,18798,21992,27655,28788,38395,40972,55756,60526,67714,67760);
+INSERT INTO `spell_bonus_data` (`entry`,`direct_bonus`,`dot_bonus`,`ap_bonus`,`ap_dot_bonus`,`comments`) VALUES
+( 7712, 0, 0, -1, -1, 'Blazefury Medallion & Fiery Retributer (Fire Strike)'),
+( 7714, 0, 0, -1, -1, 'Fiery Plate Gauntlets (Fire Strike)'),
+(10577, 0, 0, -1, -1, 'Gauntlets of the Sea (Heal)'),
+(16614, 0, 0, -1, -1, 'Storm Gauntlets (Lightning Strike)'),
+(17484, 0, 0, -1, -1, 'Skullforge Reaver - Skullforge Brand'),
+(18798, 0, 0, -1, -1, 'Freezing Band (Freeze)'),
+(21992, 0, 0, -1, -1, 'Thunderfury'),
+(27655, 0, 0, -1, -1, 'Heart of Wyrmthalak (Flame Lash)'),
+(28788, 0, 0, -1, -1, 'Paladin T3 (8)'),
+(38395, 0, 0, -1, -1, 'Warlock - Siphon Essence - T6 2P proc'),
+(40972, 0, 0, -1, -1, 'Crystal Spire of Karabor - heal effect'),
+(55756, 0, 0, -1, -1, 'Brunnhildar weapons (Chilling Blow)'),
+(60526, 0, 0, -1, -1, 'Living Ice Crystals - heal effect'),
+(67714, 0, 0, -1, -1, 'Pillar of Flame (Normal)'),
+(67760, 0, 0, -1, -1, 'Pillar of Flame (Heroic)');
+
+-- Consumables
+DELETE FROM `spell_bonus_data` WHERE `entry` IN (28715,38616,43731,43733);
+INSERT INTO `spell_bonus_data` (`entry`,`direct_bonus`,`dot_bonus`,`ap_bonus`,`ap_dot_bonus`,`comments`) VALUES
+(28715, 0, 0, -1, -1, 'Consumable - Flamecap (Flamecap Fire)'),
+(38616, 0, 0, -1, -1, 'Poison - Bloodboil Poison'),
+(43731, 0, 0, -1, -1, 'Consumable - Stormchops (Lightning Zap)'),
+(43733, 0, 0, -1, -1, 'Consumable - Stormchops (Lightning Zap)');
diff --git a/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_03_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_03_world.sql
new file mode 100644
index 00000000000..732e3d83ee5
--- /dev/null
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_03_world.sql
@@ -0,0 +1,5 @@
+--
+DELETE FROM `player_factionchange_reputations` WHERE `alliance_id`= 589;
+INSERT INTO `player_factionchange_reputations` (`alliance_id`, `horde_id`) VALUES
+(589, 1137);
+UPDATE `creature` SET `equipment_id`=0 WHERE `id` IN(17404);
diff --git a/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_04_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_04_world.sql
new file mode 100644
index 00000000000..01154d2070a
--- /dev/null
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_04_world.sql
@@ -0,0 +1,9 @@
+--
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=17 AND `SourceEntry` IN (44550, 44610, 44609);
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(17, 0, 44550, 0, 0, 29, 0, 24820, 5, 0, 0, 0, 0, '', 'Allow spell Collect Data only on Iron Dwarf Relic 24820'),
+(17, 0, 44610, 0, 0, 29, 0, 24824, 5, 0, 0, 0, 0, '', 'Allow spell Collect Data only on Iron Dwarf Relics'),
+(17, 0, 44609, 0, 0, 29, 0, 24271, 10, 0, 0, 0, 0, '', 'Allow spell Bluff only on Iron Dwarf'),
+(17, 0, 44609, 0, 1, 29, 0, 23673, 10, 0, 0, 0, 0, '', 'Allow spell Bluff only on Iron Dwarf'),
+(17, 0, 44609, 0, 2, 29, 0, 23672, 10, 0, 0, 0, 0, '', 'Allow spell Bluff only on Iron Dwarf'),
+(17, 0, 44609, 0, 3, 29, 0, 23675, 10, 0, 0, 0, 0, '', 'Allow spell Bluff only on Iron Dwarf');
diff --git a/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_05_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_05_world.sql
new file mode 100644
index 00000000000..815540ecef1
--- /dev/null
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_09_05_world.sql
@@ -0,0 +1,41 @@
+--
+SET @Oguid:=65714;
+
+DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+29;
+INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES
+(@OGUID+0, 195256, 530, 1, 1, 1021.34, 7392.52, 36.3235, -2.79252, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+1, 195256, 530, 1, 1, 971.367, 7408.7, 29.5432, -1.25664, 0, 0, 0, 1, 180, 255, 1 ),
+(@OGUID+2, 195256, 530, 1, 1, 957.729, 7355.67, 29.1519, 0.436332, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+3, 195256, 530, 1, 1, 1006.33, 7322.55, 41.0474, -1.15192, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+4, 195256, 530, 1, 1, 1003.33, 7430, 28.0768, -0.925024, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+5, 195256, 530, 1, 1, 201.985, 8489.73, 24.4459, 0.645772, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+6, 195256, 530, 1, 1, 265.287, 8514.35, 23.5299, -2.60053, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+7, 195256, 530, 1, 1, 258.263, 8495.36, 23.4081, 2.16421, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+8, 195256, 530, 1, 1, 276.203, 6122.65, 142.509, -0.95993, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+9, 195256, 530, 1, 1, -208.633, 5388.65, 22.9273, -1.72787, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+10,195256, 530, 1, 1, -87.5959, 5535.55, 22.807, 0.575957, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+11,195256, 530, 1, 1, -192.623, 5531.5, 29.4519, -2.51327, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+12,195256, 530, 1, 1, -702.011, 2676.55, 93.484, 1.72787, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+13,195256, 530, 1, 1, -684.19, 2664.04, 90.9786, 0.506145, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+14,195256, 530, 1, 1, -708.662, 2640.04, 91.8499, -2.14675, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+15,195256, 530, 1, 1, -714.397, 2671.54, 93.9279, 2.23402, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+16,195256, 530, 1, 1, -696.738, 4172.8, 58.3883, 1.90241, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+17,195256, 530, 1, 1, -646.139, 4161.18, 66.1437, -2.58308, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+18,195256, 530, 1, 1, -597.076, 4097.25, 91.2013, 2.40855, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+19,195256, 530, 1, 1, -594.825, 4161.75, 65.7298, 2.47837, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+20,195256, 530, 1, 1, -661.823, 4157.85, 66.0003, -0.506145, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+21,195256, 530, 1, 1, -614.866, 4105.14, 90.6122, -0.453785, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+22,195256, 530, 1, 1, -685.76, 4176.18, 57.4531, 1.93731, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+23,195256, 530, 1, 1, -597.71, 4154.32, 65.3473, 2.65289, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+24,195256, 530, 1, 1, -2024.57, 5470.97, 3.92836, -0.296705, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+25,195256, 530, 1, 1, -1809.99, 5404.19, -12.5532, 1.95477, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+26,195256, 530, 1, 1, -2001.4, 5370.28, -8.0344, -2.32129, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+27,195256, 530, 1, 1, -1994.43, 5356.16, -8.06764, -2.93214, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+28,195256, 530, 1, 1, -1896.71, 5355.26, -12.4279, 1.01229, 0, 0, 0, 1, 180, 255, 1),
+(@OGUID+29,195256, 530, 1, 1, -1942.76, 5448.9, -12.428, 0.034906, 0, 0, 0, 1, 180, 255, 1);
+
+DELETE FROM `game_event_gameobject` WHERE `guid` BETWEEN 80000 AND 80029 AND `eventEntry`=24;
+
+SET @Event:=24;
+DELETE FROM `game_event_gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+29 AND `eventEntry`=24;
+INSERT INTO `game_event_gameobject` SELECT @Event, gameobject.guid FROM `gameobject` WHERE gameobject.guid BETWEEN @OGUID+0 AND @OGUID+29;
diff --git a/sql/old/3.3.5a/world/60_2016_04_11/2016_04_10_00_world.sql b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_10_00_world.sql
new file mode 100644
index 00000000000..d5c24c4a65d
--- /dev/null
+++ b/sql/old/3.3.5a/world/60_2016_04_11/2016_04_10_00_world.sql
@@ -0,0 +1,20 @@
+UPDATE `creature` SET `unit_flags`=33587968 WHERE `guid`IN(53208,53209,53210,53617,53586,53229,53711,53230,53710);
+
+DELETE FROM `creature_addon` WHERE `guid` IN(53208,53209,53210,53210,53617,53586,53229,53711,53230,53710);
+INSERT INTO `creature_addon` (`guid`, `mount`, `bytes1`, `bytes2`, `auras`) VALUES
+(53208, 0, 0x7, 0x1, ''), -- 23232 - 41290 - 41290
+(53209, 0, 0x7, 0x1, ''), -- 23232 - 41290 - 41290
+(53210, 0, 0x7, 0x1, ''), -- 23232 - 41290 - 41290
+(53617, 0, 0x7, 0x1, ''), -- 23236
+(53586, 0, 0x7, 0x1, ''), -- 23236
+(53229, 0, 0x7, 0x1, ''), -- 23235
+(53711, 0, 0x7, 0x1, ''), -- 23237
+(53230, 0, 0x7, 0x1, ''), -- 23235
+(53710, 0, 0x7, 0x1, ''); -- 23237
+
+UPDATE `creature_template` SET `ainame`='SmartAI', `scriptname`='' WHERE `entry` IN(23232);
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN(23232) 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
+(23232, 0, 0, 0, 25, 0, 100, 0, 0, 0, 0, 0, 11, 41290, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mutant War Hound - On Reset - Cast Disease Cloud'),
+(23232, 0, 1, 0, 6, 0, 100, 0, 0, 0, 0, 0, 11, 41193, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mutant War Hound - On Death - Cast Cloud of Disease');
diff --git a/sql/updates/auth/2016_04_11_00_auth.sql b/sql/updates/auth/2016_04_11_00_auth.sql
new file mode 100644
index 00000000000..be8a4d21b66
--- /dev/null
+++ b/sql/updates/auth/2016_04_11_00_auth.sql
@@ -0,0 +1 @@
+UPDATE `updates` SET `state`='ARCHIVED';
diff --git a/sql/updates/characters/2016_04_11_00_characters.sql b/sql/updates/characters/2016_04_11_00_characters.sql
new file mode 100644
index 00000000000..be8a4d21b66
--- /dev/null
+++ b/sql/updates/characters/2016_04_11_00_characters.sql
@@ -0,0 +1 @@
+UPDATE `updates` SET `state`='ARCHIVED';
diff --git a/sql/updates/world/2016_04_11_00_world.sql b/sql/updates/world/2016_04_11_00_world.sql
new file mode 100644
index 00000000000..2f8d539fe43
--- /dev/null
+++ b/sql/updates/world/2016_04_11_00_world.sql
@@ -0,0 +1,3 @@
+UPDATE `version` SET `db_version`='TDB 335.61', `cache_id`=61 LIMIT 1;
+
+UPDATE `updates` SET `state`='ARCHIVED';
diff --git a/sql/updates/world/2016_04_11_01_world_335.sql b/sql/updates/world/2016_04_11_01_world_335.sql
new file mode 100644
index 00000000000..a432307d0b1
--- /dev/null
+++ b/sql/updates/world/2016_04_11_01_world_335.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `gameobject` SET `spawntimesecs` = 5 WHERE `guid` IN (45719, 45720, 45721);
diff --git a/sql/updates/world/2016_04_11_02_world_335.sql b/sql/updates/world/2016_04_11_02_world_335.sql
new file mode 100644
index 00000000000..93b6000554c
--- /dev/null
+++ b/sql/updates/world/2016_04_11_02_world_335.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `spell_group` SET `spell_id`=56112 WHERE `id`=1061 and`spell_id`=46910;
diff --git a/sql/updates/world/2016_04_15_03_world_335.sql b/sql/updates/world/2016_04_15_03_world_335.sql
new file mode 100644
index 00000000000..afbe3b3ab63
--- /dev/null
+++ b/sql/updates/world/2016_04_15_03_world_335.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `smart_scripts` SET `action_type`=51, `action_param1`=0 WHERE `entryorguid`=193100 AND `source_type`=9 AND `id`=7;
diff --git a/sql/updates/world/dummy b/sql/updates/world/dummy
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/sql/updates/world/dummy
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 4250df6d1f1..0428738f2dd 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -33,8 +33,8 @@ GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
add_definitions(-DTRINITY_API_EXPORT_COMMON)
add_library(common
- ${PRIVATE_SOURCES}
${PRIVATE_PCH_SOURCE}
+ ${PRIVATE_SOURCES}
)
# Do NOT add any extra include directory here, as we don't want the common
@@ -71,7 +71,9 @@ target_link_libraries(common
openssl
valgrind
threads
- jemalloc)
+ jemalloc
+ PRIVATE
+ process)
add_dependencies(common revision_data.h)
diff --git a/src/common/Collision/Management/MMapManager.h b/src/common/Collision/Management/MMapManager.h
index afb693553a4..a8d792296bb 100644
--- a/src/common/Collision/Management/MMapManager.h
+++ b/src/common/Collision/Management/MMapManager.h
@@ -75,7 +75,7 @@ namespace MMAP
dtNavMesh const* GetNavMesh(uint32 mapId);
uint32 getLoadedTilesCount() const { return loadedTiles; }
- uint32 getLoadedMapsCount() const { return loadedMMaps.size(); }
+ uint32 getLoadedMapsCount() const { return uint32(loadedMMaps.size()); }
private:
bool loadMapData(uint32 mapId);
uint32 packTileID(int32 x, int32 y);
diff --git a/src/common/Common.h b/src/common/Common.h
index 4ab5ae867b9..aa04abacd30 100644
--- a/src/common/Common.h
+++ b/src/common/Common.h
@@ -21,28 +21,31 @@
#include "Define.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <cmath>
-#include <errno.h>
-#include <signal.h>
-#include <assert.h>
-
-#include <set>
-#include <unordered_set>
+#include <algorithm>
+#include <array>
+#include <exception>
#include <list>
-#include <string>
#include <map>
-#include <unordered_map>
+#include <memory>
#include <queue>
+#include <set>
#include <sstream>
-#include <algorithm>
-#include <memory>
+#include <string>
+#include <type_traits>
+#include <unordered_map>
+#include <unordered_set>
#include <vector>
-#include <array>
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <cerrno>
+#include <csignal>
+
+#include <boost/optional.hpp>
+#include <boost/utility/in_place_factory.hpp>
#include <boost/functional/hash.hpp>
#include "Debugging/Errors.h"
@@ -151,6 +154,10 @@ typedef std::vector<std::string> StringVector;
#define MAX_QUERY_LEN 32*1024
+//! Optional helper class to wrap optional values within.
+template <typename T>
+using Optional = boost::optional<T>;
+
namespace Trinity
{
//! std::make_unique implementation (TODO: remove this once C++14 is supported)
diff --git a/src/common/Logging/Appender.h b/src/common/Logging/Appender.h
index 22fe1112239..d24daa2b60d 100644
--- a/src/common/Logging/Appender.h
+++ b/src/common/Logging/Appender.h
@@ -41,7 +41,7 @@ enum LogLevel
const uint8 MaxLogLevels = 6;
-enum AppenderType
+enum AppenderType : uint8
{
APPENDER_NONE,
APPENDER_CONSOLE,
diff --git a/src/common/Utilities/EventMap.h b/src/common/Utilities/EventMap.h
index bb40980181d..6a314a9e633 100644
--- a/src/common/Utilities/EventMap.h
+++ b/src/common/Utilities/EventMap.h
@@ -122,7 +122,7 @@ public:
*/
void ScheduleEvent(uint32 eventId, Milliseconds const& time, uint32 group = 0, uint8 phase = 0)
{
- ScheduleEvent(eventId, time.count(), group, phase);
+ ScheduleEvent(eventId, uint32(time.count()), group, phase);
}
/**
@@ -145,7 +145,7 @@ public:
*/
void RescheduleEvent(uint32 eventId, Milliseconds const& time, uint32 group = 0, uint8 phase = 0)
{
- RescheduleEvent(eventId, time.count(), group, phase);
+ RescheduleEvent(eventId, uint32(time.count()), group, phase);
}
/**
@@ -169,7 +169,7 @@ public:
*/
void Repeat(Milliseconds const& time)
{
- Repeat(time.count());
+ Repeat(uint32(time.count()));
}
/**
@@ -190,7 +190,7 @@ public:
*/
void Repeat(Milliseconds const& minTime, Milliseconds const& maxTime)
{
- Repeat(minTime.count(), maxTime.count());
+ Repeat(uint32(minTime.count()), uint32(maxTime.count()));
}
/**
@@ -218,7 +218,7 @@ public:
*/
void DelayEvents(Milliseconds const& delay)
{
- DelayEvents(delay.count());
+ DelayEvents(uint32(delay.count()));
}
/**
@@ -239,7 +239,7 @@ public:
*/
void DelayEvents(Milliseconds const& delay, uint32 group)
{
- DelayEvents(delay.count(), group);
+ DelayEvents(uint32(delay.count()), group);
}
/**
diff --git a/src/server/shared/Networking/MessageBuffer.h b/src/common/Utilities/MessageBuffer.h
index d68bee181b1..d08c4b25bab 100644
--- a/src/server/shared/Networking/MessageBuffer.h
+++ b/src/common/Utilities/MessageBuffer.h
@@ -20,6 +20,7 @@
#include "Define.h"
#include <vector>
+#include <cstring>
class MessageBuffer
{
diff --git a/src/common/Utilities/StartProcess.cpp b/src/common/Utilities/StartProcess.cpp
new file mode 100644
index 00000000000..c47c02bbe87
--- /dev/null
+++ b/src/common/Utilities/StartProcess.cpp
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "StartProcess.h"
+
+#include <atomic>
+#include <thread>
+#include <functional>
+
+#include <boost/algorithm/string/join.hpp>
+#include <boost/iostreams/stream.hpp>
+#include <boost/iostreams/copy.hpp>
+#include <boost/iostreams/concepts.hpp>
+#include <boost/iostreams/device/file_descriptor.hpp>
+#include <boost/process.hpp>
+#include <boost/system/system_error.hpp>
+
+#include "Common.h"
+#include "Log.h"
+
+using namespace boost::process;
+using namespace boost::process::initializers;
+using namespace boost::iostreams;
+
+namespace Trinity {
+
+template<typename T>
+class TCLogSink
+{
+ T callback_;
+
+public:
+ typedef char char_type;
+ typedef sink_tag category;
+
+ // Requires a callback type which has a void(std::string) signature
+ TCLogSink(T callback)
+ : callback_(std::move(callback)) { }
+
+ std::streamsize write(const char* str, std::streamsize size)
+ {
+ callback_(std::string(str, size));
+ return size;
+ }
+};
+
+template<typename T>
+auto MakeTCLogSink(T&& callback)
+ -> TCLogSink<typename std::decay<T>::type>
+{
+ return { std::forward<T>(callback) };
+}
+
+template<typename T>
+static int CreateChildProcess(T waiter, std::string const& executable,
+ std::vector<std::string> const& args,
+ std::string const& logger, std::string const& input,
+ bool secure)
+{
+ auto outPipe = create_pipe();
+ auto errPipe = create_pipe();
+
+ Optional<file_descriptor_source> inputSource;
+
+ if (!secure)
+ {
+ TC_LOG_TRACE(logger.c_str(), "Starting process \"%s\" with arguments: \"%s\".",
+ executable.c_str(), boost::algorithm::join(args, " ").c_str());
+ }
+
+ // Start the child process
+ child c = [&]
+ {
+ if (!input.empty())
+ {
+ inputSource = file_descriptor_source(input);
+
+ // With binding stdin
+ return execute(run_exe(boost::filesystem::absolute(executable)),
+ set_args(args),
+ bind_stdin(*inputSource),
+ bind_stdout(file_descriptor_sink(outPipe.sink, close_handle)),
+ bind_stderr(file_descriptor_sink(errPipe.sink, close_handle)));
+ }
+ else
+ {
+ // Without binding stdin
+ return execute(run_exe(boost::filesystem::absolute(executable)),
+ set_args(args),
+ bind_stdout(file_descriptor_sink(outPipe.sink, close_handle)),
+ bind_stderr(file_descriptor_sink(errPipe.sink, close_handle)));
+ }
+ }();
+
+ file_descriptor_source outFd(outPipe.source, close_handle);
+ file_descriptor_source errFd(errPipe.source, close_handle);
+
+ auto outInfo = MakeTCLogSink([&](std::string msg)
+ {
+ TC_LOG_INFO(logger.c_str(), "%s", msg.c_str());
+ });
+
+ auto outError = MakeTCLogSink([&](std::string msg)
+ {
+ TC_LOG_ERROR(logger.c_str(), "%s", msg.c_str());
+ });
+
+ copy(outFd, outInfo);
+ copy(errFd, outError);
+
+ // Call the waiter in the current scope to prevent
+ // the streams from closing too early on leaving the scope.
+ int const result = waiter(c);
+
+ if (!secure)
+ {
+ TC_LOG_TRACE(logger.c_str(), ">> Process \"%s\" finished with return value %i.",
+ executable.c_str(), result);
+ }
+
+ if (inputSource)
+ inputSource->close();
+
+ return result;
+}
+
+int StartProcess(std::string const& executable, std::vector<std::string> const& args,
+ std::string const& logger, std::string input_file, bool secure)
+{
+ return CreateChildProcess([](child& c) -> int
+ {
+ try
+ {
+ return wait_for_exit(c);
+ }
+ catch (...)
+ {
+ return EXIT_FAILURE;
+ }
+ }, executable, args, logger, input_file, secure);
+}
+
+class AsyncProcessResultImplementation
+ : public AsyncProcessResult
+{
+ std::string const executable;
+ std::vector<std::string> const args;
+ std::string const logger;
+ std::string const input_file;
+ bool const is_secure;
+
+ std::atomic<bool> was_terminated;
+
+ // Workaround for missing move support in boost < 1.57
+ Optional<std::shared_ptr<std::future<int>>> result;
+ Optional<std::reference_wrapper<child>> my_child;
+
+public:
+ explicit AsyncProcessResultImplementation(std::string executable_, std::vector<std::string> args_,
+ std::string logger_, std::string input_file_,
+ bool secure)
+ : executable(std::move(executable_)), args(std::move(args_)),
+ logger(std::move(logger_)), input_file(input_file_),
+ is_secure(secure), was_terminated(false) { }
+
+ AsyncProcessResultImplementation(AsyncProcessResultImplementation const&) = delete;
+ AsyncProcessResultImplementation& operator= (AsyncProcessResultImplementation const&) = delete;
+ AsyncProcessResultImplementation(AsyncProcessResultImplementation&&) = delete;
+ AsyncProcessResultImplementation& operator= (AsyncProcessResultImplementation&&) = delete;
+
+ int StartProcess()
+ {
+ ASSERT(!my_child, "Process started already!");
+
+ return CreateChildProcess([&](child& c) -> int
+ {
+ int result;
+ my_child = std::reference_wrapper<child>(c);
+
+ try
+ {
+ result = wait_for_exit(c);
+ }
+ catch (...)
+ {
+ result = EXIT_FAILURE;
+ }
+
+ my_child.reset();
+ return was_terminated ? EXIT_FAILURE : result;
+
+ }, executable, args, logger, input_file, is_secure);
+ }
+
+ void SetFuture(std::future<int> result_)
+ {
+ result = std::make_shared<std::future<int>>(std::move(result_));
+ }
+
+ /// Returns the future which contains the result of the process
+ /// as soon it is finished.
+ std::future<int>& GetFutureResult() override
+ {
+ ASSERT(*result, "The process wasn't started!");
+ return **result;
+ }
+
+ /// Tries to terminate the process
+ void Terminate() override
+ {
+ if (!my_child)
+ {
+ was_terminated = true;
+ try
+ {
+ terminate(my_child->get());
+ }
+ catch(...)
+ {
+ // Do nothing
+ }
+ }
+ }
+};
+
+TC_COMMON_API std::shared_ptr<AsyncProcessResult>
+ StartAsyncProcess(std::string executable, std::vector<std::string> args,
+ std::string logger, std::string input_file, bool secure)
+{
+ auto handle = std::make_shared<AsyncProcessResultImplementation>(
+ std::move(executable), std::move(args), std::move(logger), std::move(input_file), secure);
+
+ handle->SetFuture(std::async(std::launch::async, [handle] { return handle->StartProcess(); }));
+ return handle;
+}
+
+Optional<std::string> SearchExecutableInPath(std::string const& filename)
+{
+ try
+ {
+ auto result = search_path(filename);
+ if (result.empty())
+ return boost::none;
+ else
+ return result;
+ }
+ catch (...)
+ {
+ return boost::none;
+ }
+}
+
+} // namespace Trinity
diff --git a/src/common/Utilities/StartProcess.h b/src/common/Utilities/StartProcess.h
new file mode 100644
index 00000000000..3b380bd4f4e
--- /dev/null
+++ b/src/common/Utilities/StartProcess.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef Process_h__
+#define Process_h__
+
+#include <future>
+#include <memory>
+#include "Common.h"
+
+namespace Trinity {
+
+/// Starts a process with the given arguments and parameters and will block
+/// until the process is finished.
+/// When an input path is given, the file will be routed to the processes stdin.
+/// When the process is marked as secure no arguments are leaked to logs.
+/// Note that most executables expect it's name as the first argument.
+TC_COMMON_API int StartProcess(std::string const& executable, std::vector<std::string> const& args,
+ std::string const& logger, std::string input_file = "",
+ bool secure = false);
+
+/// Platform and library independent representation
+/// of asynchronous process results
+class AsyncProcessResult
+{
+public:
+ virtual ~AsyncProcessResult() { }
+
+ /// Returns the future which contains the result of the process
+ /// as soon it is finished.
+ virtual std::future<int>& GetFutureResult() = 0;
+
+ /// Tries to terminate the process
+ virtual void Terminate() = 0;
+};
+
+/// Starts a process asynchronously with the given arguments and parameters and
+/// returns an AsyncProcessResult immediately which is set, when the process exits.
+/// When an input path is given, the file will be routed to the processes stdin.
+/// When the process is marked as secure no arguments are leaked to logs.
+/// Note that most executables expect it's name as the first argument.
+TC_COMMON_API std::shared_ptr<AsyncProcessResult>
+ StartAsyncProcess(std::string executable, std::vector<std::string> args,
+ std::string logger, std::string input_file = "",
+ bool secure = false);
+
+/// Searches for the given executable in the PATH variable
+/// and returns a present optional when it was found.
+TC_COMMON_API Optional<std::string> SearchExecutableInPath(std::string const& filename);
+
+} // namespace Trinity
+
+#endif // Process_h__
diff --git a/src/common/Utilities/TaskScheduler.h b/src/common/Utilities/TaskScheduler.h
index c5163ef33d5..6784c968683 100644
--- a/src/common/Utilities/TaskScheduler.h
+++ b/src/common/Utilities/TaskScheduler.h
@@ -401,7 +401,7 @@ private:
auto const milli_max = std::chrono::duration_cast<std::chrono::milliseconds>(max);
// TC specific: use SFMT URandom
- return std::chrono::milliseconds(urand(milli_min.count(), milli_max.count()));
+ return std::chrono::milliseconds(urand(uint32(milli_min.count()), uint32(milli_max.count())));
}
/// Dispatch remaining tasks
diff --git a/src/common/Utilities/Util.cpp b/src/common/Utilities/Util.cpp
index 6572280d00b..3d8cda66d48 100644
--- a/src/common/Utilities/Util.cpp
+++ b/src/common/Utilities/Util.cpp
@@ -22,6 +22,7 @@
#include "utf8.h"
#include "Errors.h" // for ASSERT
#include <stdarg.h>
+#include <boost/algorithm/string/case_conv.hpp>
#if COMPILER == COMPILER_GNU
#include <sys/socket.h>
@@ -425,7 +426,7 @@ bool utf8ToConsole(const std::string& utf8str, std::string& conStr)
return false;
conStr.resize(wstr.size());
- CharToOemBuffW(&wstr[0], &conStr[0], wstr.size());
+ CharToOemBuffW(&wstr[0], &conStr[0], uint32(wstr.size()));
#else
// not implemented yet
conStr = utf8str;
@@ -439,7 +440,7 @@ bool consoleToUtf8(const std::string& conStr, std::string& utf8str)
#if PLATFORM == PLATFORM_WINDOWS
std::wstring wstr;
wstr.resize(conStr.size());
- OemToCharBuffW(&conStr[0], &wstr[0], conStr.size());
+ OemToCharBuffW(&conStr[0], &wstr[0], uint32(conStr.size()));
return WStrToUtf8(wstr, utf8str);
#else
@@ -457,7 +458,7 @@ bool Utf8FitTo(const std::string& str, std::wstring const& search)
return false;
// converting to lower case
- wstrToLower( temp );
+ wstrToLower(temp);
if (temp.find(search) == std::wstring::npos)
return false;
@@ -476,10 +477,10 @@ void utf8printf(FILE* out, const char *str, ...)
void vutf8printf(FILE* out, const char *str, va_list* ap)
{
#if PLATFORM == PLATFORM_WINDOWS
- char temp_buf[32*1024];
- wchar_t wtemp_buf[32*1024];
+ char temp_buf[32 * 1024];
+ wchar_t wtemp_buf[32 * 1024];
- size_t temp_len = vsnprintf(temp_buf, 32*1024, str, *ap);
+ size_t temp_len = vsnprintf(temp_buf, 32 * 1024, str, *ap);
//vsnprintf returns -1 if the buffer is too small
if (temp_len == size_t(-1))
temp_len = 32*1024-1;
@@ -487,7 +488,7 @@ void vutf8printf(FILE* out, const char *str, va_list* ap)
size_t wtemp_len = 32*1024-1;
Utf8toWStr(temp_buf, temp_len, wtemp_buf, wtemp_len);
- CharToOemBuffW(&wtemp_buf[0], &temp_buf[0], wtemp_len+1);
+ CharToOemBuffW(&wtemp_buf[0], &temp_buf[0], uint32(wtemp_len + 1));
fprintf(out, "%s", temp_buf);
#else
vfprintf(out, str, *ap);
@@ -528,3 +529,34 @@ std::string ByteArrayToHexStr(uint8 const* bytes, uint32 arrayLen, bool reverse
return ss.str();
}
+
+void HexStrToByteArray(std::string const& str, uint8* out, bool reverse /*= false*/)
+{
+ // string must have even number of characters
+ if (str.length() & 1)
+ return;
+
+ int32 init = 0;
+ int32 end = int32(str.length());
+ int8 op = 1;
+
+ if (reverse)
+ {
+ init = int32(str.length() - 2);
+ end = -2;
+ op = -1;
+ }
+
+ uint32 j = 0;
+ for (int32 i = init; i != end; i += 2 * op)
+ {
+ char buffer[3] = { str[i], str[i + 1], '\0' };
+ out[j++] = uint8(strtoul(buffer, NULL, 16));
+ }
+}
+
+bool StringToBool(std::string const& str)
+{
+ std::string lowerStr = boost::algorithm::to_lower_copy(str);
+ return lowerStr == "1" || lowerStr == "true" || lowerStr == "yes";
+}
diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h
index cd0a8bae823..cc68f3b2237 100644
--- a/src/common/Utilities/Util.h
+++ b/src/common/Utilities/Util.h
@@ -318,6 +318,9 @@ TC_COMMON_API uint32 CreatePIDFile(std::string const& filename);
TC_COMMON_API uint32 GetPID();
TC_COMMON_API std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false);
+TC_COMMON_API void HexStrToByteArray(std::string const& str, uint8* out, bool reverse = false);
+
+TC_COMMON_API bool StringToBool(std::string const& str);
// simple class for not-modifyable list
template <typename T>
diff --git a/src/server/authserver/CMakeLists.txt b/src/server/authserver/CMakeLists.txt
index 1d40129ec1b..d1f0e4460e9 100644
--- a/src/server/authserver/CMakeLists.txt
+++ b/src/server/authserver/CMakeLists.txt
@@ -31,8 +31,8 @@ endif()
GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
add_executable(authserver
- ${PRIVATE_SOURCES}
${PRIVATE_PCH_SOURCE}
+ ${PRIVATE_SOURCES}
)
if( NOT WIN32 )
diff --git a/src/server/authserver/Server/AuthSession.cpp b/src/server/authserver/Server/AuthSession.cpp
index 982aca58eee..f044e0cea94 100644
--- a/src/server/authserver/Server/AuthSession.cpp
+++ b/src/server/authserver/Server/AuthSession.cpp
@@ -924,7 +924,7 @@ void AuthSession::RealmListCallback(PreparedQueryResult result)
pkt << uint8(lock); // if 1, then realm locked
pkt << uint8(flag); // RealmFlags
pkt << name;
- pkt << boost::lexical_cast<std::string>(GetAddressForClient(realm, GetRemoteIpAddress()));
+ pkt << boost::lexical_cast<std::string>(realm.GetAddressForClient(GetRemoteIpAddress()));
pkt << float(realm.PopulationLevel);
pkt << uint8(characterCounts[realm.Id.Realm]);
pkt << uint8(realm.Timezone); // realm category
diff --git a/src/server/authserver/authserver.conf.dist b/src/server/authserver/authserver.conf.dist
index a97d75b3f57..db60e3b3ece 100644
--- a/src/server/authserver/authserver.conf.dist
+++ b/src/server/authserver/authserver.conf.dist
@@ -184,6 +184,13 @@ LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;auth"
LoginDatabase.WorkerThreads = 1
#
+# LoginDatabase.SynchThreads
+# Description: The amount of MySQL connections spawned to handle.
+# Default: 1 - (LoginDatabase.WorkerThreads)
+
+LoginDatabase.SynchThreads = 1
+
+#
###################################################################################################
###################################################################################################
diff --git a/src/server/database/CMakeLists.txt b/src/server/database/CMakeLists.txt
index 06772cd5309..bd2fa280ad6 100644
--- a/src/server/database/CMakeLists.txt
+++ b/src/server/database/CMakeLists.txt
@@ -22,8 +22,8 @@ endif()
GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
add_library(database
- ${PRIVATE_SOURCES}
${PRIVATE_PCH_SOURCE}
+ ${PRIVATE_SOURCES}
)
# Do NOT add any extra include directory unless it does not create unneeded extra dependencies,
@@ -52,7 +52,6 @@ add_definitions(-DTRINITY_API_EXPORT_DATABASE)
target_link_libraries(database
PUBLIC
common
- process
mysql)
set_target_properties(database
diff --git a/src/server/database/Database/DatabaseWorkerPool.cpp b/src/server/database/Database/DatabaseWorkerPool.cpp
index 087a35682aa..ba2a4256919 100644
--- a/src/server/database/Database/DatabaseWorkerPool.cpp
+++ b/src/server/database/Database/DatabaseWorkerPool.cpp
@@ -234,7 +234,7 @@ void DatabaseWorkerPool<T>::EscapeString(std::string& str)
return;
char* buf = new char[str.size() * 2 + 1];
- EscapeString(buf, str.c_str(), str.size());
+ EscapeString(buf, str.c_str(), uint32(str.size()));
str = buf;
delete[] buf;
}
diff --git a/src/server/database/Database/Field.h b/src/server/database/Database/Field.h
index fd4ddc79450..123e25dbbf3 100644
--- a/src/server/database/Database/Field.h
+++ b/src/server/database/Database/Field.h
@@ -323,7 +323,7 @@ class TC_DATABASE_API Field
data.value = NULL;
}
- static size_t SizeForType(MYSQL_FIELD* field)
+ static uint32 SizeForType(MYSQL_FIELD* field)
{
switch (field->type)
{
diff --git a/src/server/database/Database/PreparedStatement.cpp b/src/server/database/Database/PreparedStatement.cpp
index 848a923c75d..119f1d4c93b 100644
--- a/src/server/database/Database/PreparedStatement.cpp
+++ b/src/server/database/Database/PreparedStatement.cpp
@@ -344,7 +344,7 @@ void MySQLPreparedStatement::setString(const uint8 index, const char* value)
CheckValidIndex(index);
m_paramsSet[index] = true;
MYSQL_BIND* param = &m_bind[index];
- size_t len = strlen(value) + 1;
+ uint32 len = uint32(strlen(value) + 1);
param->buffer_type = MYSQL_TYPE_VAR_STRING;
delete [] static_cast<char *>(param->buffer);
param->buffer = new char[len];
diff --git a/src/server/database/Database/QueryResult.cpp b/src/server/database/Database/QueryResult.cpp
index f02457f67ca..db9e737830c 100644
--- a/src/server/database/Database/QueryResult.cpp
+++ b/src/server/database/Database/QueryResult.cpp
@@ -76,7 +76,7 @@ m_length(NULL)
std::size_t rowSize = 0;
for (uint32 i = 0; i < m_fieldCount; ++i)
{
- size_t size = Field::SizeForType(&field[i]);
+ uint32 size = Field::SizeForType(&field[i]);
rowSize += size;
m_rBind[i].buffer_type = field[i].type;
diff --git a/src/server/database/Updater/DBUpdater.cpp b/src/server/database/Updater/DBUpdater.cpp
index 5f5b519d2b3..3be81e85715 100644
--- a/src/server/database/Updater/DBUpdater.cpp
+++ b/src/server/database/Updater/DBUpdater.cpp
@@ -22,19 +22,11 @@
#include "DatabaseLoader.h"
#include "Config.h"
#include "BuiltInConfig.h"
+#include "StartProcess.h"
#include <fstream>
#include <iostream>
#include <unordered_map>
-#include <boost/process.hpp>
-#include <boost/iostreams/stream.hpp>
-#include <boost/iostreams/copy.hpp>
-#include <boost/iostreams/device/file_descriptor.hpp>
-#include <boost/system/system_error.hpp>
-
-using namespace boost::process;
-using namespace boost::process::initializers;
-using namespace boost::iostreams;
std::string DBUpdaterUtil::GetCorrectedMySQLExecutable()
{
@@ -51,19 +43,16 @@ bool DBUpdaterUtil::CheckExecutable()
{
exe.clear();
- try
- {
- exe = search_path("mysql");
- }
- catch (std::runtime_error&)
+ if (auto path = Trinity::SearchExecutableInPath("mysql"))
{
- }
+ exe = std::move(*path);
- if (!exe.empty() && exists(exe))
- {
- // Correct the path to the cli
- corrected_path() = absolute(exe).generic_string();
- return true;
+ if (!exe.empty() && exists(exe))
+ {
+ // Correct the path to the cli
+ corrected_path() = absolute(exe).generic_string();
+ return true;
+ }
}
TC_LOG_FATAL("sql.updates", "Didn't find executeable mysql binary at \'%s\' or in path, correct the path in the *.conf (\"Updates.MySqlCLIPath\").",
@@ -387,44 +376,9 @@ void DBUpdater<T>::ApplyFile(DatabaseWorkerPool<T>& pool, std::string const& hos
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
- {
- boost::process::pipe outPipe = create_pipe();
- boost::process::pipe errPipe = create_pipe();
-
- child c = execute(run_exe(
- boost::filesystem::absolute(DBUpdaterUtil::GetCorrectedMySQLExecutable()).generic_string()),
- set_args(args), bind_stdin(source), throw_on_error(),
- bind_stdout(file_descriptor_sink(outPipe.sink, close_handle)),
- bind_stderr(file_descriptor_sink(errPipe.sink, close_handle)));
-
- file_descriptor_source mysqlOutfd(outPipe.source, close_handle);
- file_descriptor_source mysqlErrfd(errPipe.source, close_handle);
-
- stream<file_descriptor_source> mysqlOutStream(mysqlOutfd);
- stream<file_descriptor_source> mysqlErrStream(mysqlErrfd);
-
- std::stringstream out;
- std::stringstream err;
-
- copy(mysqlOutStream, out);
- copy(mysqlErrStream, err);
-
- TC_LOG_INFO("sql.updates", "%s", out.str().c_str());
- TC_LOG_ERROR("sql.updates", "%s", err.str().c_str());
-
- ret = wait_for_exit(c);
- }
- catch (boost::system::system_error&)
- {
- ret = EXIT_FAILURE;
- }
-
- source.close();
+ // Invokes a mysql process which doesn't leak credentials to logs
+ int const ret = Trinity::StartProcess(DBUpdaterUtil::GetCorrectedMySQLExecutable(), args,
+ "sql.updates", path.generic_string(), true);
if (ret != EXIT_SUCCESS)
{
diff --git a/src/server/database/Updater/UpdateFetcher.cpp b/src/server/database/Updater/UpdateFetcher.cpp
index 2d60cdb92ef..6f67867c52b 100644
--- a/src/server/database/Updater/UpdateFetcher.cpp
+++ b/src/server/database/Updater/UpdateFetcher.cpp
@@ -354,7 +354,7 @@ uint32 UpdateFetcher::Apply(Path const& path) const
_applyFile(path);
// Return time the query took to apply
- return std::chrono::duration_cast<std::chrono::milliseconds>(Time::now() - begin).count();
+ return uint32(std::chrono::duration_cast<std::chrono::milliseconds>(Time::now() - begin).count());
}
void UpdateFetcher::UpdateEntry(AppliedFileEntry const& entry, uint32 const speed) const
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 859282891fb..9db36c76bb4 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -489,7 +489,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
// unless target is outside spell range, out of mana, or LOS.
bool _allowMove = false;
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(e.action.cast.spell);
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(e.action.cast.spell);
int32 mana = me->GetPower(POWER_MANA);
if (me->GetDistance(*itr) > spellInfo->GetMaxRange(true) ||
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index ba1738a523b..86aaf45af88 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -859,7 +859,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
if (!IsSpellValid(e, e.action.cast.spell))
return false;
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(e.action.cast.spell);
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(e.action.cast.spell);
for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
{
if (spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT) || spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT2))
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index ebc814405bf..87f5ff6ce5c 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -1533,7 +1533,7 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
//! Since no common attributes were found, (not even in titleRewardFlags field)
//! we explicitly check by ID. Maybe in the future we could move the achievement_reward
//! condition fields to the condition system.
- if (uint32 titleId = reward->titleId[achievement->ID == 1793 ? GetPlayer()->GetByteValue(PLAYER_BYTES_3, 0) : (GetPlayer()->GetTeam() == ALLIANCE ? 0 : 1)])
+ if (uint32 titleId = reward->titleId[achievement->ID == 1793 ? GetPlayer()->GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER) : (GetPlayer()->GetTeam() == ALLIANCE ? 0 : 1)])
if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId))
GetPlayer()->SetTitle(titleEntry);
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
index 5acb56b5173..fd105c5b25f 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
@@ -582,13 +582,13 @@ void AuctionBotSeller::LoadSellerValues(SellerConfiguration& config)
break;
}
- config.SetPriceRatioPerQuality(AUCTION_QUALITY_GRAY, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_GRAY_PRICE_RATIO) / 100);
- config.SetPriceRatioPerQuality(AUCTION_QUALITY_WHITE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_WHITE_PRICE_RATIO) / 100);
- config.SetPriceRatioPerQuality(AUCTION_QUALITY_GREEN, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_GREEN_PRICE_RATIO) / 100);
- config.SetPriceRatioPerQuality(AUCTION_QUALITY_BLUE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_BLUE_PRICE_RATIO) / 100);
- config.SetPriceRatioPerQuality(AUCTION_QUALITY_PURPLE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_PURPLE_PRICE_RATIO) / 100);
- config.SetPriceRatioPerQuality(AUCTION_QUALITY_ORANGE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_ORANGE_PRICE_RATIO) / 100);
- config.SetPriceRatioPerQuality(AUCTION_QUALITY_YELLOW, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_YELLOW_PRICE_RATIO) / 100);
+ config.SetPriceRatioPerQuality(AUCTION_QUALITY_GRAY, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_GRAY_PRICE_RATIO));
+ config.SetPriceRatioPerQuality(AUCTION_QUALITY_WHITE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_WHITE_PRICE_RATIO));
+ config.SetPriceRatioPerQuality(AUCTION_QUALITY_GREEN, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_GREEN_PRICE_RATIO));
+ config.SetPriceRatioPerQuality(AUCTION_QUALITY_BLUE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_BLUE_PRICE_RATIO));
+ config.SetPriceRatioPerQuality(AUCTION_QUALITY_PURPLE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_PURPLE_PRICE_RATIO));
+ config.SetPriceRatioPerQuality(AUCTION_QUALITY_ORANGE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_ORANGE_PRICE_RATIO));
+ config.SetPriceRatioPerQuality(AUCTION_QUALITY_YELLOW, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_YELLOW_PRICE_RATIO));
config.SetPriceRatioPerClass(ITEM_CLASS_CONSUMABLE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_PRICE_RATIO));
config.SetPriceRatioPerClass(ITEM_CLASS_CONTAINER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_PRICE_RATIO));
@@ -701,10 +701,10 @@ void AuctionBotSeller::SetPricesOfItem(ItemTemplate const* itemProto, SellerConf
{
uint32 classRatio = config.GetPriceRatioPerClass(ItemClass(itemProto->Class));
uint32 qualityRatio = config.GetPriceRatioPerQuality(AuctionQuality(itemProto->Quality));
- uint32 priceRatio = (classRatio * qualityRatio) / 100;
+ float priceRatio = (classRatio * qualityRatio) / 10000.0f;
- uint32 buyPrice = itemProto->BuyPrice;
- uint32 sellPrice = itemProto->SellPrice;
+ float buyPrice = itemProto->BuyPrice;
+ float sellPrice = itemProto->SellPrice;
if (buyPrice == 0)
{
@@ -712,11 +712,11 @@ void AuctionBotSeller::SetPricesOfItem(ItemTemplate const* itemProto, SellerConf
buyPrice = sellPrice * GetSellModifier(itemProto);
else
{
- uint32 divisor = ((itemProto->Class == 2 || itemProto->Class == 4) ? 284 : 80);
- uint32 tempLevel = (itemProto->ItemLevel == 0 ? 1 : itemProto->ItemLevel);
- uint32 tempQuality = (itemProto->Quality == 0 ? 1 : itemProto->Quality);
+ float divisor = ((itemProto->Class == ITEM_CLASS_WEAPON || itemProto->Class == ITEM_CLASS_ARMOR) ? 284.0f : 80.0f);
+ float tempLevel = (itemProto->ItemLevel == 0 ? 1.0f : itemProto->ItemLevel);
+ float tempQuality = (itemProto->Quality == 0 ? 1.0f : itemProto->Quality);
- buyPrice = tempLevel * tempQuality * GetBuyModifier(itemProto)* tempLevel / divisor;
+ buyPrice = tempLevel * tempQuality * static_cast<float>(GetBuyModifier(itemProto))* tempLevel / divisor;
}
}
@@ -725,15 +725,16 @@ void AuctionBotSeller::SetPricesOfItem(ItemTemplate const* itemProto, SellerConf
if (sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYPRICE_SELLER))
buyPrice = sellPrice;
-
- uint32 basePrice = (buyPrice * stackCount * priceRatio) / (itemProto->Class == 6 ? 200 : itemProto->BuyCount) / 100;
- uint32 range = basePrice * 0.04;
-
- buyp = urand(basePrice - range, basePrice + range) + 1;
-
- basePrice = buyp * .5;
+
+ float basePriceFloat = (buyPrice * stackCount * priceRatio) / (itemProto->Class == 6 ? 200.0f : static_cast<float>(itemProto->BuyCount)) / 100.0f;
+ float range = basePriceFloat * 0.04f;
+
+ buyp = static_cast<uint32>(frand(basePriceFloat - range, basePriceFloat + range) + 0.5f);
+ if (buyp == 0)
+ buyp = 1;
+ uint32 basePrice = buyp * .5;
range = buyp * .4;
- bidp = urand(basePrice - range, basePrice + range) + 1;
+ bidp = urand(static_cast<uint32>(basePrice - range + 0.5f), static_cast<uint32>(basePrice + range + 0.5f)) + 1;
}
// Determines the stack size to use for the item
diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
index df0d2b7cc2a..239e59d6dbb 100644
--- a/src/server/game/CMakeLists.txt
+++ b/src/server/game/CMakeLists.txt
@@ -23,27 +23,36 @@ GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
add_definitions(-DTRINITY_API_EXPORT_GAME)
-add_library(game
- ${PRIVATE_SOURCES}
- ${PRIVATE_PCH_SOURCE}
-)
-
CollectIncludeDirectories(
${CMAKE_CURRENT_SOURCE_DIR}
PUBLIC_INCLUDES
# Exclude
${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
+# Provide an interface target for the game project to allow
+# dependent projects to build meanwhile.
+add_library(game-interface INTERFACE)
+
+target_include_directories(game-interface
+ INTERFACE
+ ${PUBLIC_INCLUDES})
+
+target_link_libraries(game-interface
+ INTERFACE
+ shared
+ Detour)
+
+add_library(game
+ ${PRIVATE_PCH_SOURCE}
+ ${PRIVATE_SOURCES})
+
target_include_directories(game
- PUBLIC
- ${PUBLIC_INCLUDES}
PRIVATE
${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(game
PUBLIC
- shared
- Detour
+ game-interface
PRIVATE
efsw)
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index f0e98ee8c1f..ec90a5f7efb 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -32,18 +32,19 @@
#include "ScriptMgr.h"
#include "ChatLink.h"
-bool ChatHandler::load_command_table = true;
+// Lazy loading of the command table cache from commands and the
+// ScriptMgr should be thread safe since the player commands,
+// cli commands and ScriptMgr updates are all dispatched one after
+// one inside the world update loop.
+static Optional<std::vector<ChatCommand>> commandTableCache;
std::vector<ChatCommand> const& ChatHandler::getCommandTable()
{
- static std::vector<ChatCommand> commandTableCache;
-
- if (LoadCommandTable())
+ if (!commandTableCache)
{
- SetLoadCommandTable(false);
-
- std::vector<ChatCommand> cmds = sScriptMgr->GetChatCommands();
- commandTableCache.swap(cmds);
+ // We need to initialize this at top since SetDataForCommandInTable
+ // calls getCommandTable() recursively.
+ commandTableCache = sScriptMgr->GetChatCommands();
PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_COMMANDS);
PreparedQueryResult result = WorldDatabase.Query(stmt);
@@ -54,13 +55,18 @@ std::vector<ChatCommand> const& ChatHandler::getCommandTable()
Field* fields = result->Fetch();
std::string name = fields[0].GetString();
- SetDataForCommandInTable(commandTableCache, name.c_str(), fields[1].GetUInt16(), fields[2].GetString(), name);
+ SetDataForCommandInTable(*commandTableCache, name.c_str(), fields[1].GetUInt16(), fields[2].GetString(), name);
}
while (result->NextRow());
}
}
- return commandTableCache;
+ return *commandTableCache;
+}
+
+void ChatHandler::invalidateCommandTable()
+{
+ commandTableCache.reset();
}
char const* ChatHandler::GetTrinityString(uint32 entry) const
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index a061ff63b00..1c9368275ad 100644
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -96,6 +96,7 @@ class TC_GAME_API ChatHandler
bool ParseCommands(const char* text);
static std::vector<ChatCommand> const& getCommandTable();
+ static void invalidateCommandTable();
bool isValidChatMessage(const char* msg);
void SendGlobalSysMessage(const char *str);
@@ -143,8 +144,6 @@ class TC_GAME_API ChatHandler
GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(ObjectGuid::LowType lowguid, uint32 entry);
bool HasSentErrorMessage() const { return sentErrorMessage; }
void SetSentErrorMessage(bool val){ sentErrorMessage = val; }
- static bool LoadCommandTable() { return load_command_table; }
- static void SetLoadCommandTable(bool val) { load_command_table = val; }
bool ShowHelpForCommand(std::vector<ChatCommand> const& table, const char* cmd);
protected:
@@ -157,7 +156,6 @@ class TC_GAME_API ChatHandler
WorldSession* m_session; // != NULL for chat command call and NULL for CLI command
// common global flag
- static bool load_command_table;
bool sentErrorMessage;
};
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 50e3e64ea2c..afb6255079b 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -440,7 +440,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const
if (Unit* unit = object->ToUnit())
{
if (ConditionValue1 == 0)
- condMeets = (unit->getStandState() == ConditionValue2);
+ condMeets = (unit->GetStandState() == ConditionValue2);
else if (ConditionValue2 == 0)
condMeets = unit->IsStandState();
else if (ConditionValue2 == 1)
@@ -1242,7 +1242,7 @@ bool ConditionMgr::addToGossipMenuItems(Condition* cond) const
bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) const
{
uint32 conditionEffMask = cond->SourceGroup;
- SpellInfo* spellInfo = const_cast<SpellInfo*>(sSpellMgr->EnsureSpellInfo(cond->SourceEntry));
+ SpellInfo* spellInfo = const_cast<SpellInfo*>(sSpellMgr->AssertSpellInfo(cond->SourceEntry));
std::list<uint32> sharedMasks;
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index 6c51c71fe7b..5ede70da2a3 100644
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -27,6 +27,9 @@
#include <boost/regex.hpp>
#include <map>
+#include <fstream>
+#include <iostream>
+#include <iomanip>
typedef std::map<uint16, uint32> AreaFlagByAreaID;
typedef std::map<uint32, uint32> AreaFlagByMapID;
@@ -73,6 +76,7 @@ DBCStorage <CharTitlesEntry> sCharTitlesStore(CharTitlesEntryfmt);
DBCStorage <ChatChannelsEntry> sChatChannelsStore(ChatChannelsEntryfmt);
DBCStorage <ChrClassesEntry> sChrClassesStore(ChrClassesEntryfmt);
DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt);
+DBCStorage <CinematicCameraEntry> sCinematicCameraStore(CinematicCameraEntryfmt);
DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore(CinematicSequencesEntryfmt);
DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt);
DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore(CreatureDisplayInfoExtrafmt);
@@ -217,6 +221,8 @@ DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore(WorldMapAreaEntryfmt);
DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore(WorldMapOverlayEntryfmt);
DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore(WorldSafeLocsEntryfmt);
+std::unordered_map<uint32, FlyByCameraCollection> sFlyByCameraStore;
+
typedef std::list<std::string> StoreProblemList;
uint32 DBCFileCount = 0;
@@ -311,6 +317,7 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales, bad_dbc_files, sChatChannelsStore, dbcPath, "ChatChannels.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sChrClassesStore, dbcPath, "ChrClasses.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sChrRacesStore, dbcPath, "ChrRaces.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicCameraStore, dbcPath, "CinematicCamera.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoExtraStore, dbcPath, "CreatureDisplayInfoExtra.dbc");
@@ -717,10 +724,250 @@ void LoadDBCStores(const std::string& dataPath)
exit(1);
}
+ LoadM2Cameras(dataPath);
+
TC_LOG_INFO("server.loading", ">> Initialized %d data stores in %u ms", DBCFileCount, GetMSTimeDiffToNow(oldMSTime));
}
+// Convert the geomoetry from a spline value, to an actual WoW XYZ
+G3D::Vector3 TranslateLocation(G3D::Vector4 const* DBCPosition, G3D::Vector3 const* basePosition, G3D::Vector3 const* splineVector)
+{
+ G3D::Vector3 work;
+ float x = basePosition->x + splineVector->x;
+ float y = basePosition->y + splineVector->y;
+ float z = basePosition->z + splineVector->z;
+ float const distance = sqrt((x * x) + (y * y));
+ float angle = std::atan2(x, y) - DBCPosition->w;
+
+ if (angle < 0)
+ angle += 2 * float(M_PI);
+
+ work.x = DBCPosition->x + (distance * sin(angle));
+ work.y = DBCPosition->y + (distance * cos(angle));
+ work.z = DBCPosition->z + z;
+ return work;
+}
+
+// Number of cameras not used. Multiple cameras never used in 3.3.5
+bool readCamera(M2Camera const* cam, uint32 buffSize, M2Header const* header, CinematicCameraEntry const* dbcentry)
+{
+ char const* buffer = reinterpret_cast<char const*>(header);
+
+ FlyByCameraCollection cameras;
+ FlyByCameraCollection targetcam;
+
+ G3D::Vector4 DBCData;
+ DBCData.x = dbcentry->base_x;
+ DBCData.y = dbcentry->base_y;
+ DBCData.z = dbcentry->base_z;
+ DBCData.w = dbcentry->base_o;
+
+ // Read target locations, only so that we can calculate orientation
+ for (uint32 k = 0; k < cam->target_positions.timestamps.number; ++k)
+ {
+ // Extract Target positions
+ if (cam->target_positions.timestamps.offset_elements + sizeof(M2Array) > buffSize)
+ return false;
+ M2Array const* targTsArray = reinterpret_cast<M2Array const*>(buffer + cam->target_positions.timestamps.offset_elements);
+ if (targTsArray->offset_elements + sizeof(uint32) > buffSize || cam->target_positions.values.offset_elements + sizeof(M2Array) > buffSize)
+ return false;
+ uint32 const* targTimestamps = reinterpret_cast<uint32 const*>(buffer + targTsArray->offset_elements);
+ M2Array const* targArray = reinterpret_cast<M2Array const*>(buffer + cam->target_positions.values.offset_elements);
+
+ if (targArray->offset_elements + sizeof(M2SplineKey<G3D::Vector3>) > buffSize)
+ return false;
+ M2SplineKey<G3D::Vector3> const* targPositions = reinterpret_cast<M2SplineKey<G3D::Vector3> const*>(buffer + targArray->offset_elements);
+
+ // Read the data for this set
+ uint32 currPos = targArray->offset_elements;
+ for (uint32 i = 0; i < targTsArray->number; ++i)
+ {
+ if (currPos + sizeof(M2SplineKey<G3D::Vector3>) > buffSize)
+ return false;
+ // Translate co-ordinates
+ G3D::Vector3 newPos = TranslateLocation(&DBCData, &cam->target_position_base, &targPositions->p0);
+
+ // Add to vector
+ FlyByCamera thisCam;
+ thisCam.timeStamp = targTimestamps[i];
+ thisCam.locations.x = newPos.x;
+ thisCam.locations.y = newPos.y;
+ thisCam.locations.z = newPos.z;
+ thisCam.locations.w = 0.0f;
+ targetcam.push_back(thisCam);
+ targPositions++;
+ currPos += sizeof(M2SplineKey<G3D::Vector3>);
+ }
+ }
+
+ // Read camera positions and timestamps (translating first position of 3 only, we don't need to translate the whole spline)
+ for (uint32 k = 0; k < cam->positions.timestamps.number; ++k)
+ {
+ // Extract Camera positions for this set
+ if (cam->positions.timestamps.offset_elements + sizeof(M2Array) > buffSize)
+ return false;
+ M2Array const* posTsArray = reinterpret_cast<M2Array const*>(buffer + cam->positions.timestamps.offset_elements);
+ if (posTsArray->offset_elements + sizeof(uint32) > buffSize || cam->positions.values.offset_elements + sizeof(M2Array) > buffSize)
+ return false;
+ uint32 const* posTimestamps = reinterpret_cast<uint32 const*>(buffer + posTsArray->offset_elements);
+ M2Array const* posArray = reinterpret_cast<M2Array const*>(buffer + cam->positions.values.offset_elements);
+ if (posArray->offset_elements + sizeof(M2SplineKey<G3D::Vector3>) > buffSize)
+ return false;
+ M2SplineKey<G3D::Vector3> const* positions = reinterpret_cast<M2SplineKey<G3D::Vector3> const*>(buffer + posArray->offset_elements);
+
+ // Read the data for this set
+ uint32 currPos = posArray->offset_elements;
+ for (uint32 i = 0; i < posTsArray->number; ++i)
+ {
+ if (currPos + sizeof(M2SplineKey<G3D::Vector3>) > buffSize)
+ return false;
+ // Translate co-ordinates
+ G3D::Vector3 newPos = TranslateLocation(&DBCData, &cam->position_base, &positions->p0);
+
+ // Add to vector
+ FlyByCamera thisCam;
+ thisCam.timeStamp = posTimestamps[i];
+ thisCam.locations.x = newPos.x;
+ thisCam.locations.y = newPos.y;
+ thisCam.locations.z = newPos.z;
+
+ if (targetcam.size() > 0)
+ {
+ // Find the target camera before and after this camera
+ FlyByCamera lastTarget;
+ FlyByCamera nextTarget;
+
+ // Pre-load first item
+ lastTarget = targetcam[0];
+ nextTarget = targetcam[0];
+ for (uint32 j = 0; j < targetcam.size(); ++j)
+ {
+ nextTarget = targetcam[j];
+ if (targetcam[j].timeStamp > posTimestamps[i])
+ break;
+
+ lastTarget = targetcam[j];
+ }
+
+ float x = lastTarget.locations.x;
+ float y = lastTarget.locations.y;
+ float z = lastTarget.locations.z;
+
+ // Now, the timestamps for target cam and position can be different. So, if they differ we interpolate
+ if (lastTarget.timeStamp != posTimestamps[i])
+ {
+ uint32 timeDiffTarget = nextTarget.timeStamp - lastTarget.timeStamp;
+ uint32 timeDiffThis = posTimestamps[i] - lastTarget.timeStamp;
+ float xDiff = nextTarget.locations.x - lastTarget.locations.x;
+ float yDiff = nextTarget.locations.y - lastTarget.locations.y;
+ float zDiff = nextTarget.locations.z - lastTarget.locations.z;
+ x = lastTarget.locations.x + (xDiff * (float(timeDiffThis) / float(timeDiffTarget)));
+ y = lastTarget.locations.y + (yDiff * (float(timeDiffThis) / float(timeDiffTarget)));
+ z = lastTarget.locations.z + (zDiff * (float(timeDiffThis) / float(timeDiffTarget)));
+ }
+ float xDiff = x - thisCam.locations.x;
+ float yDiff = y - thisCam.locations.y;
+ thisCam.locations.w = std::atan2(yDiff, xDiff);
+
+ if (thisCam.locations.w < 0)
+ thisCam.locations.w += 2 * float(M_PI);
+ }
+
+ cameras.push_back(thisCam);
+ positions++;
+ currPos += sizeof(M2SplineKey<G3D::Vector3>);
+ }
+ }
+
+ sFlyByCameraStore[dbcentry->id] = cameras;
+ return true;
+}
+
+void LoadM2Cameras(const std::string& dataPath)
+{
+ sFlyByCameraStore.clear();
+ TC_LOG_INFO("server.loading", ">> Loading Cinematic Camera files");
+
+ uint32 oldMSTime = getMSTime();
+ for (uint32 i = 0; i < sCinematicCameraStore.GetNumRows(); ++i)
+ {
+ if (CinematicCameraEntry const* dbcentry = sCinematicCameraStore.LookupEntry(i))
+ {
+ std::string filename = dataPath.c_str();
+ filename.append(dbcentry->filename);
+
+ // Replace slashes
+ size_t loc = filename.find("\\");
+ while (loc != std::string::npos)
+ {
+ filename.replace(loc, 1, "/");
+ loc = filename.find("\\");
+ }
+
+ // Replace mdx to .m2
+ loc = filename.find(".mdx");
+ if (loc != std::string::npos)
+ filename.replace(loc, 4, ".m2");
+
+ std::ifstream m2file(filename.c_str(), std::ios::in | std::ios::binary);
+ if (!m2file.is_open())
+ continue;
+
+ // Get file size
+ m2file.seekg(0, std::ios::end);
+ std::streamoff const fileSize = m2file.tellg();
+
+ // Reject if not at least the size of the header
+ if (static_cast<uint32 const>(fileSize) < sizeof(M2Header))
+ {
+ TC_LOG_ERROR("server.loading", "Camera file %s is damaged. File is smaller than header size", filename.c_str());
+ m2file.close();
+ continue;
+ }
+
+ // Read 4 bytes (signature)
+ m2file.seekg(0, std::ios::beg);
+ char fileCheck[5];
+ m2file.read(fileCheck, 4);
+ fileCheck[4] = 0;
+
+ // Check file has correct magic (MD20)
+ if (strcmp(fileCheck, "MD20"))
+ {
+ TC_LOG_ERROR("server.loading", "Camera file %s is damaged. File identifier not found", filename.c_str());
+ m2file.close();
+ continue;
+ }
+
+ // Now we have a good file, read it all into a vector of char's, then close the file.
+ std::vector<char> buffer(fileSize);
+ m2file.seekg(0, std::ios::beg);
+ if (!m2file.read(buffer.data(), fileSize))
+ {
+ m2file.close();
+ continue;
+ }
+ m2file.close();
+
+ // Read header
+ M2Header const* header = reinterpret_cast<M2Header const*>(buffer.data());
+
+ if (header->ofsCameras + sizeof(M2Camera) > static_cast<uint32 const>(fileSize))
+ {
+ TC_LOG_ERROR("server.loading", "Camera file %s is damaged. Camera references position beyond file end", filename.c_str());
+ continue;
+ }
+
+ // Get camera(s) - Main header, then dump them.
+ M2Camera const* cam = reinterpret_cast<M2Camera const*>(buffer.data() + header->ofsCameras);
+ if (!readCamera(cam, fileSize, header, dbcentry))
+ TC_LOG_ERROR("server.loading", "Camera file %s is damaged. Camera references position beyond file end", filename.c_str());
+ }
+ }
+ TC_LOG_INFO("server.loading", ">> Loaded %u cinematic waypoint sets in %u ms", (uint32)sFlyByCameraStore.size(), GetMSTimeDiffToNow(oldMSTime));
+}
+
SimpleFactionsList const* GetFactionTeamList(uint32 faction)
{
FactionTeamMap::const_iterator itr = sFactionTeamMap.find(faction);
@@ -1017,5 +1264,6 @@ ResponseCodes ValidateName(std::string const& name, LocaleConstant locale)
EmotesTextSoundEntry const* FindTextSoundEmoteFor(uint32 emote, uint32 race, uint32 gender)
{
- return sEmotesTextSoundMap[EmotesTextSoundKey(emote, race, gender)];
+ auto itr = sEmotesTextSoundMap.find(EmotesTextSoundKey(emote, race, gender));
+ return itr != sEmotesTextSoundMap.end() ? itr->second : nullptr;
}
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index beb0bb514cc..6cad13fdf9a 100644
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -27,6 +27,8 @@
#include <list>
typedef std::list<uint32> SimpleFactionsList;
+typedef std::vector<FlyByCamera> FlyByCameraCollection;
+
TC_GAME_API SimpleFactionsList const* GetFactionTeamList(uint32 faction);
TC_GAME_API char* GetPetName(uint32 petfamily, uint32 dbclang);
@@ -96,6 +98,7 @@ TC_GAME_API extern DBCStorage <CharSectionsEntry> sCharSectionsStore;
TC_GAME_API extern DBCStorage <CharTitlesEntry> sCharTitlesStore;
TC_GAME_API extern DBCStorage <ChrClassesEntry> sChrClassesStore;
TC_GAME_API extern DBCStorage <ChrRacesEntry> sChrRacesStore;
+TC_GAME_API extern DBCStorage <CinematicCameraEntry> sCinematicCameraStore;
TC_GAME_API extern DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore;
TC_GAME_API extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore;
TC_GAME_API extern DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore;
@@ -193,7 +196,9 @@ TC_GAME_API extern DBCStorage <WMOAreaTableEntry> sWMOAreaTableStore;
//TC_GAME_API extern DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore; -- use Zone2MapCoordinates and Map2ZoneCoordinates
TC_GAME_API extern DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore;
TC_GAME_API extern DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore;
+TC_GAME_API extern std::unordered_map<uint32, FlyByCameraCollection> sFlyByCameraStore;
TC_GAME_API void LoadDBCStores(const std::string& dataPath);
+TC_GAME_API void LoadM2Cameras(const std::string& dataPath);
#endif
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index b5dc4489148..51b3dcbd38b 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -725,24 +725,22 @@ struct ChrRacesEntry
uint32 expansion; // 68 (0 - original race, 1 - tbc addon, ...)
};
-/* not used
struct CinematicCameraEntry
{
uint32 id; // 0 index
char* filename; // 1
uint32 soundid; // 2 in SoundEntries.dbc or 0
- float start_x; // 3
- float start_y; // 4
- float start_z; // 5
- float unk6; // 6 speed?
+ float base_x; // 3
+ float base_y; // 4
+ float base_z; // 5
+ float base_o; // 6
};
-*/
struct CinematicSequencesEntry
{
uint32 Id; // 0 index
//uint32 unk1; // 1 always 0
- //uint32 cinematicCamera; // 2 id in CinematicCamera.dbc
+ uint32 cinematicCamera; // 2 id in CinematicCamera.dbc
// 3-9 always 0
};
diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h
index c61ec997bc2..1accc81714b 100644
--- a/src/server/game/DataStores/DBCfmt.h
+++ b/src/server/game/DataStores/DBCfmt.h
@@ -38,7 +38,8 @@ char const CharTitlesEntryfmt[] = "nxssssssssssssssssxssssssssssssssssxi";
char const ChatChannelsEntryfmt[] = "nixssssssssssssssssxxxxxxxxxxxxxxxxxx";
char const ChrClassesEntryfmt[] = "nxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
char const ChrRacesEntryfmt[] = "niixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
-char const CinematicSequencesEntryfmt[] = "nxxxxxxxxx";
+char const CinematicCameraEntryfmt[] = "nsiffff";
+char const CinematicSequencesEntryfmt[] = "nxixxxxxxx";
char const CreatureDisplayInfofmt[] = "nixifxxxxxxxxxxx";
char const CreatureDisplayInfoExtrafmt[] = "diixxxxxxxxxxxxxxxxxx";
char const CreatureFamilyfmt[] = "nfifiiiiixssssssssssssssssxx";
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index fe997bc0343..e72859c23e7 100644
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -40,8 +40,6 @@ namespace lfg
LFGMgr::LFGMgr(): m_QueueTimer(0), m_lfgProposalId(1),
m_options(sWorld->getIntConfig(CONFIG_LFG_OPTIONSMASK))
{
- new LFGPlayerScript();
- new LFGGroupScript();
}
LFGMgr::~LFGMgr()
@@ -1148,7 +1146,7 @@ void LFGMgr::RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdate
for (GuidList::const_iterator it = proposal.queues.begin(); it != proposal.queues.end(); ++it)
{
ObjectGuid guid = *it;
- queue.AddToQueue(guid);
+ queue.AddToQueue(guid, true);
}
ProposalsStore.erase(itProposal);
diff --git a/src/server/game/DungeonFinding/LFGQueue.cpp b/src/server/game/DungeonFinding/LFGQueue.cpp
index 314803d1602..d156158dee6 100644
--- a/src/server/game/DungeonFinding/LFGQueue.cpp
+++ b/src/server/game/DungeonFinding/LFGQueue.cpp
@@ -117,7 +117,7 @@ std::string LFGQueue::GetDetailedMatchRoles(GuidList const& check) const
return o.str();
}
-void LFGQueue::AddToQueue(ObjectGuid guid)
+void LFGQueue::AddToQueue(ObjectGuid guid, bool reAdd)
{
LfgQueueDataContainer::iterator itQueue = QueueDataStore.find(guid);
if (itQueue == QueueDataStore.end())
@@ -126,7 +126,10 @@ void LFGQueue::AddToQueue(ObjectGuid guid)
return;
}
- AddToNewQueue(guid);
+ if (reAdd)
+ AddToFrontCurrentQueue(guid);
+ else
+ AddToNewQueue(guid);
}
void LFGQueue::RemoveFromQueue(ObjectGuid guid)
@@ -171,6 +174,11 @@ void LFGQueue::AddToCurrentQueue(ObjectGuid guid)
currentQueueStore.push_back(guid);
}
+void LFGQueue::AddToFrontCurrentQueue(ObjectGuid guid)
+{
+ currentQueueStore.push_front(guid);
+}
+
void LFGQueue::RemoveFromCurrentQueue(ObjectGuid guid)
{
currentQueueStore.remove(guid);
diff --git a/src/server/game/DungeonFinding/LFGQueue.h b/src/server/game/DungeonFinding/LFGQueue.h
index 7c35c4d04e3..32711e81468 100644
--- a/src/server/game/DungeonFinding/LFGQueue.h
+++ b/src/server/game/DungeonFinding/LFGQueue.h
@@ -89,7 +89,7 @@ class TC_GAME_API LFGQueue
// Add/Remove from queue
std::string GetDetailedMatchRoles(GuidList const& check) const;
- void AddToQueue(ObjectGuid guid);
+ void AddToQueue(ObjectGuid guid, bool reAdd = false);
void RemoveFromQueue(ObjectGuid guid);
void AddQueueData(ObjectGuid guid, time_t joinTime, LfgDungeonSet const& dungeons, LfgRolesMap const& rolesMap);
void RemoveQueueData(ObjectGuid guid);
@@ -116,6 +116,7 @@ class TC_GAME_API LFGQueue
void AddToNewQueue(ObjectGuid guid);
void AddToCurrentQueue(ObjectGuid guid);
+ void AddToFrontCurrentQueue(ObjectGuid guid);
void RemoveFromNewQueue(ObjectGuid guid);
void RemoveFromCurrentQueue(ObjectGuid guid);
diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp
index 79d36055870..1d2b963b254 100644
--- a/src/server/game/DungeonFinding/LFGScripts.cpp
+++ b/src/server/game/DungeonFinding/LFGScripts.cpp
@@ -241,4 +241,10 @@ void LFGGroupScript::OnInviteMember(Group* group, ObjectGuid guid)
sLFGMgr->LeaveLfg(leader);
}
+void AddSC_LFGScripts()
+{
+ new LFGPlayerScript();
+ new LFGGroupScript();
+}
+
} // namespace lfg
diff --git a/src/server/game/DungeonFinding/LFGScripts.h b/src/server/game/DungeonFinding/LFGScripts.h
index ec64604a282..9f52668ea61 100644
--- a/src/server/game/DungeonFinding/LFGScripts.h
+++ b/src/server/game/DungeonFinding/LFGScripts.h
@@ -53,4 +53,6 @@ class TC_GAME_API LFGGroupScript : public GroupScript
void OnInviteMember(Group* group, ObjectGuid guid) override;
};
+/*keep private*/ void AddSC_LFGScripts();
+
} // namespace lfg
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 61d5d7d9459..d5e1e0956b1 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -342,10 +342,10 @@ bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/)
m_creatureInfo = cinfo; // map mode related always
// equal to player Race field, but creature does not have race
- SetByteValue(UNIT_FIELD_BYTES_0, 0, 0);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE, 0);
// known valid are: CLASS_WARRIOR, CLASS_PALADIN, CLASS_ROGUE, CLASS_MAGE
- SetByteValue(UNIT_FIELD_BYTES_0, 1, uint8(cinfo->unit_class));
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, uint8(cinfo->unit_class));
// Cancel load if no model defined
if (!(cinfo->GetFirstValidModelId()))
@@ -364,7 +364,7 @@ bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/)
SetDisplayId(displayID);
SetNativeDisplayId(displayID);
- SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, minfo->gender);
// Load creature equipment
if (data && data->equipmentId != 0)
@@ -791,6 +791,24 @@ void Creature::DoFleeToGetAssistance()
}
}
+bool Creature::AIM_Destroy()
+{
+ if (m_AI_locked)
+ {
+ TC_LOG_DEBUG("scripts", "AIM_Destroy: failed to destroy, locked.");
+ return false;
+ }
+
+ ASSERT(!i_disabledAI,
+ "The disabled AI wasn't cleared!");
+
+ delete i_AI;
+ i_AI = nullptr;
+
+ IsAIEnabled = false;
+ return true;
+}
+
bool Creature::AIM_Initialize(CreatureAI* ai)
{
// make sure nothing can change the AI during AI update
@@ -800,12 +818,12 @@ bool Creature::AIM_Initialize(CreatureAI* ai)
return false;
}
- UnitAI* oldAI = i_AI;
+ AIM_Destroy();
Motion_Initialize();
i_AI = ai ? ai : FactorySelector::selectAI(this);
- delete oldAI;
+
IsAIEnabled = true;
i_AI->InitializeAI();
// Initialize vehicle
@@ -889,7 +907,7 @@ bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 phaseMask, u
{
SetDisplayId(displayID);
SetNativeDisplayId(displayID);
- SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, minfo->gender);
}
LastUsedScriptID = GetCreatureTemplate()->ScriptID;
@@ -1705,7 +1723,7 @@ void Creature::Respawn(bool force)
{
SetDisplayId(displayID);
SetNativeDisplayId(displayID);
- SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, minfo->gender);
}
GetMotionMaster()->InitDefault();
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index c6b19dbb939..8466dad9e95 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -476,6 +476,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
bool IsInEvadeMode() const { return HasUnitState(UNIT_STATE_EVADE); }
+ bool AIM_Destroy();
bool AIM_Initialize(CreatureAI* ai = NULL);
void Motion_Initialize();
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 1acfeacbf83..7f922f89572 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -71,9 +71,15 @@ GameObject::~GameObject()
// CleanupsBeforeDelete();
}
-bool GameObject::AIM_Initialize()
+void GameObject::AIM_Destroy()
{
delete m_AI;
+ m_AI = nullptr;
+}
+
+bool GameObject::AIM_Initialize()
+{
+ AIM_Destroy();
m_AI = FactorySelector::SelectGameObjectAI(this);
@@ -1282,8 +1288,8 @@ void GameObject::Use(Unit* user)
{
if (Player* ChairUser = ObjectAccessor::FindPlayer(itr->second))
{
- if (ChairUser->IsSitState() && ChairUser->getStandState() != UNIT_STAND_STATE_SIT && ChairUser->GetExactDist2d(x_i, y_i) < 0.1f)
- continue; // This seat is already occupied by ChairUser. NOTE: Not sure if the ChairUser->getStandState() != UNIT_STAND_STATE_SIT check is required.
+ if (ChairUser->IsSitState() && ChairUser->GetStandState() != UNIT_STAND_STATE_SIT && ChairUser->GetExactDist2d(x_i, y_i) < 0.1f)
+ continue; // This seat is already occupied by ChairUser. NOTE: Not sure if the ChairUser->GetStandState() != UNIT_STAND_STATE_SIT check is required.
else
itr->second.Clear(); // This seat is unoccupied.
}
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index 49f94013ac2..2b092427178 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -849,8 +849,10 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
void UpdateModelPosition();
- protected:
+ void AIM_Destroy();
bool AIM_Initialize();
+
+ protected:
GameObjectModel* CreateModel();
void UpdateModel(); // updates model in case displayId were changed
uint32 m_spellId;
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 824f42ad671..45952ba51ac 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -928,6 +928,11 @@ bool Object::HasByteFlag(uint16 index, uint8 offset, uint8 flag) const
return (((uint8*)&m_uint32Values[index])[offset] & flag) != 0;
}
+void Object::ApplyModByteFlag(uint16 index, uint8 offset, uint8 flag, bool apply)
+{
+ if (apply) SetByteFlag(index, offset, flag); else RemoveByteFlag(index, offset, flag);
+}
+
void Object::SetFlag64(uint16 index, uint64 newFlag)
{
uint64 oldval = GetUInt64Value(index);
@@ -1465,9 +1470,20 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
float WorldObject::GetGridActivationRange() const
{
if (ToPlayer())
+ {
+ if (ToPlayer()->IsOnCinematic())
+ return DEFAULT_VISIBILITY_INSTANCE;
return GetMap()->GetVisibilityRange();
+ }
else if (ToCreature())
return ToCreature()->m_SightDistance;
+ else if (ToDynObject())
+ {
+ if (isActiveObject())
+ return GetMap()->GetVisibilityRange();
+ else
+ return 0.0f;
+ }
else
return 0.0f;
}
@@ -1488,6 +1504,8 @@ float WorldObject::GetSightRange(const WorldObject* target) const
{
if (target && target->isActiveObject() && !target->ToPlayer())
return MAX_VISIBILITY_DISTANCE;
+ else if (ToPlayer()->IsOnCinematic())
+ return DEFAULT_VISIBILITY_INSTANCE;
else
return GetMap()->GetVisibilityRange();
}
@@ -1497,6 +1515,11 @@ float WorldObject::GetSightRange(const WorldObject* target) const
return SIGHT_RANGE_UNIT;
}
+ if (ToDynObject() && isActiveObject())
+ {
+ return GetMap()->GetVisibilityRange();
+ }
+
return 0.0f;
}
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 029a8c08fd7..d4c8fc35451 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -160,6 +160,7 @@ class TC_GAME_API Object
void RemoveByteFlag(uint16 index, uint8 offset, uint8 newFlag);
void ToggleByteFlag(uint16 index, uint8 offset, uint8 flag);
bool HasByteFlag(uint16 index, uint8 offset, uint8 flag) const;
+ void ApplyModByteFlag(uint16 index, uint8 offset, uint8 flag, bool apply);
void SetFlag64(uint16 index, uint64 newFlag);
void RemoveFlag64(uint16 index, uint64 oldFlag);
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index 0da63c5e500..37fb23b38f5 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -213,12 +213,14 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
case SUMMON_PET:
petlevel = owner->getLevel();
- SetUInt32Value(UNIT_FIELD_BYTES_0, 0x800); // class = mage
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, uint8(CLASS_MAGE));
SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
// this enables popup window (pet dismiss, cancel)
break;
case HUNTER_PET:
- SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100); // class = warrior, gender = none, power = focus
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, CLASS_WARRIOR);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, GENDER_NONE);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_POWER_TYPE, POWER_FOCUS);
SetSheath(SHEATH_STATE_MELEE);
SetByteFlag(UNIT_FIELD_BYTES_2, 2, fields[9].GetBool() ? UNIT_CAN_BE_ABANDONED : UNIT_CAN_BE_RENAMED | UNIT_CAN_BE_ABANDONED);
@@ -226,7 +228,6 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
// this enables popup window (pet abandon, cancel)
SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS));
SetPower(POWER_HAPPINESS, fields[12].GetUInt32());
- setPowerType(POWER_FOCUS);
break;
default:
if (!IsPetGhoul())
@@ -822,7 +823,9 @@ bool Pet::CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map, uint32 phas
if (cinfo->type == CREATURE_TYPE_BEAST)
{
- SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, CLASS_WARRIOR);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, GENDER_NONE);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_POWER_TYPE, POWER_FOCUS);
SetSheath(SHEATH_STATE_MELEE);
SetByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED | UNIT_CAN_BE_ABANDONED);
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index a3602166edf..c58f2c940fc 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -96,6 +96,9 @@
#define SKILL_PERM_BONUS(x) int16(PAIR32_HIPART(x))
#define MAKE_SKILL_BONUS(t, p) MAKE_PAIR32(t, p)
+#define CINEMATIC_LOOKAHEAD (2 * IN_MILLISECONDS)
+#define CINEMATIC_UPDATEDIFF 500
+
enum CharacterFlags
{
CHARACTER_FLAG_NONE = 0x00000000,
@@ -535,6 +538,14 @@ Player::Player(WorldSession* session): Unit(true)
_activeCheats = CHEAT_NONE;
healthBeforeDuel = 0;
manaBeforeDuel = 0;
+
+ m_cinematicDiff = 0;
+ m_lastCinematicCheck = 0;
+ m_activeCinematicCameraId = 0;
+ m_cinematicCamera = nullptr;
+ m_remoteSightPosition = Position(0.0f, 0.0f, 0.0f);
+ m_CinematicObject = nullptr;
+
m_achievementMgr = new AchievementMgr(this);
m_reputationMgr = new ReputationMgr(this);
}
@@ -643,9 +654,10 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo
return false;
}
- uint32 RaceClassGender = (createInfo->Race) | (createInfo->Class << 8) | (createInfo->Gender << 16);
-
- SetUInt32Value(UNIT_FIELD_BYTES_0, (RaceClassGender | (powertype << 24)));
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE, createInfo->Race);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, createInfo->Class);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, createInfo->Gender);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_POWER_TYPE, powertype);
InitDisplayIds();
if (sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP)
{
@@ -658,13 +670,14 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo
SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1)); // -1 is default value
- SetUInt32Value(PLAYER_BYTES, (createInfo->Skin | (createInfo->Face << 8) | (createInfo->HairStyle << 16) | (createInfo->HairColor << 24)));
- SetUInt32Value(PLAYER_BYTES_2, (createInfo->FacialHair |
- (0x00 << 8) |
- (0x00 << 16) |
- (((GetSession()->IsARecruiter() || GetSession()->GetRecruiterId() != 0) ? REST_STATE_RAF_LINKED : REST_STATE_NOT_RAF_LINKED) << 24)));
- SetByteValue(PLAYER_BYTES_3, 0, createInfo->Gender);
- SetByteValue(PLAYER_BYTES_3, 3, 0); // BattlefieldArenaFaction (0 or 1)
+ SetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID, createInfo->Skin);
+ SetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_FACE_ID, createInfo->Face);
+ SetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_STYLE_ID, createInfo->HairStyle);
+ SetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_COLOR_ID, createInfo->HairColor);
+ SetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_FACIAL_STYLE, createInfo->FacialHair);
+ SetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_REST_STATE, (GetSession()->IsARecruiter() || GetSession()->GetRecruiterId() != 0) ? REST_STATE_RAF_LINKED : REST_STATE_NOT_RAF_LINKED);
+ SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER, createInfo->Gender);
+ SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_ARENA_FACTION, 0);
SetUInt32Value(PLAYER_GUILDID, 0);
SetUInt32Value(PLAYER_GUILDRANK, 0);
@@ -1179,7 +1192,7 @@ void Player::SetDrunkValue(uint8 newDrunkValue, uint32 itemId /*= 0*/)
m_invisibilityDetect.DelFlag(INVISIBILITY_DRUNK);
uint32 newDrunkenState = Player::GetDrunkenstateByValue(newDrunkValue);
- SetByteValue(PLAYER_BYTES_3, 1, newDrunkValue);
+ SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_INEBRIATION, newDrunkValue);
UpdateObjectVisibility();
if (!isSobering)
@@ -1222,7 +1235,15 @@ void Player::Update(uint32 p_time)
m_spellModTakingSpell = nullptr;
}
- //used to implement delayed far teleport
+ // Update cinematic location, if 500ms have passed and we're doing a cinematic now.
+ m_cinematicDiff += p_time;
+ if (m_cinematicCamera && m_activeCinematicCameraId && GetMSTimeDiffToNow(m_lastCinematicCheck) > CINEMATIC_UPDATEDIFF)
+ {
+ m_lastCinematicCheck = getMSTime();
+ UpdateCinematicLocation(p_time);
+ }
+
+ //used to implement delayed far teleports
SetCanDelayTeleport(true);
Unit::Update(p_time);
SetCanDelayTeleport(false);
@@ -2822,8 +2843,8 @@ void Player::GiveLevel(uint8 level)
{
++m_grantableLevels;
- if (!HasByteFlag(PLAYER_FIELD_BYTES, 1, 0x01))
- SetByteFlag(PLAYER_FIELD_BYTES, 1, 0x01);
+ if (!HasByteFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_RAF_GRANTABLE_LEVEL, 0x01))
+ SetByteFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_RAF_GRANTABLE_LEVEL, 0x01);
}
sScriptMgr->OnPlayerLevelChanged(this, oldLevel);
@@ -3841,7 +3862,7 @@ bool Player::Has310Flyer(bool checkAllSpells, uint32 excludeSpellId)
if (_spell_idx->second->skillId != SKILL_MOUNTS)
break; // We can break because mount spells belong only to one skillline (at least 310 flyers do)
- spellInfo = sSpellMgr->EnsureSpellInfo(itr->first);
+ spellInfo = sSpellMgr->AssertSpellInfo(itr->first);
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED &&
spellInfo->Effects[i].CalcValue() == 310)
@@ -3861,7 +3882,7 @@ void Player::RemoveArenaSpellCooldowns(bool removeActivePetCooldowns)
// remove cooldowns on spells that have < 10 min CD
GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool
{
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first);
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first);
return spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS && spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS;
}, true);
@@ -4789,7 +4810,7 @@ Corpse* Player::CreateCorpse()
// prevent the existence of 2 corpses for one player
SpawnCorpseBones();
- uint32 _pb, _pb2, _cfb1, _cfb2;
+ uint32 _cfb1, _cfb2;
Corpse* corpse = new Corpse((m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH) ? CORPSE_RESURRECTABLE_PVP : CORPSE_RESURRECTABLE_PVE);
SetPvPDeath(false);
@@ -4802,16 +4823,13 @@ Corpse* Player::CreateCorpse()
_corpseLocation.WorldRelocate(*this);
- _pb = GetUInt32Value(PLAYER_BYTES);
- _pb2 = GetUInt32Value(PLAYER_BYTES_2);
-
- uint8 skin = (uint8)(_pb);
- uint8 face = (uint8)(_pb >> 8);
- uint8 hairstyle = (uint8)(_pb >> 16);
- uint8 haircolor = (uint8)(_pb >> 24);
- uint8 facialhair = (uint8)(_pb2);
+ uint8 skin = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID);
+ uint8 face = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_FACE_ID);
+ uint8 hairstyle = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_STYLE_ID);
+ uint8 haircolor = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_COLOR_ID);
+ uint8 facialhair = GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_FACIAL_STYLE);
- _cfb1 = ((0x00) | (getRace() << 8) | (GetByteValue(PLAYER_BYTES_3, 0) << 16) | (skin << 24));
+ _cfb1 = ((0x00) | (getRace() << 8) | (GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER) << 16) | (skin << 24));
_cfb2 = ((face) | (hairstyle << 8) | (haircolor << 16) | (facialhair << 24));
corpse->SetUInt32Value(CORPSE_FIELD_BYTES_1, _cfb1);
@@ -6399,11 +6417,13 @@ void Player::SendDirectMessage(WorldPacket const* data) const
m_session->SendPacket(data);
}
-void Player::SendCinematicStart(uint32 CinematicSequenceId) const
+void Player::SendCinematicStart(uint32 CinematicSequenceId)
{
WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4);
data << uint32(CinematicSequenceId);
SendDirectMessage(&data);
+ if (const CinematicSequencesEntry* sequence = sCinematicSequencesStore.LookupEntry(CinematicSequenceId))
+ SetActiveCinematicCamera(sequence->cinematicCamera);
}
void Player::SendMovieStart(uint32 MovieId) const
@@ -10344,8 +10364,7 @@ InventoryResult Player::CanStoreItem_InBag(uint8 bag, ItemPosCountVec &dest, Ite
if (pItem2)
{
// can be merged at least partly
- uint8 res = pItem2->CanBeMergedPartlyWith(pProto);
- if (res != EQUIP_ERR_OK)
+ if (pItem2->CanBeMergedPartlyWith(pProto) != EQUIP_ERR_OK)
continue;
// descrease at current stacksize
@@ -10395,8 +10414,7 @@ InventoryResult Player::CanStoreItem_InInventorySlots(uint8 slot_begin, uint8 sl
if (pItem2)
{
// can be merged at least partly
- uint8 res = pItem2->CanBeMergedPartlyWith(pProto);
- if (res != EQUIP_ERR_OK)
+ if (pItem2->CanBeMergedPartlyWith(pProto) != EQUIP_ERR_OK)
continue;
// descrease at current stacksize
@@ -11074,7 +11092,7 @@ InventoryResult Player::CanStoreItems(Item** items, int count, uint32* itemLimit
continue;
// search free slot in bags
- for (int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; ++t)
+ for (uint8 t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; ++t)
{
if (Bag* bag = GetBagByPos(t))
{
@@ -12599,7 +12617,7 @@ void Player::DestroyConjuredItems(bool update)
Item* Player::GetItemByEntry(uint32 entry) const
{
// in inventory
- for (int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i)
+ for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i)
if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
if (pItem->GetEntry() == entry)
return pItem;
@@ -12609,14 +12627,14 @@ Item* Player::GetItemByEntry(uint32 entry) const
if (pItem->GetEntry() == entry)
return pItem;
- for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
+ for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
if (Bag* pBag = GetBagByPos(i))
for (uint32 j = 0; j < pBag->GetBagSize(); ++j)
if (Item* pItem = pBag->GetItemByPos(j))
if (pItem->GetEntry() == entry)
return pItem;
- for (int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; ++i)
+ for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; ++i)
if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
if (pItem->GetEntry() == entry)
return pItem;
@@ -13809,8 +13827,8 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
TC_LOG_ERROR("entities.player", "Player::ApplyEnchantment: Unknown item enchantment (ID: %u, DisplayType: %u) for player '%s' (%s)",
enchant_id, enchant_display_type, GetName().c_str(), GetGUID().ToString().c_str());
break;
- } /*switch (enchant_display_type)*/
- } /*for*/
+ }
+ }
}
// visualize enchantment at player and equipped items
@@ -16861,12 +16879,9 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
return false;
}
- // overwrite some data fields
- uint32 bytes0 = 0;
- bytes0 |= fields[3].GetUInt8(); // race
- bytes0 |= fields[4].GetUInt8() << 8; // class
- bytes0 |= gender << 16; // gender
- SetUInt32Value(UNIT_FIELD_BYTES_0, bytes0);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE, fields[3].GetUInt8());
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, fields[4].GetUInt8());
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, gender);
// check if race/class combination is valid
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
@@ -16893,25 +16908,25 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
money = MAX_MONEY_AMOUNT;
SetMoney(money);
- SetByteValue(PLAYER_BYTES, 0, fields[9].GetUInt8());
- SetByteValue(PLAYER_BYTES, 1, fields[10].GetUInt8());
- SetByteValue(PLAYER_BYTES, 2, fields[11].GetUInt8());
- SetByteValue(PLAYER_BYTES, 3, fields[12].GetUInt8());
- SetByteValue(PLAYER_BYTES_2, 0, fields[13].GetUInt8());
- SetByteValue(PLAYER_BYTES_2, 2, fields[14].GetUInt8());
- SetByteValue(PLAYER_BYTES_2, 3, fields[15].GetUInt8());
- SetByteValue(PLAYER_BYTES_3, 0, fields[5].GetUInt8());
- SetByteValue(PLAYER_BYTES_3, 1, fields[54].GetUInt8());
+ SetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID, fields[9].GetUInt8());
+ SetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_FACE_ID, fields[10].GetUInt8());
+ SetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_STYLE_ID, fields[11].GetUInt8());
+ SetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_COLOR_ID, fields[12].GetUInt8());
+ SetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_FACIAL_STYLE, fields[13].GetUInt8());
+ SetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_BANK_BAG_SLOTS, fields[14].GetUInt8());
+ SetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_REST_STATE, fields[15].GetUInt8());
+ SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER, fields[5].GetUInt8());
+ SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_INEBRIATION, fields[54].GetUInt8());
if (!ValidateAppearance(
fields[3].GetUInt8(), // race
fields[4].GetUInt8(), // class
gender,
- GetByteValue(PLAYER_BYTES, 2),
- GetByteValue(PLAYER_BYTES, 3),
- GetByteValue(PLAYER_BYTES, 1),
- GetByteValue(PLAYER_BYTES_2, 0),
- GetByteValue(PLAYER_BYTES, 0)))
+ GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_STYLE_ID),
+ GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_COLOR_ID),
+ GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_FACE_ID),
+ GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_FACIAL_STYLE),
+ GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID)))
{
TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has wrong Appearance values (Hair/Skin/Color), can't load.", guid.ToString().c_str());
return false;
@@ -16925,7 +16940,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
SetUInt32Value(PLAYER_AMMO_ID, fields[68].GetUInt32());
// set which actionbars the client has active - DO NOT REMOVE EVER AGAIN (can be changed though, if it does change fieldwise)
- SetByteValue(PLAYER_FIELD_BYTES, 2, fields[70].GetUInt8());
+ SetByteValue(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_ACTION_BAR_TOGGLES, fields[70].GetUInt8());
InitDisplayIds();
@@ -17508,7 +17523,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_REFER_A_FRIEND);
if (m_grantableLevels > 0)
- SetByteValue(PLAYER_FIELD_BYTES, 1, 0x01);
+ SetByteValue(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_RAF_GRANTABLE_LEVEL, 0x01);
_LoadDeclinedNames(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_DECLINED_NAMES));
@@ -17715,7 +17730,7 @@ void Player::LoadCorpse(PreparedQueryResult result)
{
Field* fields = result->Fetch();
_corpseLocation.WorldRelocate(fields[0].GetUInt16(), fields[1].GetFloat(), fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat());
- ApplyModFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTE_RELEASE_TIMER, !sMapStore.LookupEntry(_corpseLocation.GetMapId())->Instanceable());
+ ApplyModByteFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_FLAGS, PLAYER_FIELD_BYTE_RELEASE_TIMER, !sMapStore.LookupEntry(_corpseLocation.GetMapId())->Instanceable());
}
else
ResurrectPlayer(0.5f);
@@ -17751,7 +17766,7 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
ObjectGuid::LowType bagGuid = fields[11].GetUInt32();
uint8 slot = fields[12].GetUInt8();
- uint8 err = EQUIP_ERR_OK;
+ InventoryResult err = EQUIP_ERR_OK;
// Item is not in bag
if (!bagGuid)
{
@@ -17827,7 +17842,7 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
else
{
TC_LOG_ERROR("entities.player", "Player::_LoadInventory: Player '%s' (%s) has item (%s, entry: %u) which can't be loaded into inventory (Bag %u, slot: %u) by reason %u. Item will be sent by mail.",
- GetName().c_str(), GetGUID().ToString().c_str(), item->GetGUID().ToString().c_str(), item->GetEntry(), bagGuid, slot, err);
+ GetName().c_str(), GetGUID().ToString().c_str(), item->GetGUID().ToString().c_str(), item->GetEntry(), bagGuid, slot, uint32(err));
item->DeleteFromInventoryDB(trans);
problematicItems.push_back(item);
}
@@ -18949,17 +18964,17 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setString(index++, GetName());
stmt->setUInt8(index++, getRace());
stmt->setUInt8(index++, getClass());
- stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_3, 0)); // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER)); // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect
stmt->setUInt8(index++, getLevel());
stmt->setUInt32(index++, GetUInt32Value(PLAYER_XP));
stmt->setUInt32(index++, GetMoney());
- stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 0));
- stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 1));
- stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 2));
- stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 3));
- stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 0));
- stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 2));
- stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 3));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_FACE_ID));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_STYLE_ID));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_COLOR_ID));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_FACIAL_STYLE));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_BANK_BAG_SLOTS));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_REST_STATE));
stmt->setUInt32(index++, GetUInt32Value(PLAYER_FLAGS));
stmt->setUInt16(index++, (uint16)GetMapId());
stmt->setUInt32(index++, (uint32)GetInstanceId());
@@ -19049,7 +19064,7 @@ void Player::SaveToDB(bool create /*=false*/)
ss << GetUInt32Value(PLAYER__FIELD_KNOWN_TITLES + i) << ' ';
stmt->setString(index++, ss.str());
- stmt->setUInt8(index++, GetByteValue(PLAYER_FIELD_BYTES, 2));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_ACTION_BAR_TOGGLES));
stmt->setUInt32(index, m_grantableLevels);
}
else
@@ -19059,17 +19074,17 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setString(index++, GetName());
stmt->setUInt8(index++, getRace());
stmt->setUInt8(index++, getClass());
- stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_3, 0)); // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER)); // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect
stmt->setUInt8(index++, getLevel());
stmt->setUInt32(index++, GetUInt32Value(PLAYER_XP));
stmt->setUInt32(index++, GetMoney());
- stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 0));
- stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 1));
- stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 2));
- stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 3));
- stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 0));
- stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 2));
- stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 3));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_FACE_ID));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_STYLE_ID));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_COLOR_ID));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_FACIAL_STYLE));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_BANK_BAG_SLOTS));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_REST_STATE));
stmt->setUInt32(index++, GetUInt32Value(PLAYER_FLAGS));
if (!IsBeingTeleported())
@@ -19174,7 +19189,7 @@ void Player::SaveToDB(bool create /*=false*/)
ss << GetUInt32Value(PLAYER__FIELD_KNOWN_TITLES + i) << ' ';
stmt->setString(index++, ss.str());
- stmt->setUInt8(index++, GetByteValue(PLAYER_FIELD_BYTES, 2));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_ACTION_BAR_TOGGLES));
stmt->setUInt32(index++, m_grantableLevels);
stmt->setUInt8(index++, IsInWorld() && !GetSession()->PlayerLogout() ? 1 : 0);
@@ -20894,13 +20909,13 @@ void Player::SetRestBonus(float rest_bonus_new)
// update data for client
if ((GetsRecruitAFriendBonus(true) && (GetSession()->IsARecruiter() || GetSession()->GetRecruiterId() != 0)))
- SetByteValue(PLAYER_BYTES_2, 3, REST_STATE_RAF_LINKED);
+ SetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_REST_STATE, REST_STATE_RAF_LINKED);
else
{
if (m_rest_bonus > 10)
- SetByteValue(PLAYER_BYTES_2, 3, REST_STATE_RESTED);
+ SetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_REST_STATE, REST_STATE_RESTED);
else if (m_rest_bonus <= 1)
- SetByteValue(PLAYER_BYTES_2, 3, REST_STATE_NOT_RAF_LINKED);
+ SetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_REST_STATE, REST_STATE_NOT_RAF_LINKED);
}
//RestTickUpdate
@@ -21234,7 +21249,7 @@ void Player::InitDisplayIds()
return;
}
- uint8 gender = GetByteValue(PLAYER_BYTES_3, 0);
+ uint8 gender = GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER);
switch (gender)
{
case GENDER_FEMALE:
@@ -21842,7 +21857,7 @@ void Player::SetBattlegroundEntryPoint()
void Player::SetBGTeam(uint32 team)
{
m_bgData.bgTeam = team;
- SetByteValue(PLAYER_BYTES_3, 3, uint8(team == ALLIANCE ? 1 : 0));
+ SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_ARENA_FACTION, uint8(team == ALLIANCE ? 1 : 0));
}
uint32 Player::GetBGTeam() const
@@ -22543,7 +22558,7 @@ void Player::ApplyEquipCooldown(Item* pItem)
continue;
// Don't replace longer cooldowns by equip cooldown if we have any.
- if (GetSpellHistory()->GetRemainingCooldown(sSpellMgr->EnsureSpellInfo(spellData.SpellId)) > 30 * IN_MILLISECONDS)
+ if (GetSpellHistory()->GetRemainingCooldown(sSpellMgr->AssertSpellInfo(spellData.SpellId)) > 30 * IN_MILLISECONDS)
continue;
GetSpellHistory()->AddCooldown(spellData.SpellId, pItem->GetEntry(), std::chrono::seconds(30));
@@ -23237,8 +23252,7 @@ void Player::AutoUnequipOffhandIfNeed(bool force /*= false*/)
return;
ItemPosCountVec off_dest;
- uint8 off_msg = CanStoreItem(NULL_BAG, NULL_SLOT, off_dest, offItem, false);
- if (off_msg == EQUIP_ERR_OK)
+ if (CanStoreItem(NULL_BAG, NULL_SLOT, off_dest, offItem, false) == EQUIP_ERR_OK)
{
RemoveItem(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND, true);
StoreItem(off_dest, offItem, true);
@@ -24064,10 +24078,10 @@ uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 n
if (level > GT_MAX_LEVEL)
level = GT_MAX_LEVEL; // max level in this dbc
- uint8 hairstyle = GetByteValue(PLAYER_BYTES, 2);
- uint8 haircolor = GetByteValue(PLAYER_BYTES, 3);
- uint8 facialhair = GetByteValue(PLAYER_BYTES_2, 0);
- uint8 skincolor = GetByteValue(PLAYER_BYTES, 0);
+ uint8 hairstyle = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_STYLE_ID);
+ uint8 haircolor = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_COLOR_ID);
+ uint8 facialhair = GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_FACIAL_STYLE);
+ uint8 skincolor = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID);
if ((hairstyle == newhairstyle) && (haircolor == newhaircolor) && (facialhair == newfacialhair) && (!newSkin || (newSkin->hair_id == skincolor)))
return 0;
@@ -26097,6 +26111,9 @@ bool Player::SetCanFly(bool apply, bool packetOnly /*= false*/)
if (!packetOnly && !Unit::SetCanFly(apply))
return false;
+ if (!apply)
+ SetFallInformation(0, GetPositionZ());
+
WorldPacket data(apply ? SMSG_MOVE_SET_CAN_FLY : SMSG_MOVE_UNSET_CAN_FLY, 12);
data << GetPackGUID();
data << uint32(0); //! movement counter
@@ -26193,6 +26210,125 @@ float Player::GetCollisionHeight(bool mounted) const
}
}
+void Player::BeginCinematic()
+{
+ // Sanity check for active camera set
+ if (m_activeCinematicCameraId == 0)
+ return;
+
+ auto itr = sFlyByCameraStore.find(m_activeCinematicCameraId);
+ if (itr != sFlyByCameraStore.end())
+ {
+ // Initialize diff, and set camera
+ m_cinematicDiff = 0;
+ m_cinematicCamera = &itr->second;
+
+ auto camitr = m_cinematicCamera->begin();
+ if (camitr != m_cinematicCamera->end())
+ {
+ Position pos(camitr->locations.x, camitr->locations.y, camitr->locations.z, camitr->locations.w);
+ if (!pos.IsPositionValid())
+ return;
+
+ m_mapRef->LoadGrid(camitr->locations.x, camitr->locations.y);
+ m_CinematicObject = SummonCreature(VISUAL_WAYPOINT, pos.m_positionX, pos.m_positionY, pos.m_positionZ, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000);
+ if (m_CinematicObject)
+ {
+ m_CinematicObject->setActive(true);
+ SetViewpoint(m_CinematicObject, true);
+ }
+ }
+ }
+}
+
+void Player::EndCinematic()
+{
+ m_cinematicDiff = 0;
+ m_cinematicCamera = nullptr;
+ m_activeCinematicCameraId = 0;
+ if (m_CinematicObject)
+ {
+ if (m_seer && m_seer == m_CinematicObject)
+ SetViewpoint(m_CinematicObject, false);
+ m_CinematicObject->AddObjectToRemoveList();
+ }
+}
+
+void Player::UpdateCinematicLocation(uint32 /*diff*/)
+{
+ Position lastPosition;
+ uint32 lastTimestamp = 0;
+ Position nextPosition;
+ uint32 nextTimestamp = 0;
+
+ if (m_cinematicCamera->size() == 0)
+ return;
+
+ // Obtain direction of travel
+ for (FlyByCamera cam : *m_cinematicCamera)
+ {
+ if (cam.timeStamp > m_cinematicDiff)
+ {
+ nextPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w);
+ nextTimestamp = cam.timeStamp;
+ break;
+ }
+ lastPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w);
+ lastTimestamp = cam.timeStamp;
+ }
+ float angle = lastPosition.GetAngle(&nextPosition);
+ angle -= lastPosition.GetOrientation();
+ if (angle < 0)
+ angle += 2 * float(M_PI);
+
+ // Look for position around 2 second ahead of us.
+ int32 workDiff = m_cinematicDiff;
+
+ // Modify result based on camera direction (Humans for example, have the camera point behind)
+ workDiff += static_cast<int32>(float(CINEMATIC_LOOKAHEAD) * cos(angle));
+
+ // Get an iterator to the last entry in the cameras, to make sure we don't go beyond the end
+ FlyByCameraCollection::const_reverse_iterator endItr = m_cinematicCamera->rbegin();
+ if (endItr != m_cinematicCamera->rend() && workDiff > static_cast<int32>(endItr->timeStamp))
+ workDiff = endItr->timeStamp;
+
+ // Never try to go back in time before the start of cinematic!
+ if (workDiff < 0)
+ workDiff = m_cinematicDiff;
+
+ // Obtain the previous and next waypoint based on timestamp
+ for (FlyByCamera cam : *m_cinematicCamera)
+ {
+ if (static_cast<int32>(cam.timeStamp) >= workDiff)
+ {
+ nextPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w);
+ nextTimestamp = cam.timeStamp;
+ break;
+ }
+ lastPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w);
+ lastTimestamp = cam.timeStamp;
+ }
+
+ // Never try to go beyond the end of the cinematic
+ if (workDiff > static_cast<int32>(nextTimestamp))
+ workDiff = static_cast<int32>(nextTimestamp);
+
+ // Interpolate the position for this moment in time (or the adjusted moment in time)
+ uint32 timeDiff = nextTimestamp - lastTimestamp;
+ uint32 interDiff = workDiff - lastTimestamp;
+ float xDiff = nextPosition.m_positionX - lastPosition.m_positionX;
+ float yDiff = nextPosition.m_positionY - lastPosition.m_positionY;
+ float zDiff = nextPosition.m_positionZ - lastPosition.m_positionZ;
+ Position interPosition(lastPosition.m_positionX + (xDiff * (float(interDiff)/float(timeDiff))), lastPosition.m_positionY +
+ (yDiff * (float(interDiff) / float(timeDiff))), lastPosition.m_positionZ + (zDiff * (float(interDiff) / float(timeDiff))));
+
+ // Advance (at speed) to this position. The remote sight object is used
+ // to send update information to player in cinematic
+ if (m_CinematicObject && interPosition.IsPositionValid())
+ m_CinematicObject->MonsterMoveWithSpeed(interPosition.m_positionX, interPosition.m_positionY, interPosition.m_positionZ, 200.0f, false, true);
+}
+
+
std::string Player::GetMapAreaAndZoneString() const
{
uint32 areaId = GetAreaId();
@@ -26288,7 +26424,7 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
case SUMMON_PET:
// this enables pet details window (Shift+P)
pet->GetCharmInfo()->SetPetNumber(pet_number, true);
- pet->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
+ pet->SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, CLASS_MAGE);
pet->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
pet->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000);
pet->SetFullHealth();
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 91a4a403fab..fd0fac69674 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -315,7 +315,7 @@ enum RuneCooldowns
RUNE_MISS_COOLDOWN = 1500 // cooldown applied on runes when the spell misses
};
-enum RuneType
+enum RuneType : uint8
{
RUNE_BLOOD = 0,
RUNE_UNHOLY = 1,
@@ -415,50 +415,48 @@ enum PlayerFlags
PLAYER_FLAGS_UNK31 = 0x80000000
};
-// used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1<<bit_index) without (-1)
-// can't use enum for uint64 values
-#define PLAYER_TITLE_DISABLED UI64LIT(0x0000000000000000)
-#define PLAYER_TITLE_NONE UI64LIT(0x0000000000000001)
-#define PLAYER_TITLE_PRIVATE UI64LIT(0x0000000000000002) // 1
-#define PLAYER_TITLE_CORPORAL UI64LIT(0x0000000000000004) // 2
-#define PLAYER_TITLE_SERGEANT_A UI64LIT(0x0000000000000008) // 3
-#define PLAYER_TITLE_MASTER_SERGEANT UI64LIT(0x0000000000000010) // 4
-#define PLAYER_TITLE_SERGEANT_MAJOR UI64LIT(0x0000000000000020) // 5
-#define PLAYER_TITLE_KNIGHT UI64LIT(0x0000000000000040) // 6
-#define PLAYER_TITLE_KNIGHT_LIEUTENANT UI64LIT(0x0000000000000080) // 7
-#define PLAYER_TITLE_KNIGHT_CAPTAIN UI64LIT(0x0000000000000100) // 8
-#define PLAYER_TITLE_KNIGHT_CHAMPION UI64LIT(0x0000000000000200) // 9
-#define PLAYER_TITLE_LIEUTENANT_COMMANDER UI64LIT(0x0000000000000400) // 10
-#define PLAYER_TITLE_COMMANDER UI64LIT(0x0000000000000800) // 11
-#define PLAYER_TITLE_MARSHAL UI64LIT(0x0000000000001000) // 12
-#define PLAYER_TITLE_FIELD_MARSHAL UI64LIT(0x0000000000002000) // 13
-#define PLAYER_TITLE_GRAND_MARSHAL UI64LIT(0x0000000000004000) // 14
-#define PLAYER_TITLE_SCOUT UI64LIT(0x0000000000008000) // 15
-#define PLAYER_TITLE_GRUNT UI64LIT(0x0000000000010000) // 16
-#define PLAYER_TITLE_SERGEANT_H UI64LIT(0x0000000000020000) // 17
-#define PLAYER_TITLE_SENIOR_SERGEANT UI64LIT(0x0000000000040000) // 18
-#define PLAYER_TITLE_FIRST_SERGEANT UI64LIT(0x0000000000080000) // 19
-#define PLAYER_TITLE_STONE_GUARD UI64LIT(0x0000000000100000) // 20
-#define PLAYER_TITLE_BLOOD_GUARD UI64LIT(0x0000000000200000) // 21
-#define PLAYER_TITLE_LEGIONNAIRE UI64LIT(0x0000000000400000) // 22
-#define PLAYER_TITLE_CENTURION UI64LIT(0x0000000000800000) // 23
-#define PLAYER_TITLE_CHAMPION UI64LIT(0x0000000001000000) // 24
-#define PLAYER_TITLE_LIEUTENANT_GENERAL UI64LIT(0x0000000002000000) // 25
-#define PLAYER_TITLE_GENERAL UI64LIT(0x0000000004000000) // 26
-#define PLAYER_TITLE_WARLORD UI64LIT(0x0000000008000000) // 27
-#define PLAYER_TITLE_HIGH_WARLORD UI64LIT(0x0000000010000000) // 28
-#define PLAYER_TITLE_GLADIATOR UI64LIT(0x0000000020000000) // 29
-#define PLAYER_TITLE_DUELIST UI64LIT(0x0000000040000000) // 30
-#define PLAYER_TITLE_RIVAL UI64LIT(0x0000000080000000) // 31
-#define PLAYER_TITLE_CHALLENGER UI64LIT(0x0000000100000000) // 32
-#define PLAYER_TITLE_SCARAB_LORD UI64LIT(0x0000000200000000) // 33
-#define PLAYER_TITLE_CONQUEROR UI64LIT(0x0000000400000000) // 34
-#define PLAYER_TITLE_JUSTICAR UI64LIT(0x0000000800000000) // 35
-#define PLAYER_TITLE_CHAMPION_OF_THE_NAARU UI64LIT(0x0000001000000000) // 36
-#define PLAYER_TITLE_MERCILESS_GLADIATOR UI64LIT(0x0000002000000000) // 37
-#define PLAYER_TITLE_OF_THE_SHATTERED_SUN UI64LIT(0x0000004000000000) // 38
-#define PLAYER_TITLE_HAND_OF_ADAL UI64LIT(0x0000008000000000) // 39
-#define PLAYER_TITLE_VENGEFUL_GLADIATOR UI64LIT(0x0000010000000000) // 40
+enum PlayerBytesOffsets
+{
+ PLAYER_BYTES_OFFSET_SKIN_ID = 0,
+ PLAYER_BYTES_OFFSET_FACE_ID = 1,
+ PLAYER_BYTES_OFFSET_HAIR_STYLE_ID = 2,
+ PLAYER_BYTES_OFFSET_HAIR_COLOR_ID = 3
+};
+
+enum PlayerBytes2Offsets
+{
+ PLAYER_BYTES_2_OFFSET_FACIAL_STYLE = 0,
+ PLAYER_BYTES_2_OFFSET_PARTY_TYPE = 1,
+ PLAYER_BYTES_2_OFFSET_BANK_BAG_SLOTS = 2,
+ PLAYER_BYTES_2_OFFSET_REST_STATE = 3
+};
+
+enum PlayerBytes3Offsets
+{
+ PLAYER_BYTES_3_OFFSET_GENDER = 0,
+ PLAYER_BYTES_3_OFFSET_INEBRIATION = 1,
+ PLAYER_BYTES_3_OFFSET_PVP_TITLE = 2,
+ PLAYER_BYTES_3_OFFSET_ARENA_FACTION = 3
+};
+
+enum PlayerFieldBytesOffsets
+{
+ PLAYER_FIELD_BYTES_OFFSET_FLAGS = 0,
+ PLAYER_FIELD_BYTES_OFFSET_RAF_GRANTABLE_LEVEL = 1,
+ PLAYER_FIELD_BYTES_OFFSET_ACTION_BAR_TOGGLES = 2,
+ PLAYER_FIELD_BYTES_OFFSET_LIFETIME_MAX_PVP_RANK = 3
+};
+
+enum PlayerFieldBytes2Offsets
+{
+ PLAYER_FIELD_BYTES_2_OFFSET_OVERRIDE_SPELLS_ID = 0, // uint16!
+ PLAYER_FIELD_BYTES_2_OFFSET_IGNORE_POWER_REGEN_PREDICTION_MASK = 2,
+ PLAYER_FIELD_BYTES_2_OFFSET_AURA_VISION = 3
+};
+
+static_assert((PLAYER_FIELD_BYTES_2_OFFSET_OVERRIDE_SPELLS_ID & 1) == 0, "PLAYER_FIELD_BYTES_2_OFFSET_OVERRIDE_SPELLS_ID must be aligned to 2 byte boundary");
+
+#define PLAYER_BYTES_2_OVERRIDE_SPELLS_UINT16_OFFSET (PLAYER_FIELD_BYTES_2_OFFSET_OVERRIDE_SPELLS_ID / 2)
#define KNOWN_TITLES_SIZE 3
#define MAX_TITLE_INDEX (KNOWN_TITLES_SIZE*64) // 3 uint64 fields
@@ -584,7 +582,7 @@ enum PlayerSlots
#define INVENTORY_SLOT_BAG_0 255
-enum EquipmentSlots // 19 slots
+enum EquipmentSlots : uint8 // 19 slots
{
EQUIPMENT_SLOT_START = 0,
EQUIPMENT_SLOT_HEAD = 0,
@@ -609,13 +607,13 @@ enum EquipmentSlots // 19 slots
EQUIPMENT_SLOT_END = 19
};
-enum InventorySlots // 4 slots
+enum InventorySlots : uint8 // 4 slots
{
INVENTORY_SLOT_BAG_START = 19,
INVENTORY_SLOT_BAG_END = 23
};
-enum InventoryPackSlots // 16 slots
+enum InventoryPackSlots : uint8 // 16 slots
{
INVENTORY_SLOT_ITEM_START = 23,
INVENTORY_SLOT_ITEM_END = 39
@@ -640,7 +638,7 @@ enum BuyBackSlots // 12 slots
BUYBACK_SLOT_END = 86
};
-enum KeyRingSlots // 32 slots
+enum KeyRingSlots : uint8 // 32 slots
{
KEYRING_SLOT_START = 86,
KEYRING_SLOT_END = 118
@@ -750,7 +748,7 @@ enum TeleportToOptions
};
/// Type of environmental damages
-enum EnviromentalDamage
+enum EnviromentalDamage : uint8
{
DAMAGE_EXHAUSTED = 0,
DAMAGE_DROWNING = 1,
@@ -902,7 +900,7 @@ enum ReferAFriendError
ERR_REFER_A_FRIEND_SUMMON_OFFLINE_S = 0x0D
};
-enum PlayerRestState
+enum PlayerRestState : uint8
{
REST_STATE_RESTED = 0x01,
REST_STATE_NOT_RAF_LINKED = 0x02,
@@ -1185,8 +1183,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
static bool IsBankPos(uint8 bag, uint8 slot);
bool IsValidPos(uint16 pos, bool explicit_pos) const { return IsValidPos(pos >> 8, pos & 255, explicit_pos); }
bool IsValidPos(uint8 bag, uint8 slot, bool explicit_pos) const;
- uint8 GetBankBagSlotCount() const { return GetByteValue(PLAYER_BYTES_2, 2); }
- void SetBankBagSlotCount(uint8 count) { SetByteValue(PLAYER_BYTES_2, 2, count); }
+ uint8 GetBankBagSlotCount() const { return GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_BANK_BAG_SLOTS); }
+ void SetBankBagSlotCount(uint8 count) { SetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_BANK_BAG_SLOTS, count); }
bool HasItemCount(uint32 item, uint32 count = 1, bool inBankAlso = false) const;
bool HasItemFitToSpellRequirements(SpellInfo const* spellInfo, Item const* ignoreItem = nullptr) const;
bool CanNoReagentCast(SpellInfo const* spellInfo) const;
@@ -1911,7 +1909,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
//End of PvP System
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId = 0);
- uint8 GetDrunkValue() const { return GetByteValue(PLAYER_BYTES_3, 1); }
+ uint8 GetDrunkValue() const { return GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_INEBRIATION); }
static DrunkenState GetDrunkenstateByValue(uint8 value);
uint32 GetDeathTimer() const { return m_deathTimer; }
@@ -2131,7 +2129,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void ResummonPetTemporaryUnSummonedIfAny();
bool IsPetNeedBeTemporaryUnsummoned() const;
- void SendCinematicStart(uint32 CinematicSequenceId) const;
+ void SendCinematicStart(uint32 CinematicSequenceId);
void SendMovieStart(uint32 MovieId) const;
/*********************************************************/
@@ -2267,6 +2265,17 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
std::string GetMapAreaAndZoneString() const;
std::string GetCoordsMapAreaAndZoneString() const;
+ // Cinematic camera data and remote sight functions
+ uint32 GetActiveCinematicCamera() const { return m_activeCinematicCameraId; }
+ void SetActiveCinematicCamera(uint32 cinematicCameraId = 0) { m_activeCinematicCameraId = cinematicCameraId; }
+ bool IsOnCinematic() const { return (m_cinematicCamera != nullptr); }
+ void BeginCinematic();
+ void EndCinematic();
+ void UpdateCinematicLocation(uint32 diff);
+
+ std::string GetMapAreaAndZoneString();
+ std::string GetCoordsMapAreaAndZoneString();
+
protected:
// Gamemaster whisper whitelist
GuidList WhisperList;
@@ -2592,6 +2601,14 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
uint32 manaBeforeDuel;
WorldLocation _corpseLocation;
+
+ // Remote location information
+ uint32 m_cinematicDiff;
+ uint32 m_lastCinematicCheck;
+ uint32 m_activeCinematicCameraId;
+ FlyByCameraCollection* m_cinematicCamera;
+ Position m_remoteSightPosition;
+ Creature* m_CinematicObject;
};
TC_GAME_API void AddItemsSetItem(Player* player, Item* item);
diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp
index a8e13a9f7db..82792a49c96 100644
--- a/src/server/game/Entities/Unit/StatSystem.cpp
+++ b/src/server/game/Entities/Unit/StatSystem.cpp
@@ -1152,7 +1152,7 @@ bool Guardian::UpdateStats(Stats stat)
if (itr != ToPet()->m_spells.end()) // If pet has Wild Hunt
{
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
AddPct(mod, spellInfo->Effects[EFFECT_0].CalcValue());
}
}
@@ -1321,7 +1321,7 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged)
if (itr != ToPet()->m_spells.end()) // If pet has Wild Hunt
{
- SpellInfo const* sProto = sSpellMgr->EnsureSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
+ SpellInfo const* sProto = sSpellMgr->AssertSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
mod += CalculatePct(1.0f, sProto->Effects[1].CalcValue());
}
}
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 912f0a75ab3..41f6f02b32b 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -8715,7 +8715,7 @@ void Unit::setPowerType(Powers new_powertype)
if (getPowerType() == new_powertype)
return;
- SetByteValue(UNIT_FIELD_BYTES_0, 3, new_powertype);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_POWER_TYPE, new_powertype);
if (GetTypeId() == TYPEID_PLAYER)
{
@@ -14721,7 +14721,7 @@ void Unit::SendMovementFlagUpdate(bool self /* = false */)
bool Unit::IsSitState() const
{
- uint8 s = getStandState();
+ uint8 s = GetStandState();
return
s == UNIT_STAND_STATE_SIT_CHAIR || s == UNIT_STAND_STATE_SIT_LOW_CHAIR ||
s == UNIT_STAND_STATE_SIT_MEDIUM_CHAIR || s == UNIT_STAND_STATE_SIT_HIGH_CHAIR ||
@@ -14730,7 +14730,7 @@ bool Unit::IsSitState() const
bool Unit::IsStandState() const
{
- uint8 s = getStandState();
+ uint8 s = GetStandState();
return !IsSitState() && s != UNIT_STAND_STATE_SLEEP && s != UNIT_STAND_STATE_KNEEL;
}
@@ -14767,7 +14767,7 @@ void Unit::SetDisplayId(uint32 modelId)
SetUInt32Value(UNIT_FIELD_DISPLAYID, modelId);
// Set Gender by modelId
if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(modelId))
- SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, minfo->gender);
}
void Unit::RestoreDisplayId()
@@ -16078,7 +16078,7 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au
if (cinfo && cinfo->type == CREATURE_TYPE_DEMON)
{
// to prevent client crash
- SetByteValue(UNIT_FIELD_BYTES_0, 1, (uint8)CLASS_MAGE);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, (uint8)CLASS_MAGE);
// just to enable stat window
if (GetCharmInfo())
@@ -16180,7 +16180,7 @@ void Unit::RemoveCharmedBy(Unit* charmer)
CreatureTemplate const* cinfo = ToCreature()->GetCreatureTemplate();
if (cinfo && cinfo->type == CREATURE_TYPE_DEMON)
{
- SetByteValue(UNIT_FIELD_BYTES_0, 1, uint8(cinfo->unit_class));
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, uint8(cinfo->unit_class));
if (GetCharmInfo())
GetCharmInfo()->SetPetNumber(0, true);
else
@@ -16698,7 +16698,7 @@ uint32 Unit::GetModelForForm(ShapeshiftForm form) const
// Based on Hair color
if (getRace() == RACE_NIGHTELF)
{
- uint8 hairColor = GetByteValue(PLAYER_BYTES, 3);
+ uint8 hairColor = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_COLOR_ID);
switch (hairColor)
{
case 7: // Violet
@@ -16719,7 +16719,7 @@ uint32 Unit::GetModelForForm(ShapeshiftForm form) const
// Based on Skin color
else if (getRace() == RACE_TAUREN)
{
- uint8 skinColor = GetByteValue(PLAYER_BYTES, 0);
+ uint8 skinColor = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID);
// Male
if (getGender() == GENDER_MALE)
{
@@ -16778,7 +16778,7 @@ uint32 Unit::GetModelForForm(ShapeshiftForm form) const
// Based on Hair color
if (getRace() == RACE_NIGHTELF)
{
- uint8 hairColor = GetByteValue(PLAYER_BYTES, 3);
+ uint8 hairColor = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_COLOR_ID);
switch (hairColor)
{
case 0: // Green
@@ -16798,7 +16798,7 @@ uint32 Unit::GetModelForForm(ShapeshiftForm form) const
// Based on Skin color
else if (getRace() == RACE_TAUREN)
{
- uint8 skinColor = GetByteValue(PLAYER_BYTES, 0);
+ uint8 skinColor = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID);
// Male
if (getGender() == GENDER_MALE)
{
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 4841cac84cf..9255ce039f3 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -190,6 +190,30 @@ enum UnitStandFlags
UNIT_STAND_FLAGS_ALL = 0xFF
};
+enum UnitBytes0Offsets
+{
+ UNIT_BYTES_0_OFFSET_RACE = 0,
+ UNIT_BYTES_0_OFFSET_CLASS = 1,
+ UNIT_BYTES_0_OFFSET_GENDER = 2,
+ UNIT_BYTES_0_OFFSET_POWER_TYPE = 3,
+};
+
+enum UnitBytes1Offsets
+{
+ UNIT_BYTES_1_OFFSET_STAND_STATE = 0,
+ UNIT_BYTES_1_OFFSET_PET_TALENTS = 1,
+ UNIT_BYTES_1_OFFSET_VIS_FLAG = 2,
+ UNIT_BYTES_1_OFFSET_ANIM_TIER = 3
+};
+
+enum UnitBytes2Offsets
+{
+ UNIT_BYTES_2_OFFSET_SHEATH_STATE = 0,
+ UNIT_BYTES_2_OFFSET_PVP_FLAG = 1,
+ UNIT_BYTES_2_OFFSET_PET_FLAG = 2,
+ UNIT_BYTES_2_OFFSET_SHAPESHIFT = 3,
+};
+
// byte flags value (UNIT_FIELD_BYTES_1, 3)
enum UnitBytes1_Flags
{
@@ -536,7 +560,7 @@ enum UnitMoveType
TC_GAME_API extern float baseMoveSpeed[MAX_MOVE_TYPE];
TC_GAME_API extern float playerBaseMoveSpeed[MAX_MOVE_TYPE];
-enum WeaponAttackType
+enum WeaponAttackType : uint8
{
BASE_ATTACK = 0,
OFF_ATTACK = 1,
@@ -1043,7 +1067,7 @@ enum ReactStates
REACT_AGGRESSIVE = 2
};
-enum CommandStates
+enum CommandStates : uint8
{
COMMAND_STAY = 0,
COMMAND_FOLLOW = 1,
@@ -1314,11 +1338,11 @@ class TC_GAME_API Unit : public WorldObject
uint8 getLevel() const { return uint8(GetUInt32Value(UNIT_FIELD_LEVEL)); }
uint8 getLevelForTarget(WorldObject const* /*target*/) const override { return getLevel(); }
void SetLevel(uint8 lvl);
- uint8 getRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, 0); }
+ uint8 getRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE); }
uint32 getRaceMask() const { return 1 << (getRace()-1); }
- uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, 1); }
+ uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS); }
uint32 getClassMask() const { return 1 << (getClass()-1); }
- uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, 2); }
+ uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER); }
float GetStat(Stats stat) const { return float(GetUInt32Value(UNIT_FIELD_STAT0+stat)); }
void SetStat(Stats stat, int32 val) { SetStatInt32Value(UNIT_FIELD_STAT0+stat, val); }
@@ -1347,7 +1371,7 @@ class TC_GAME_API Unit : public WorldObject
int32 ModifyHealth(int32 val);
int32 GetHealthGain(int32 dVal);
- Powers getPowerType() const { return Powers(GetByteValue(UNIT_FIELD_BYTES_0, 3)); }
+ Powers getPowerType() const { return Powers(GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_POWER_TYPE)); }
void setPowerType(Powers power);
uint32 GetPower(Powers power) const { return GetUInt32Value(UNIT_FIELD_POWER1 +power); }
uint32 GetMaxPower(Powers power) const { return GetUInt32Value(UNIT_FIELD_MAXPOWER1+power); }
@@ -1388,7 +1412,7 @@ class TC_GAME_API Unit : public WorldObject
uint32 GetCreatureType() const;
uint32 GetCreatureTypeMask() const;
- uint8 getStandState() const { return GetByteValue(UNIT_FIELD_BYTES_1, 0); }
+ uint8 GetStandState() const { return GetByteValue(UNIT_FIELD_BYTES_1, 0); }
bool IsSitState() const;
bool IsStandState() const;
void SetStandState(uint8 state);
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index fc7d668ae0b..3efeb1ca273 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -4715,7 +4715,7 @@ void ObjectMgr::LoadScripts(ScriptsType type)
if (tableName.empty())
return;
- if (sScriptMgr->IsScriptScheduled()) // function cannot be called when scripts are in use.
+ if (sMapMgr->IsScriptScheduled()) // function cannot be called when scripts are in use.
return;
TC_LOG_INFO("server.loading", "Loading %s...", tableName.c_str());
@@ -5162,7 +5162,7 @@ void ObjectMgr::LoadSpellScriptNames()
while (spellInfo)
{
- _spellScriptsStore.insert(SpellScriptsContainer::value_type(spellInfo->Id, GetScriptId(scriptName)));
+ _spellScriptsStore.insert(SpellScriptsContainer::value_type(spellInfo->Id, std::make_pair(GetScriptId(scriptName), true)));
spellInfo = spellInfo->GetNextRankSpell();
}
}
@@ -5171,7 +5171,7 @@ void ObjectMgr::LoadSpellScriptNames()
if (spellInfo->IsRanked())
TC_LOG_ERROR("sql.sql", "Scriptname: `%s` spell (Id: %d) is ranked spell. Perhaps not all ranks are assigned to this script.", scriptName.c_str(), spellId);
- _spellScriptsStore.insert(SpellScriptsContainer::value_type(spellInfo->Id, GetScriptId(scriptName)));
+ _spellScriptsStore.insert(SpellScriptsContainer::value_type(spellInfo->Id, std::make_pair(GetScriptId(scriptName), true)));
}
++count;
@@ -5193,45 +5193,59 @@ void ObjectMgr::ValidateSpellScripts()
uint32 count = 0;
- for (SpellScriptsContainer::iterator itr = _spellScriptsStore.begin(); itr != _spellScriptsStore.end();)
+ for (auto spell : _spellScriptsStore)
{
- SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(itr->first);
- std::vector<std::pair<SpellScriptLoader *, SpellScriptsContainer::iterator> > SpellScriptLoaders;
- sScriptMgr->CreateSpellScriptLoaders(itr->first, SpellScriptLoaders);
- itr = _spellScriptsStore.upper_bound(itr->first);
+ SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(spell.first);
- for (std::vector<std::pair<SpellScriptLoader *, SpellScriptsContainer::iterator> >::iterator sitr = SpellScriptLoaders.begin(); sitr != SpellScriptLoaders.end(); ++sitr)
+ auto const bounds = sObjectMgr->GetSpellScriptsBounds(spell.first);
+
+ for (auto itr = bounds.first; itr != bounds.second; ++itr)
{
- SpellScript* spellScript = sitr->first->GetSpellScript();
- AuraScript* auraScript = sitr->first->GetAuraScript();
- bool valid = true;
- if (!spellScript && !auraScript)
- {
- TC_LOG_ERROR("scripts", "Functions GetSpellScript() and GetAuraScript() of script `%s` do not return objects - script skipped", GetScriptName(sitr->second->second).c_str());
- valid = false;
- }
- if (spellScript)
- {
- spellScript->_Init(&sitr->first->GetName(), spellEntry->Id);
- spellScript->_Register();
- if (!spellScript->_Validate(spellEntry))
- valid = false;
- delete spellScript;
- }
- if (auraScript)
+ if (SpellScriptLoader* spellScriptLoader = sScriptMgr->GetSpellScriptLoader(itr->second.first))
{
- auraScript->_Init(&sitr->first->GetName(), spellEntry->Id);
- auraScript->_Register();
- if (!auraScript->_Validate(spellEntry))
- valid = false;
- delete auraScript;
- }
- if (!valid)
- {
- _spellScriptsStore.erase(sitr->second);
+ ++count;
+
+ std::unique_ptr<SpellScript> spellScript(spellScriptLoader->GetSpellScript());
+ std::unique_ptr<AuraScript> auraScript(spellScriptLoader->GetAuraScript());
+
+ if (!spellScript && !auraScript)
+ {
+ TC_LOG_ERROR("scripts", "Functions GetSpellScript() and GetAuraScript() of script `%s` do not return objects - script skipped", GetScriptName(itr->second.first).c_str());
+
+ itr->second.second = false;
+ continue;
+ }
+
+ if (spellScript)
+ {
+ spellScript->_Init(&spellScriptLoader->GetName(), spellEntry->Id);
+ spellScript->_Register();
+
+ if (!spellScript->_Validate(spellEntry))
+ {
+ itr->second.second = false;
+ continue;
+ }
+ }
+
+ if (auraScript)
+ {
+ auraScript->_Init(&spellScriptLoader->GetName(), spellEntry->Id);
+ auraScript->_Register();
+
+ if (!auraScript->_Validate(spellEntry))
+ {
+ itr->second.second = false;
+ continue;
+ }
+ }
+
+ // Enable the script when all checks passed
+ itr->second.second = true;
}
+ else
+ itr->second.second = false;
}
- ++count;
}
TC_LOG_INFO("server.loading", ">> Validated %u scripts in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
@@ -8571,6 +8585,8 @@ void ObjectMgr::LoadScriptNames()
{
uint32 oldMSTime = getMSTime();
+ // We insert an empty placeholder here so we can use the
+ // script id 0 as dummy for "no script found".
_scriptNamesStore.emplace_back("");
QueryResult result = WorldDatabase.Query(
@@ -8612,18 +8628,18 @@ void ObjectMgr::LoadScriptNames()
std::sort(_scriptNamesStore.begin(), _scriptNamesStore.end());
-#ifdef SCRIPTS
- for (size_t i = 1; i < _scriptNamesStore.size(); ++i)
- UnusedScriptNames.push_back(_scriptNamesStore[i]);
-#endif
-
TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " ScriptNames in %u ms", _scriptNamesStore.size(), GetMSTimeDiffToNow(oldMSTime));
}
+ObjectMgr::ScriptNameContainer const& ObjectMgr::GetAllScriptNames() const
+{
+ return _scriptNamesStore;
+}
+
std::string const& ObjectMgr::GetScriptName(uint32 id) const
{
static std::string const empty = "";
- return id < _scriptNamesStore.size() ? _scriptNamesStore[id] : empty;
+ return (id < _scriptNamesStore.size()) ? _scriptNamesStore[id] : empty;
}
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 73c03849699..576a8d2ccac 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -370,7 +370,7 @@ struct ScriptInfo
typedef std::multimap<uint32, ScriptInfo> ScriptMap;
typedef std::map<uint32, ScriptMap > ScriptMapMap;
-typedef std::multimap<uint32, uint32> SpellScriptsContainer;
+typedef std::multimap<uint32 /*spell id*/, std::pair<uint32 /*script id*/, bool /*enabled*/>> SpellScriptsContainer;
typedef std::pair<SpellScriptsContainer::iterator, SpellScriptsContainer::iterator> SpellScriptsBounds;
TC_GAME_API extern ScriptMapMap sSpellScripts;
TC_GAME_API extern ScriptMapMap sEventScripts;
@@ -1272,6 +1272,7 @@ class TC_GAME_API ObjectMgr
bool IsVendorItemValid(uint32 vendor_entry, uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* player = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0) const;
void LoadScriptNames();
+ ScriptNameContainer const& GetAllScriptNames() const;
std::string const& GetScriptName(uint32 id) const;
uint32 GetScriptId(std::string const& name);
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 2b4b77dc7a9..19638ec1bf8 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -642,7 +642,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Create Character:[%s] (GUID: %u)", GetAccountId(), GetRemoteAddress().c_str(), createInfo->Name.c_str(), newChar.GetGUID().GetCounter());
sScriptMgr->OnPlayerCreate(&newChar);
- sWorld->AddCharacterInfo(newChar.GetGUID(), GetAccountId(), newChar.GetName(), newChar.GetByteValue(PLAYER_BYTES_3, 0), newChar.getRace(), newChar.getClass(), newChar.getLevel());
+ sWorld->AddCharacterInfo(newChar.GetGUID(), GetAccountId(), newChar.GetName(), newChar.GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER), newChar.getRace(), newChar.getClass(), newChar.getLevel());
newChar.CleanupsBeforeDelete();
delete createInfo;
@@ -1242,20 +1242,25 @@ void WorldSession::HandleAlterAppearance(WorldPacket& recvData)
BarberShopStyleEntry const* bs_hair = sBarberShopStyleStore.LookupEntry(Hair);
- if (!bs_hair || bs_hair->type != 0 || bs_hair->race != _player->getRace() || bs_hair->gender != _player->GetByteValue(PLAYER_BYTES_3, 0))
+ if (!bs_hair || bs_hair->type != 0 || bs_hair->race != _player->getRace() || bs_hair->gender != _player->GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER))
return;
BarberShopStyleEntry const* bs_facialHair = sBarberShopStyleStore.LookupEntry(FacialHair);
- if (!bs_facialHair || bs_facialHair->type != 2 || bs_facialHair->race != _player->getRace() || bs_facialHair->gender != _player->GetByteValue(PLAYER_BYTES_3, 0))
+ if (!bs_facialHair || bs_facialHair->type != 2 || bs_facialHair->race != _player->getRace() || bs_facialHair->gender != _player->GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER))
return;
BarberShopStyleEntry const* bs_skinColor = sBarberShopStyleStore.LookupEntry(SkinColor);
- if (bs_skinColor && (bs_skinColor->type != 3 || bs_skinColor->race != _player->getRace() || bs_skinColor->gender != _player->GetByteValue(PLAYER_BYTES_3, 0)))
+ if (bs_skinColor && (bs_skinColor->type != 3 || bs_skinColor->race != _player->getRace() || bs_skinColor->gender != _player->GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER)))
return;
- if (!Player::ValidateAppearance(_player->getRace(), _player->getClass(), _player->GetByteValue(PLAYER_BYTES_3, 0), bs_hair->hair_id, Color, _player->GetByteValue(PLAYER_BYTES, 1), bs_facialHair->hair_id, bs_skinColor ? bs_skinColor->hair_id : _player->GetByteValue(PLAYER_BYTES, 0)))
+ if (!Player::ValidateAppearance(_player->getRace(), _player->getClass(), _player->GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER),
+ bs_hair->hair_id,
+ Color,
+ _player->GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_FACE_ID),
+ bs_facialHair->hair_id,
+ bs_skinColor ? bs_skinColor->hair_id : _player->GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID)))
return;
GameObject* go = _player->FindNearestGameObjectOfType(GAMEOBJECT_TYPE_BARBER_CHAIR, 5.0f);
@@ -1265,7 +1270,7 @@ void WorldSession::HandleAlterAppearance(WorldPacket& recvData)
return;
}
- if (_player->getStandState() != UNIT_STAND_STATE_SIT_LOW_CHAIR + go->GetGOInfo()->barberChair.chairheight)
+ if (_player->GetStandState() != UNIT_STAND_STATE_SIT_LOW_CHAIR + go->GetGOInfo()->barberChair.chairheight)
{
SendBarberShopResult(BARBER_SHOP_RESULT_NOT_ON_CHAIR);
return;
@@ -1287,11 +1292,11 @@ void WorldSession::HandleAlterAppearance(WorldPacket& recvData)
_player->ModifyMoney(-int32(cost)); // it isn't free
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER, cost);
- _player->SetByteValue(PLAYER_BYTES, 2, uint8(bs_hair->hair_id));
- _player->SetByteValue(PLAYER_BYTES, 3, uint8(Color));
- _player->SetByteValue(PLAYER_BYTES_2, 0, uint8(bs_facialHair->hair_id));
+ _player->SetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_STYLE_ID, uint8(bs_hair->hair_id));
+ _player->SetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_COLOR_ID, uint8(Color));
+ _player->SetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_FACIAL_STYLE, uint8(bs_facialHair->hair_id));
if (bs_skinColor)
- _player->SetByteValue(PLAYER_BYTES, 0, uint8(bs_skinColor->hair_id));
+ _player->SetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID, uint8(bs_skinColor->hair_id));
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, 1);
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 91df877e936..467d3730ab2 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -284,7 +284,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
continue;
uint32 pzoneid = target->GetZoneId();
- uint8 gender = target->GetByteValue(PLAYER_BYTES_3, 0);
+ uint8 gender = target->GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER);
bool z_show = true;
for (uint32 i = 0; i < zones_count; ++i)
@@ -405,7 +405,7 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/)
// not set flags if player can't free move to prevent lost state at logout cancel
if (GetPlayer()->CanFreeMove())
{
- if (GetPlayer()->getStandState() == UNIT_STAND_STATE_STAND)
+ if (GetPlayer()->GetStandState() == UNIT_STAND_STATE_STAND)
GetPlayer()->SetStandState(UNIT_STAND_STATE_SIT);
WorldPacket data(SMSG_FORCE_MOVE_ROOT, (8+4)); // guess size
@@ -1056,12 +1056,14 @@ void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recvData)
void WorldSession::HandleCompleteCinematic(WorldPacket& /*recvData*/)
{
- TC_LOG_DEBUG("network", "WORLD: Received CMSG_COMPLETE_CINEMATIC");
+ // If player has sight bound to visual waypoint NPC we should remove it
+ GetPlayer()->EndCinematic();
}
void WorldSession::HandleNextCinematicCamera(WorldPacket& /*recvData*/)
{
- TC_LOG_DEBUG("network", "WORLD: Received CMSG_NEXT_CINEMATIC_CAMERA");
+ // Sent by client when cinematic actually begun. So we begin the server side process
+ GetPlayer()->BeginCinematic();
}
void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket& recvData)
@@ -1157,7 +1159,7 @@ void WorldSession::HandleSetActionBarToggles(WorldPacket& recvData)
return;
}
- GetPlayer()->SetByteValue(PLAYER_FIELD_BYTES, 2, actionBar);
+ GetPlayer()->SetByteValue(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_ACTION_BAR_TOGGLES, actionBar);
}
void WorldSession::HandlePlayedTime(WorldPacket& recvData)
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index 6be1fd30ae3..e07e10ab00c 100644
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -594,11 +594,11 @@ void WorldSession::HandleMirrorImageDataRequest(WorldPacket& recvData)
if (creator->GetTypeId() == TYPEID_PLAYER)
{
Player* player = creator->ToPlayer();
- data << uint8(player->GetByteValue(PLAYER_BYTES, 0)); // skin
- data << uint8(player->GetByteValue(PLAYER_BYTES, 1)); // face
- data << uint8(player->GetByteValue(PLAYER_BYTES, 2)); // hair
- data << uint8(player->GetByteValue(PLAYER_BYTES, 3)); // haircolor
- data << uint8(player->GetByteValue(PLAYER_BYTES_2, 0)); // facialhair
+ data << uint8(player->GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID));
+ data << uint8(player->GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_FACE_ID));
+ data << uint8(player->GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_STYLE_ID));
+ data << uint8(player->GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_COLOR_ID));
+ data << uint8(player->GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_FACIAL_STYLE));
data << uint32(player->GetGuildId()); // unk
static EquipmentSlots const itemSlots[] =
diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp
index 1575b50098f..0887d183a8b 100644
--- a/src/server/game/Instances/InstanceScript.cpp
+++ b/src/server/game/Instances/InstanceScript.cpp
@@ -29,6 +29,8 @@
#include "Pet.h"
#include "WorldSession.h"
#include "Opcodes.h"
+#include "ScriptReloadMgr.h"
+#include "ScriptMgr.h"
BossBoundaryData::~BossBoundaryData()
{
@@ -36,6 +38,18 @@ BossBoundaryData::~BossBoundaryData()
delete it->Boundary;
}
+InstanceScript::InstanceScript(Map* map) : instance(map), completedEncounters(0)
+{
+#ifdef TRINITY_API_USE_DYNAMIC_LINKING
+ uint32 scriptId = sObjectMgr->GetInstanceTemplate(map->GetId())->ScriptId;
+ auto const scriptname = sObjectMgr->GetScriptName(scriptId);
+ ASSERT(!scriptname.empty());
+ // Acquire a strong reference from the script module
+ // to keep it loaded until this object is destroyed.
+ module_reference = sScriptMgr->AcquireModuleReferenceOfScriptName(scriptname);
+#endif // #ifndef TRINITY_API_USE_DYNAMIC_LINKING
+}
+
void InstanceScript::SaveToDB()
{
std::string data = GetSaveData();
diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h
index 949cdf5abcb..3814afe2f4b 100644
--- a/src/server/game/Instances/InstanceScript.h
+++ b/src/server/game/Instances/InstanceScript.h
@@ -36,6 +36,7 @@ class Unit;
class Player;
class GameObject;
class Creature;
+class ModuleReference;
enum EncounterFrameType
{
@@ -137,7 +138,7 @@ typedef std::map<uint32 /*entry*/, uint32 /*type*/> ObjectInfoMap;
class TC_GAME_API InstanceScript : public ZoneScript
{
public:
- explicit InstanceScript(Map* map) : instance(map), completedEncounters(0) { }
+ explicit InstanceScript(Map* map);
virtual ~InstanceScript() { }
@@ -289,6 +290,11 @@ class TC_GAME_API InstanceScript : public ZoneScript
ObjectInfoMap _gameObjectInfo;
ObjectGuidMap _objectGuids;
uint32 completedEncounters; // completed encounter mask, bit indexes are DungeonEncounter.dbc boss numbers, used for packets
+
+ #ifdef TRINITY_API_USE_DYNAMIC_LINKING
+ // Strong reference to the associated script module
+ std::shared_ptr<ModuleReference> module_reference;
+ #endif // #ifndef TRINITY_API_USE_DYNAMIC_LINKING
};
template<class AI, class T>
diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h
index 41feb7b26e2..0afb327d7f0 100644
--- a/src/server/game/Loot/LootMgr.h
+++ b/src/server/game/Loot/LootMgr.h
@@ -54,7 +54,7 @@ enum RollMask
#define MAX_NR_QUEST_ITEMS 32
// unrelated to the number of quest items shown, just for reserve
-enum LootMethod
+enum LootMethod : uint8
{
FREE_FOR_ALL = 0,
ROUND_ROBIN = 1,
@@ -74,7 +74,7 @@ enum PermissionTypes
NONE_PERMISSION = 6
};
-enum LootType
+enum LootType : uint8
{
LOOT_NONE = 0,
diff --git a/src/server/game/Maps/AreaBoundary.h b/src/server/game/Maps/AreaBoundary.h
index a8780ddb60f..0973d1a6e86 100644
--- a/src/server/game/Maps/AreaBoundary.h
+++ b/src/server/game/Maps/AreaBoundary.h
@@ -40,7 +40,7 @@ class TC_GAME_API AreaBoundary
{
double d_positionX, d_positionY, d_positionZ;
DoublePosition(double x = 0.0, double y = 0.0, double z = 0.0, float o = 0.0f)
- : Position(x, y, z, o), d_positionX(x), d_positionY(y), d_positionZ(z) { }
+ : Position(float(x), float(y), float(z), o), d_positionX(x), d_positionY(y), d_positionZ(z) { }
DoublePosition(float x, float y = 0.0f, float z = 0.0f, float o = 0.0f)
: Position(x, y, z, o), d_positionX(x), d_positionY(y), d_positionZ(z) { }
DoublePosition(const Position& pos)
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 8640150d86b..664ed3dc8ec 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -17,6 +17,7 @@
*/
#include "Map.h"
+#include "MapManager.h"
#include "Battleground.h"
#include "MMapFactory.h"
#include "CellImpl.h"
@@ -64,7 +65,7 @@ Map::~Map()
}
if (!m_scriptSchedule.empty())
- sScriptMgr->DecreaseScheduledScriptCount(m_scriptSchedule.size());
+ sMapMgr->DecreaseScheduledScriptCount(m_scriptSchedule.size());
MMAP::MMapFactory::createOrGetMMapManager()->unloadMapInstance(GetId(), i_InstanceId);
}
@@ -713,6 +714,15 @@ void Map::Update(const uint32 t_diff)
VisitNearbyCellsOf(player, grid_object_update, world_object_update);
+ // If player is using far sight, visit that object too
+ if (WorldObject* viewPoint = player->GetViewpoint())
+ {
+ if (Creature* viewCreature = viewPoint->ToCreature())
+ VisitNearbyCellsOf(viewCreature, grid_object_update, world_object_update);
+ else if (DynamicObject* viewObject = viewPoint->ToDynObject())
+ VisitNearbyCellsOf(viewObject, grid_object_update, world_object_update);
+ }
+
// Handle updates for creatures in combat with player and are more than 60 yards away
if (player->IsInCombat())
{
@@ -2657,8 +2667,8 @@ void Map::UpdateObjectsVisibilityFor(Player* player, Cell cell, CellCoord cellpa
cell.SetNoCreate();
TypeContainerVisitor<Trinity::VisibleNotifier, WorldTypeMapContainer > world_notifier(notifier);
TypeContainerVisitor<Trinity::VisibleNotifier, GridTypeMapContainer > grid_notifier(notifier);
- cell.Visit(cellpair, world_notifier, *this, *player, player->GetSightRange());
- cell.Visit(cellpair, grid_notifier, *this, *player, player->GetSightRange());
+ cell.Visit(cellpair, world_notifier, *this, *player->m_seer, player->GetSightRange());
+ cell.Visit(cellpair, grid_notifier, *this, *player->m_seer, player->GetSightRange());
// send data
notifier.SendToSelf();
diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp
index c1882b3dc75..79a8b3855e8 100644
--- a/src/server/game/Maps/MapManager.cpp
+++ b/src/server/game/Maps/MapManager.cpp
@@ -38,10 +38,10 @@
#include "AchievementMgr.h"
MapManager::MapManager()
+ : _nextInstanceId(0), _scheduledScripts(0)
{
i_gridCleanUpDelay = sWorld->getIntConfig(CONFIG_INTERVAL_GRIDCLEAN);
i_timer.SetInterval(sWorld->getIntConfig(CONFIG_INTERVAL_MAPUPDATE));
- _nextInstanceId = 0;
}
MapManager::~MapManager() { }
diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h
index e74453a1196..a7fdc37d324 100644
--- a/src/server/game/Maps/MapManager.h
+++ b/src/server/game/Maps/MapManager.h
@@ -126,6 +126,11 @@ class TC_GAME_API MapManager
template<typename Worker>
void DoForAllMapsWithMapId(uint32 mapId, Worker&& worker);
+ uint32 IncreaseScheduledScriptsCount() { return ++_scheduledScripts; }
+ uint32 DecreaseScheduledScriptCount() { return --_scheduledScripts; }
+ uint32 DecreaseScheduledScriptCount(size_t count) { return _scheduledScripts -= count; }
+ bool IsScriptScheduled() const { return _scheduledScripts > 0; }
+
private:
typedef std::unordered_map<uint32, Map*> MapMapType;
typedef std::vector<bool> InstanceIds;
@@ -150,6 +155,9 @@ class TC_GAME_API MapManager
InstanceIds _instanceIds;
uint32 _nextInstanceId;
MapUpdater m_updater;
+
+ // atomic op counter for active scripts amount
+ std::atomic<uint32> _scheduledScripts;
};
template<typename Worker>
diff --git a/src/server/game/Scripting/MapScripts.cpp b/src/server/game/Maps/MapScripts.cpp
index a01c109b9ca..c5d7bdc64ce 100644
--- a/src/server/game/Scripting/MapScripts.cpp
+++ b/src/server/game/Maps/MapScripts.cpp
@@ -21,6 +21,7 @@
#include "GridNotifiersImpl.h"
#include "GossipDef.h"
#include "Map.h"
+#include "MapManager.h"
#include "ObjectMgr.h"
#include "Pet.h"
#include "Item.h"
@@ -58,7 +59,7 @@ void Map::ScriptsStart(ScriptMapMap const& scripts, uint32 id, Object* source, O
if (iter->first == 0)
immedScript = true;
- sScriptMgr->IncreaseScheduledScriptsCount();
+ sMapMgr->IncreaseScheduledScriptsCount();
}
///- If one of the effects should be immediate, launch the script execution
if (/*start &&*/ immedScript && !i_scriptLock)
@@ -86,7 +87,7 @@ void Map::ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* sou
sa.script = &script;
m_scriptSchedule.insert(ScriptScheduleMap::value_type(time_t(sWorld->GetGameTime() + delay), sa));
- sScriptMgr->IncreaseScheduledScriptsCount();
+ sMapMgr->IncreaseScheduledScriptsCount();
///- If effects should be immediate, launch the script execution
if (delay == 0 && !i_scriptLock)
@@ -878,6 +879,6 @@ void Map::ScriptsProcess()
m_scriptSchedule.erase(iter);
iter = m_scriptSchedule.begin();
- sScriptMgr->DecreaseScheduledScriptCount();
+ sMapMgr->DecreaseScheduledScriptCount();
}
}
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index dcee5ff7071..ca63137ac93 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -887,7 +887,9 @@ enum TrinityStrings
LANG_CHARACTER_DELETED_LIST_LINE_CHAT = 1026,
LANG_SQLDRIVER_QUERY_LOGGING_ENABLED = 1027,
LANG_SQLDRIVER_QUERY_LOGGING_DISABLED = 1028,
- // Room for more level 4 1029-1099 not used
+ LANG_ACCOUNT_INVALID_BNET_NAME = 1029, // 6.x ONLY
+ LANG_ACCOUNT_USE_BNET_COMMANDS = 1030, // 6.x enum value name but different text in DB
+ // Room for more level 4 1031-1099 not used
// Level 3 (continue)
LANG_ACCOUNT_SETADDON = 1100,
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index 77d6f739da6..aa45c5024e6 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -23,7 +23,7 @@
#include "DetourNavMesh.h"
#include <cassert>
-enum SpellEffIndex
+enum SpellEffIndex : uint8
{
EFFECT_0 = 0,
EFFECT_1 = 1,
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 2a57524cb3c..b01ddcb060d 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -302,6 +302,27 @@ void MotionMaster::MovePoint(uint32 id, float x, float y, float z, bool generate
}
}
+void MotionMaster::MoveCloserAndStop(uint32 id, Unit* target, float distance)
+{
+ float distanceToTravel = _owner->GetExactDist2d(target) - distance;
+ if (distanceToTravel > 0.0f)
+ {
+ float angle = _owner->GetAngle(target);
+ float destx = _owner->GetPositionX() + distanceToTravel * std::cos(angle);
+ float desty = _owner->GetPositionY() + distanceToTravel * std::sin(angle);
+ MovePoint(id, destx, desty, target->GetPositionZ());
+ }
+ else
+ {
+ // we are already close enough. We just need to turn toward the target without changing position.
+ Movement::MoveSplineInit init(_owner);
+ init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZMinusOffset());
+ init.SetFacing(target);
+ init.Launch();
+ Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE);
+ }
+}
+
void MotionMaster::MoveLand(uint32 id, Position const& pos)
{
float x, y, z;
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index d1c6474fb36..7d6d512e88d 100644
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -173,6 +173,12 @@ class TC_GAME_API MotionMaster //: private std::stack<MovementGenerator *>
{ MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ, generatePath); }
void MovePoint(uint32 id, float x, float y, float z, bool generatePath = true);
+ /* Makes the unit move toward the target until it is at a certain distance from it. The unit then stops.
+ Only works in 2D.
+ This method doesn't account for any movement done by the target. in other words, it only works if the target is stationary.
+ */
+ void MoveCloserAndStop(uint32 id, Unit* target, float distance);
+
// These two movement types should only be used with creatures having landing/takeoff animations
void MoveLand(uint32 id, Position const& pos);
void MoveTakeoff(uint32 id, Position const& pos);
diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp
index 7f0695e16b3..aa00d211d6e 100644
--- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp
+++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp
@@ -33,8 +33,14 @@ void OutdoorPvPMgr::Die()
for (OutdoorPvPSet::iterator itr = m_OutdoorPvPSet.begin(); itr != m_OutdoorPvPSet.end(); ++itr)
delete *itr;
+ m_OutdoorPvPSet.clear();
+
for (OutdoorPvPDataMap::iterator itr = m_OutdoorPvPDatas.begin(); itr != m_OutdoorPvPDatas.end(); ++itr)
delete itr->second;
+
+ m_OutdoorPvPDatas.clear();
+
+ m_OutdoorPvPMap.clear();
}
OutdoorPvPMgr* OutdoorPvPMgr::instance()
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index 75b52bb4537..5e3bb4889ab 100644
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -60,7 +60,7 @@ enum QuestFailedReason
INVALIDREASON_DAILY_QUEST_COMPLETED_TODAY = 29 // You have completed that daily quest today.
};
-enum QuestShareMessages
+enum QuestShareMessages : uint8
{
QUEST_PARTY_MSG_SHARING_QUEST = 0,
QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1,
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index 4218746893f..ca1cd71363e 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -17,6 +17,7 @@
*/
#include "ScriptMgr.h"
+#include "ScriptReloadMgr.h"
#include "Config.h"
#include "DatabaseEnv.h"
#include "DBCStores.h"
@@ -34,11 +35,9 @@
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Chat.h"
-
-// namespace
-// {
- UnusedScriptNamesContainer UnusedScriptNames;
-// }
+#include "MapManager.h"
+#include "LFGScripts.h"
+#include "InstanceScript.h"
// Trait which indicates whether this script type
// must be assigned in the database.
@@ -67,6 +66,10 @@ struct is_script_database_bound<GameObjectScript>
: std::true_type { };
template<>
+struct is_script_database_bound<VehicleScript>
+ : std::true_type { };
+
+template<>
struct is_script_database_bound<AreaTriggerScript>
: std::true_type { };
@@ -94,143 +97,846 @@ template<>
struct is_script_database_bound<AchievementCriteriaScript>
: std::true_type { };
+enum Spells
+{
+ SPELL_HOTSWAP_VISUAL_SPELL_EFFECT = 40162 // 59084
+};
+
+class ScriptRegistryInterface
+{
+public:
+ ScriptRegistryInterface() { }
+ virtual ~ScriptRegistryInterface() { }
+
+ ScriptRegistryInterface(ScriptRegistryInterface const&) = delete;
+ ScriptRegistryInterface(ScriptRegistryInterface&&) = delete;
+
+ ScriptRegistryInterface& operator= (ScriptRegistryInterface const&) = delete;
+ ScriptRegistryInterface& operator= (ScriptRegistryInterface&&) = delete;
+
+ /// Removes all scripts associated with the given script context.
+ /// Requires ScriptRegistryBase::SwapContext to be called after all transfers have finished.
+ virtual void ReleaseContext(std::string const& context) = 0;
+
+ /// Injects and updates the changed script objects.
+ virtual void SwapContext(bool initialize) = 0;
+
+ /// Removes the scripts used by this registry from the given container.
+ /// Used to find unused script names.
+ virtual void RemoveUsedScriptsFromContainer(std::unordered_set<std::string>& scripts) = 0;
+
+ /// Unloads the script registry.
+ virtual void Unload() = 0;
+};
+
+template<class>
+class ScriptRegistry;
+
+class ScriptRegistryCompositum
+ : public ScriptRegistryInterface
+{
+ ScriptRegistryCompositum() { }
+
+ template<class>
+ friend class ScriptRegistry;
+
+ /// Type erasure wrapper for objects
+ class DeleteableObjectBase
+ {
+ public:
+ DeleteableObjectBase() { }
+ virtual ~DeleteableObjectBase() { }
+
+ DeleteableObjectBase(DeleteableObjectBase const&) = delete;
+ DeleteableObjectBase& operator= (DeleteableObjectBase const&) = delete;
+ };
+
+ template<typename T>
+ class DeleteableObject
+ : public DeleteableObjectBase
+ {
+ public:
+ DeleteableObject(T&& object)
+ : _object(std::forward<T>(object)) { }
+
+ private:
+ T _object;
+ };
+
+public:
+ void SetScriptNameInContext(std::string const& scriptname, std::string const& context)
+ {
+ ASSERT(_scriptnames_to_context.find(scriptname) == _scriptnames_to_context.end(),
+ "Scriptname was assigned to this context already!");
+ _scriptnames_to_context.insert(std::make_pair(scriptname, context));
+ }
+
+ std::string const& GetScriptContextOfScriptName(std::string const& scriptname) const
+ {
+ auto itr = _scriptnames_to_context.find(scriptname);
+ ASSERT(itr != _scriptnames_to_context.end() &&
+ "Given scriptname doesn't exist!");
+ return itr->second;
+ }
+
+ void ReleaseContext(std::string const& context) final override
+ {
+ for (auto const registry : _registries)
+ registry->ReleaseContext(context);
+
+ // Clear the script names in context after calling the release hooks
+ // since it's possible that new references to a shared library
+ // are acquired when releasing.
+ for (auto itr = _scriptnames_to_context.begin();
+ itr != _scriptnames_to_context.end();)
+ if (itr->second == context)
+ itr = _scriptnames_to_context.erase(itr);
+ else
+ ++itr;
+ }
+
+ void SwapContext(bool initialize) final override
+ {
+ for (auto const registry : _registries)
+ registry->SwapContext(initialize);
+
+ DoDelayedDelete();
+ }
+
+ void RemoveUsedScriptsFromContainer(std::unordered_set<std::string>& scripts) final override
+ {
+ for (auto const registry : _registries)
+ registry->RemoveUsedScriptsFromContainer(scripts);
+ }
+
+ void Unload() final override
+ {
+ for (auto const registry : _registries)
+ registry->Unload();
+ }
+
+ template<typename T>
+ void QueueForDelayedDelete(T&& any)
+ {
+ _delayed_delete_queue.push_back(
+ Trinity::make_unique<
+ DeleteableObject<typename std::decay<T>::type>
+ >(std::forward<T>(any))
+ );
+ }
+
+ static ScriptRegistryCompositum* Instance()
+ {
+ static ScriptRegistryCompositum instance;
+ return &instance;
+ }
+
+private:
+ void Register(ScriptRegistryInterface* registry)
+ {
+ _registries.insert(registry);
+ }
+
+ void DoDelayedDelete()
+ {
+ _delayed_delete_queue.clear();
+ }
+
+ std::unordered_set<ScriptRegistryInterface*> _registries;
+
+ std::vector<std::unique_ptr<DeleteableObjectBase>> _delayed_delete_queue;
+
+ std::unordered_map<
+ std::string /*script name*/,
+ std::string /*context*/
+ > _scriptnames_to_context;
+};
+
+#define sScriptRegistryCompositum ScriptRegistryCompositum::Instance()
+
+template<typename /*ScriptType*/, bool /*IsDatabaseBound*/>
+class SpecializedScriptRegistry;
+
// This is the global static registry of scripts.
-template<class TScript>
-class ScriptRegistry
+template<class ScriptType>
+class ScriptRegistry final
+ : public SpecializedScriptRegistry<
+ ScriptType, is_script_database_bound<ScriptType>::value>
+{
+ ScriptRegistry()
+ {
+ sScriptRegistryCompositum->Register(this);
+ }
+
+public:
+ static ScriptRegistry* Instance()
+ {
+ static ScriptRegistry instance;
+ return &instance;
+ }
+
+ void LogDuplicatedScriptPointerError(ScriptType const* first, ScriptType const* second)
+ {
+ // See if the script is using the same memory as another script. If this happens, it means that
+ // someone forgot to allocate new memory for a script.
+ TC_LOG_ERROR("scripts", "Script '%s' has same memory pointer as '%s'.",
+ first->GetName().c_str(), second->GetName().c_str());
+ }
+};
+
+class ScriptRegistrySwapHookBase
+{
+public:
+ ScriptRegistrySwapHookBase() { }
+ virtual ~ScriptRegistrySwapHookBase() { }
+
+ ScriptRegistrySwapHookBase(ScriptRegistrySwapHookBase const&) = delete;
+ ScriptRegistrySwapHookBase(ScriptRegistrySwapHookBase&&) = delete;
+
+ ScriptRegistrySwapHookBase& operator= (ScriptRegistrySwapHookBase const&) = delete;
+ ScriptRegistrySwapHookBase& operator= (ScriptRegistrySwapHookBase&&) = delete;
+
+ /// Called before the actual context release happens
+ virtual void BeforeReleaseContext(std::string const& /*context*/) { }
+
+ /// Called before SwapContext
+ virtual void BeforeSwapContext(bool /*initialize*/) { }
+
+ /// Called before Unload
+ virtual void BeforeUnload() { }
+};
+
+template<typename ScriptType, typename Base>
+class ScriptRegistrySwapHooks
+ : public ScriptRegistrySwapHookBase
+{
+};
+
+/// This hook is responsible for swapping OutdoorPvP's
+template<typename Base>
+class UnsupportedScriptRegistrySwapHooks
+ : public ScriptRegistrySwapHookBase
+{
+public:
+ void BeforeReleaseContext(std::string const& context) final override
+ {
+ auto const bounds = static_cast<Base*>(this)->_ids_of_contexts.equal_range(context);
+ ASSERT(bounds.first == bounds.second);
+ }
+};
+
+/// This hook is responsible for swapping Creature and GameObject AI's
+template<typename ObjectType, typename ScriptType, typename Base>
+class CreatureGameObjectScriptRegistrySwapHooks
+ : public ScriptRegistrySwapHookBase
{
+ template<typename W>
+ class AIFunctionMapWorker
+ {
+ public:
+ template<typename T>
+ AIFunctionMapWorker(T&& worker)
+ : _worker(std::forward<T>(worker)) { }
+
+ void Visit(std::unordered_map<ObjectGuid, ObjectType*>& objects)
+ {
+ _worker(objects);
+ }
+
+ template<typename O>
+ void Visit(std::unordered_map<ObjectGuid, O*>&) { }
+
+ private:
+ W _worker;
+ };
+
+ class AsyncCastHotswapEffectEvent : public BasicEvent
+ {
public:
+ explicit AsyncCastHotswapEffectEvent(Unit* owner) : owner_(owner) { }
+
+ bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) override
+ {
+ owner_->CastSpell(owner_, SPELL_HOTSWAP_VISUAL_SPELL_EFFECT, true);
+ return true;
+ }
+
+ private:
+ Unit* owner_;
+ };
+
+ // Hook which is called before a creature is swapped
+ static void UnloadStage1(Creature* creature)
+ {
+ if (creature->IsCharmed())
+ creature->RemoveCharmedBy(nullptr);
+
+ ASSERT(!creature->IsCharmed(),
+ "There is a disabled AI which is still loaded.");
- typedef std::map<uint32, TScript*> ScriptMap;
- typedef typename ScriptMap::iterator ScriptMapIterator;
+ creature->AI()->EnterEvadeMode();
+ }
+
+ static void UnloadStage2(Creature* creature)
+ {
+ bool const destroyed = creature->AIM_Destroy();
+ ASSERT(destroyed,
+ "Destroying the AI should never fail here!");
+ (void)destroyed;
- // The actual list of scripts. This will be accessed concurrently, so it must not be modified
- // after server startup.
- static ScriptMap ScriptPointerList;
- static std::vector<TScript*> Scripts;
+ ASSERT(!creature->AI(),
+ "The AI should be null here!");
+ }
- static void AddScript(TScript* const script, bool addToDeleteContainer = true)
+ // Hook which is called before a gameobject is swapped
+ static void UnloadStage1(GameObject* gameobject)
+ {
+ gameobject->AI()->Reset();
+ }
+
+ static void UnloadStage2(GameObject* gameobject)
+ {
+ gameobject->AIM_Destroy();
+
+ ASSERT(!gameobject->AI(),
+ "The AI should be null here!");
+ }
+
+ // Hook which is called after a creature was swapped
+ static void LoadStage1(Creature* creature)
+ {
+ ASSERT(!creature->AI(),
+ "The AI should be null here!");
+
+ if (creature->IsAlive())
+ creature->ClearUnitState(UNIT_STATE_EVADE);
+
+ bool const created = creature->AIM_Initialize();
+ ASSERT(created,
+ "Creating the AI should never fail here!");
+ (void)created;
+ }
+
+ static void LoadStage2(Creature* creature)
+ {
+ if (!creature->IsAlive())
+ return;
+
+ creature->AI()->EnterEvadeMode();
+
+ // Cast a dummy visual spell asynchronously here to signal
+ // that the AI was hot swapped
+ creature->m_Events.AddEvent(new AsyncCastHotswapEffectEvent(creature),
+ creature->m_Events.CalculateTime(0));
+ }
+
+ // Hook which is called after a gameobject was swapped
+ static void LoadStage1(GameObject* gameobject)
+ {
+ ASSERT(!gameobject->AI(),
+ "The AI should be null here!");
+
+ gameobject->AIM_Initialize();
+ }
+
+ static void LoadStage2(GameObject* gameobject)
+ {
+ gameobject->AI()->Reset();
+ }
+
+ template<typename T>
+ void RunOverAllEntities(T fn)
+ {
+ auto evaluator = [&](std::unordered_map<ObjectGuid, ObjectType*>& objects)
{
- ASSERT(script);
+ for (auto object : objects)
+ fn(object.second);
+ };
- // See if the script is using the same memory as another script. If this happens, it means that
- // someone forgot to allocate new memory for a script.
- for (ScriptMapIterator it = ScriptPointerList.begin(); it != ScriptPointerList.end(); ++it)
+ AIFunctionMapWorker<typename std::decay<decltype(evaluator)>::type> worker(std::move(evaluator));
+ TypeContainerVisitor<decltype(worker), MapStoredObjectTypesContainer> visitor(worker);
+
+ sMapMgr->DoForAllMaps([&](Map* map)
+ {
+ // Run the worker over all maps
+ visitor.Visit(map->GetObjectsStore());
+ });
+ }
+
+public:
+ void BeforeReleaseContext(std::string const& context) final override
+ {
+ auto ids_to_remove = static_cast<Base*>(this)->GetScriptIDsToRemove(context);
+
+ std::vector<ObjectType*> stage2;
+
+ RunOverAllEntities([&](ObjectType* object)
+ {
+ if (ids_to_remove.find(object->GetScriptId()) != ids_to_remove.end())
{
- if (it->second == script)
- {
- TC_LOG_ERROR("scripts", "Script '%s' has same memory pointer as '%s'.",
- script->GetName().c_str(), it->second->GetName().c_str());
+ UnloadStage1(object);
+ stage2.push_back(object);
+ }
+ });
- return;
+ for (auto object : stage2)
+ UnloadStage2(object);
+
+ // Add the new ids which are removed to the global ids to remove set
+ ids_removed_.insert(ids_to_remove.begin(), ids_to_remove.end());
+ }
+
+ void BeforeSwapContext(bool initialize) override
+ {
+ // Never swap creature or gameobject scripts when initializing
+ if (initialize)
+ return;
+
+ // Add the recently added scripts to the deleted scripts to replace
+ // default AI's with recently added core scripts.
+ ids_removed_.insert(static_cast<Base*>(this)->GetRecentlyAddedScriptIDs().begin(),
+ static_cast<Base*>(this)->GetRecentlyAddedScriptIDs().end());
+
+ std::vector<ObjectType*> remove;
+ std::vector<ObjectType*> stage2;
+
+ RunOverAllEntities([&](ObjectType* object)
+ {
+ if (ids_removed_.find(object->GetScriptId()) != ids_removed_.end())
+ {
+ if (object->AI())
+ {
+ // Overwrite existing (default) AI's which are replaced by a new script
+ UnloadStage1(object);
+ remove.push_back(object);
}
+
+ stage2.push_back(object);
}
+ });
+
+ for (auto object : remove)
+ UnloadStage2(object);
- AddScript(is_script_database_bound<TScript>{}, script);
- if (addToDeleteContainer)
- Scripts.push_back(script);
+ for (auto object : stage2)
+ LoadStage1(object);
+
+ for (auto object : stage2)
+ LoadStage2(object);
+
+ ids_removed_.clear();
+ }
+
+ void BeforeUnload() final override
+ {
+ ASSERT(ids_removed_.empty());
+ }
+
+private:
+ std::unordered_set<uint32> ids_removed_;
+};
+
+// This hook is responsible for swapping CreatureAI's
+template<typename Base>
+class ScriptRegistrySwapHooks<CreatureScript, Base>
+ : public CreatureGameObjectScriptRegistrySwapHooks<
+ Creature, CreatureScript, Base
+ > { };
+
+// This hook is responsible for swapping GameObjectAI's
+template<typename Base>
+class ScriptRegistrySwapHooks<GameObjectScript, Base>
+ : public CreatureGameObjectScriptRegistrySwapHooks<
+ GameObject, GameObjectScript, Base
+ > { };
+
+/// This hook is responsible for swapping BattlegroundScript's
+template<typename Base>
+class ScriptRegistrySwapHooks<BattlegroundScript, Base>
+ : public UnsupportedScriptRegistrySwapHooks<Base> { };
+
+/// This hook is responsible for swapping OutdoorPvP's
+template<typename Base>
+class ScriptRegistrySwapHooks<OutdoorPvPScript, Base>
+ : public ScriptRegistrySwapHookBase
+{
+public:
+ ScriptRegistrySwapHooks() : swapped(false) { }
+
+ void BeforeReleaseContext(std::string const& context) final override
+ {
+ auto const bounds = static_cast<Base*>(this)->_ids_of_contexts.equal_range(context);
+
+ if ((!swapped) && (bounds.first != bounds.second))
+ {
+ swapped = true;
+ sOutdoorPvPMgr->Die();
}
+ }
- // Gets a script by its ID (assigned by ObjectMgr).
- static TScript* GetScriptById(uint32 id)
+ void BeforeSwapContext(bool initialize) override
+ {
+ // Never swap outdoor pvp scripts when initializing
+ if ((!initialize) && swapped)
{
- ScriptMapIterator it = ScriptPointerList.find(id);
- if (it != ScriptPointerList.end())
- return it->second;
+ sOutdoorPvPMgr->InitOutdoorPvP();
+ swapped = false;
+ }
+ }
+
+ void BeforeUnload() final override
+ {
+ ASSERT(!swapped);
+ }
+
+private:
+ bool swapped;
+};
+
+/// This hook is responsible for swapping InstanceMapScript's
+template<typename Base>
+class ScriptRegistrySwapHooks<InstanceMapScript, Base>
+ : public ScriptRegistrySwapHookBase
+{
+public:
+ ScriptRegistrySwapHooks() : swapped(false) { }
- return NULL;
+ void BeforeReleaseContext(std::string const& context) final override
+ {
+ auto const bounds = static_cast<Base*>(this)->_ids_of_contexts.equal_range(context);
+ if (bounds.first != bounds.second)
+ swapped = true;
+ }
+
+ void BeforeSwapContext(bool /*initialize*/) override
+ {
+ swapped = false;
+ }
+
+ void BeforeUnload() final override
+ {
+ ASSERT(!swapped);
+ }
+
+private:
+ bool swapped;
+};
+
+/// This hook is responsible for swapping SpellScriptLoader's
+template<typename Base>
+class ScriptRegistrySwapHooks<SpellScriptLoader, Base>
+ : public ScriptRegistrySwapHookBase
+{
+public:
+ ScriptRegistrySwapHooks() : swapped(false) { }
+
+ void BeforeReleaseContext(std::string const& context) final override
+ {
+ auto const bounds = static_cast<Base*>(this)->_ids_of_contexts.equal_range(context);
+
+ if (bounds.first != bounds.second)
+ swapped = true;
+ }
+
+ void BeforeSwapContext(bool /*initialize*/) override
+ {
+ if (swapped)
+ {
+ sObjectMgr->ValidateSpellScripts();
+ swapped = false;
}
+ }
- private:
+ void BeforeUnload() final override
+ {
+ ASSERT(!swapped);
+ }
+
+private:
+ bool swapped;
+};
+
+// Database bound script registry
+template<typename ScriptType>
+class SpecializedScriptRegistry<ScriptType, true>
+ : public ScriptRegistryInterface,
+ public ScriptRegistrySwapHooks<ScriptType, ScriptRegistry<ScriptType>>
+{
+ template<typename>
+ friend class UnsupportedScriptRegistrySwapHooks;
+
+ template<typename, typename>
+ friend class ScriptRegistrySwapHooks;
+
+ template<typename, typename, typename>
+ friend class CreatureGameObjectScriptRegistrySwapHooks;
+
+public:
+ SpecializedScriptRegistry() { }
+
+ typedef std::unordered_map<
+ uint32 /*script id*/,
+ std::unique_ptr<ScriptType>
+ > ScriptStoreType;
+
+ typedef typename ScriptStoreType::iterator ScriptStoreIteratorType;
+
+ void ReleaseContext(std::string const& context) final override
+ {
+ this->BeforeReleaseContext(context);
+
+ auto const bounds = _ids_of_contexts.equal_range(context);
+ for (auto itr = bounds.first; itr != bounds.second; ++itr)
+ _scripts.erase(itr->second);
+ }
+
+ void SwapContext(bool initialize) final override
+ {
+ this->BeforeSwapContext(initialize);
+
+ _recently_added_ids.clear();
+ }
+
+ void RemoveUsedScriptsFromContainer(std::unordered_set<std::string>& scripts) final override
+ {
+ for (auto const& script : _scripts)
+ scripts.erase(script.second->GetName());
+ }
+
+ void Unload() final override
+ {
+ this->BeforeUnload();
+
+ ASSERT(_recently_added_ids.empty(),
+ "Recently added script ids should be empty here!");
+
+ _scripts.clear();
+ _ids_of_contexts.clear();
+ }
+
+ // Adds a database bound script
+ void AddScript(ScriptType* script)
+ {
+ ASSERT(script,
+ "Tried to call AddScript with a nullpointer!");
+ ASSERT(!sScriptMgr->GetCurrentScriptContext().empty(),
+ "Tried to register a script without being in a valid script context!");
- // Adds a database bound script
- static void AddScript(std::true_type, TScript* const script)
+ std::unique_ptr<ScriptType> script_ptr(script);
+
+ // Get an ID for the script. An ID only exists if it's a script that is assigned in the database
+ // through a script name (or similar).
+ if (uint32 const id = sObjectMgr->GetScriptId(script->GetName()))
{
- // Get an ID for the script. An ID only exists if it's a script that is assigned in the database
- // through a script name (or similar).
- uint32 id = sObjectMgr->GetScriptId(script->GetName());
- if (id)
+ // Try to find an existing script.
+ for (auto const& stored_script : _scripts)
{
- // Try to find an existing script.
- bool existing = false;
- for (ScriptMapIterator it = ScriptPointerList.begin(); it != ScriptPointerList.end(); ++it)
- {
- // If the script names match...
- if (it->second->GetName() == script->GetName())
- {
- // ... It exists.
- existing = true;
- break;
- }
- }
-
- // If the script isn't assigned -> assign it!
- if (!existing)
- {
- ScriptPointerList[id] = script;
- sScriptMgr->IncrementScriptCount();
-
- #ifdef SCRIPTS
- UnusedScriptNamesContainer::iterator itr = std::lower_bound(UnusedScriptNames.begin(), UnusedScriptNames.end(), script->GetName());
- if (itr != UnusedScriptNames.end() && *itr == script->GetName())
- UnusedScriptNames.erase(itr);
- #endif
- }
- else
+ // If the script names match...
+ if (stored_script.second->GetName() == script->GetName())
{
// If the script is already assigned -> delete it!
- TC_LOG_ERROR("scripts", "Script '%s' already assigned with the same script name, so the script can't work.",
- script->GetName().c_str());
+ TC_LOG_ERROR("scripts", "Script '%s' already assigned with the same script name, "
+ "so the script can't work.", script->GetName().c_str());
- ABORT(); // Error that should be fixed ASAP.
+ // Error that should be fixed ASAP.
+ sScriptRegistryCompositum->QueueForDelayedDelete(std::move(script_ptr));
+ ABORT();
+ return;
}
}
- else
- {
- // The script uses a script name from database, but isn't assigned to anything.
- TC_LOG_ERROR("sql.sql", "Script named '%s' does not have a script name assigned in database.", script->GetName().c_str());
- }
- }
- // Adds a non database bound script
- static void AddScript(std::false_type, TScript* const script)
+ // If the script isn't assigned -> assign it!
+ _scripts.insert(std::make_pair(id, std::move(script_ptr)));
+ _ids_of_contexts.insert(std::make_pair(sScriptMgr->GetCurrentScriptContext(), id));
+ _recently_added_ids.insert(id);
+
+ sScriptRegistryCompositum->SetScriptNameInContext(script->GetName(),
+ sScriptMgr->GetCurrentScriptContext());
+ }
+ else
{
- // We're dealing with a code-only script; just add it.
- ScriptPointerList[_scriptIdCounter++] = script;
- sScriptMgr->IncrementScriptCount();
+ // The script uses a script name from database, but isn't assigned to anything.
+ TC_LOG_ERROR("sql.sql", "Script named '%s' does not have a script name assigned in database.",
+ script->GetName().c_str());
+
+ // Avoid calling "delete script;" because we are currently in the script constructor
+ // In a valid scenario this will not happen because every script has a name assigned in the database
+ sScriptRegistryCompositum->QueueForDelayedDelete(std::move(script_ptr));
+ return;
}
+ }
+
+ // Gets a script by its ID (assigned by ObjectMgr).
+ ScriptType* GetScriptById(uint32 id)
+ {
+ auto const itr = _scripts.find(id);
+ if (itr != _scripts.end())
+ return itr->second.get();
+
+ return nullptr;
+ }
+
+ ScriptStoreType& GetScripts()
+ {
+ return _scripts;
+ }
- // Counter used for code-only scripts.
- static uint32 _scriptIdCounter;
+protected:
+ // Returns the script id's which are registered to a certain context
+ std::unordered_set<uint32> GetScriptIDsToRemove(std::string const& context) const
+ {
+ // Create a set of all ids which are removed
+ std::unordered_set<uint32> scripts_to_remove;
+
+ auto const bounds = _ids_of_contexts.equal_range(context);
+ for (auto itr = bounds.first; itr != bounds.second; ++itr)
+ scripts_to_remove.insert(itr->second);
+
+ return scripts_to_remove;
+ }
+
+ std::unordered_set<uint32> const& GetRecentlyAddedScriptIDs() const
+ {
+ return _recently_added_ids;
+ }
+
+private:
+ ScriptStoreType _scripts;
+
+ // Scripts of a specific context
+ std::unordered_multimap<std::string /*context*/, uint32 /*id*/> _ids_of_contexts;
+
+ // Script id's which were registered recently
+ std::unordered_set<uint32> _recently_added_ids;
+};
+
+/// This hook is responsible for swapping CommandScript's
+template<typename Base>
+class ScriptRegistrySwapHooks<CommandScript, Base>
+ : public ScriptRegistrySwapHookBase
+{
+public:
+ void BeforeReleaseContext(std::string const& /*context*/) final override
+ {
+ ChatHandler::invalidateCommandTable();
+ }
+
+ void BeforeSwapContext(bool /*initialize*/) override
+ {
+ ChatHandler::invalidateCommandTable();
+ }
+
+ void BeforeUnload() final override
+ {
+ ChatHandler::invalidateCommandTable();
+ }
+};
+
+// Database unbound script registry
+template<typename ScriptType>
+class SpecializedScriptRegistry<ScriptType, false>
+ : public ScriptRegistryInterface,
+ public ScriptRegistrySwapHooks<ScriptType, ScriptRegistry<ScriptType>>
+{
+ template<typename, typename>
+ friend class ScriptRegistrySwapHooks;
+
+public:
+ typedef std::unordered_multimap<std::string /*context*/, std::unique_ptr<ScriptType>> ScriptStoreType;
+ typedef typename ScriptStoreType::iterator ScriptStoreIteratorType;
+
+ SpecializedScriptRegistry() { }
+
+ void ReleaseContext(std::string const& context) final override
+ {
+ this->BeforeReleaseContext(context);
+
+ _scripts.erase(context);
+ }
+
+ void SwapContext(bool initialize) final override
+ {
+ this->BeforeSwapContext(initialize);
+ }
+
+ void RemoveUsedScriptsFromContainer(std::unordered_set<std::string>& scripts) final override
+ {
+ for (auto const& script : _scripts)
+ scripts.erase(script.second->GetName());
+ }
+
+ void Unload() final override
+ {
+ this->BeforeUnload();
+
+ _scripts.clear();
+ }
+
+ // Adds a non database bound script
+ void AddScript(ScriptType* script)
+ {
+ ASSERT(script,
+ "Tried to call AddScript with a nullpointer!");
+ ASSERT(!sScriptMgr->GetCurrentScriptContext().empty(),
+ "Tried to register a script without being in a valid script context!");
+
+ std::unique_ptr<ScriptType> script_ptr(script);
+
+ for (auto const& entry : _scripts)
+ if (entry.second.get() == script)
+ {
+ static_cast<ScriptRegistry<ScriptType>*>(this)->
+ LogDuplicatedScriptPointerError(script, entry.second.get());
+
+ sScriptRegistryCompositum->QueueForDelayedDelete(std::move(script_ptr));
+ return;
+ }
+
+ // We're dealing with a code-only script, just add it.
+ _scripts.insert(std::make_pair(sScriptMgr->GetCurrentScriptContext(), std::move(script_ptr)));
+ }
+
+ ScriptStoreType& GetScripts()
+ {
+ return _scripts;
+ }
+
+private:
+ ScriptStoreType _scripts;
};
// Utility macros to refer to the script registry.
-#define SCR_REG_MAP(T) ScriptRegistry<T>::ScriptMap
-#define SCR_REG_ITR(T) ScriptRegistry<T>::ScriptMapIterator
-#define SCR_REG_LST(T) ScriptRegistry<T>::ScriptPointerList
-#define SCR_REG_VEC(T) ScriptRegistry<T>::Scripts
+#define SCR_REG_MAP(T) ScriptRegistry<T>::ScriptStoreType
+#define SCR_REG_ITR(T) ScriptRegistry<T>::ScriptStoreIteratorType
+#define SCR_REG_LST(T) ScriptRegistry<T>::Instance()->GetScripts()
// Utility macros for looping over scripts.
#define FOR_SCRIPTS(T, C, E) \
if (SCR_REG_LST(T).empty()) \
return; \
+ \
for (SCR_REG_ITR(T) C = SCR_REG_LST(T).begin(); \
C != SCR_REG_LST(T).end(); ++C)
+
#define FOR_SCRIPTS_RET(T, C, E, R) \
if (SCR_REG_LST(T).empty()) \
return R; \
+ \
for (SCR_REG_ITR(T) C = SCR_REG_LST(T).begin(); \
C != SCR_REG_LST(T).end(); ++C)
+
#define FOREACH_SCRIPT(T) \
FOR_SCRIPTS(T, itr, end) \
- itr->second
+ itr->second
// Utility macros for finding specific scripts.
#define GET_SCRIPT(T, I, V) \
- T* V = ScriptRegistry<T>::GetScriptById(I); \
+ T* V = ScriptRegistry<T>::Instance()->GetScriptById(I); \
if (!V) \
return;
+
#define GET_SCRIPT_RET(T, I, V, R) \
- T* V = ScriptRegistry<T>::GetScriptById(I); \
+ T* V = ScriptRegistry<T>::Instance()->GetScriptById(I); \
if (!V) \
return R;
@@ -240,8 +946,18 @@ struct TSpellSummary
uint8 Effects; // set of enum SelectEffect
} *SpellSummary;
+ScriptObject::ScriptObject(const char* name) : _name(name)
+{
+ sScriptMgr->IncreaseScriptCount();
+}
+
+ScriptObject::~ScriptObject()
+{
+ sScriptMgr->DecreaseScriptCount();
+}
+
ScriptMgr::ScriptMgr()
- : _scriptCount(0), _scheduledScripts(0), _script_loader_callback(nullptr)
+ : _scriptCount(0), _script_loader_callback(nullptr)
{
}
@@ -255,6 +971,9 @@ ScriptMgr* ScriptMgr::instance()
void ScriptMgr::Initialize()
{
+ ASSERT(sSpellMgr->GetSpellInfo(SPELL_HOTSWAP_VISUAL_SPELL_EFFECT)
+ && "Reload hotswap spell effect for creatures isn't valid!");
+
uint32 oldMSTime = getMSTime();
LoadDatabase();
@@ -263,59 +982,85 @@ void ScriptMgr::Initialize()
FillSpellSummary();
+ // Load core scripts
+ SetScriptContext("___static___");
+
+ // SmartAI
AddSC_SmartScripts();
+ // LFGScripts
+ lfg::AddSC_LFGScripts();
+
+ // Load all static linked scripts through the script loader function.
ASSERT(_script_loader_callback,
"Script loader callback wasn't registered!");
-
_script_loader_callback();
-#ifdef SCRIPTS
- for (std::string const& scriptName : UnusedScriptNames)
+ // Initialize all dynamic scripts
+ // and finishes the context switch to do
+ // bulk loading
+ sScriptReloadMgr->Initialize();
+
+ // Loads all scripts from the current context
+ sScriptMgr->SwapScriptContext(true);
+
+ // Print unused script names.
+ std::unordered_set<std::string> unusedScriptNames(
+ sObjectMgr->GetAllScriptNames().begin(),
+ sObjectMgr->GetAllScriptNames().end());
+
+ // Remove the used scripts from the given container.
+ sScriptRegistryCompositum->RemoveUsedScriptsFromContainer(unusedScriptNames);
+
+ for (std::string const& scriptName : unusedScriptNames)
{
- TC_LOG_ERROR("sql.sql", "ScriptName '%s' exists in database, but no core script found!", scriptName.c_str());
+ // Avoid complaining about empty script names since the
+ // script name container contains a placeholder as the 0 element.
+ if (scriptName.empty())
+ continue;
+
+ TC_LOG_ERROR("sql.sql", "ScriptName '%s' exists in database, "
+ "but no core script found!", scriptName.c_str());
}
-#endif
- TC_LOG_INFO("server.loading", ">> Loaded %u C++ scripts in %u ms", GetScriptCount(), GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u C++ scripts in %u ms",
+ GetScriptCount(), GetMSTimeDiffToNow(oldMSTime));
+}
+
+void ScriptMgr::SetScriptContext(std::string const& context)
+{
+ _currentContext = context;
+}
+
+void ScriptMgr::SwapScriptContext(bool initialize)
+{
+ sScriptRegistryCompositum->SwapContext(initialize);
+ _currentContext.clear();
+}
+
+void ScriptMgr::ReleaseScriptContext(std::string const& context)
+{
+ sScriptRegistryCompositum->ReleaseContext(context);
+}
+
+std::shared_ptr<ModuleReference>
+ ScriptMgr::AcquireModuleReferenceOfScriptName(std::string const& scriptname) const
+{
+#ifdef TRINITY_API_USE_DYNAMIC_LINKING
+ // Returns the reference to the module of the given scriptname
+ return ScriptReloadMgr::AcquireModuleReferenceOfContext(
+ sScriptRegistryCompositum->GetScriptContextOfScriptName(scriptname));
+#else
+ (void)scriptname;
+ // Something went wrong when this function is used in
+ // a static linked context.
+ WPAbort();
+#endif // #ifndef TRINITY_API_USE_DYNAMIC_LINKING
}
void ScriptMgr::Unload()
{
- #define SCR_CLEAR(T) \
- for (T* scr : SCR_REG_VEC(T)) \
- delete scr; \
- SCR_REG_VEC(T).clear();
-
- // Clear scripts for every script type.
- SCR_CLEAR(SpellScriptLoader);
- SCR_CLEAR(ServerScript);
- SCR_CLEAR(WorldScript);
- SCR_CLEAR(FormulaScript);
- SCR_CLEAR(WorldMapScript);
- SCR_CLEAR(InstanceMapScript);
- SCR_CLEAR(BattlegroundMapScript);
- SCR_CLEAR(ItemScript);
- SCR_CLEAR(CreatureScript);
- SCR_CLEAR(GameObjectScript);
- SCR_CLEAR(AreaTriggerScript);
- SCR_CLEAR(BattlegroundScript);
- SCR_CLEAR(OutdoorPvPScript);
- SCR_CLEAR(CommandScript);
- SCR_CLEAR(WeatherScript);
- SCR_CLEAR(AuctionHouseScript);
- SCR_CLEAR(ConditionScript);
- SCR_CLEAR(VehicleScript);
- SCR_CLEAR(DynamicObjectScript);
- SCR_CLEAR(TransportScript);
- SCR_CLEAR(AchievementCriteriaScript);
- SCR_CLEAR(PlayerScript);
- SCR_CLEAR(AccountScript);
- SCR_CLEAR(GuildScript);
- SCR_CLEAR(GroupScript);
- SCR_CLEAR(UnitScript);
-
- #undef SCR_CLEAR
+ sScriptRegistryCompositum->Unload();
delete[] SpellSummary;
delete[] UnitAI::AISpellInfo;
@@ -413,38 +1158,22 @@ void ScriptMgr::FillSpellSummary()
}
}
-void ScriptMgr::CreateSpellScripts(uint32 spellId, std::list<SpellScript*>& scriptVector)
+template<typename T, typename F>
+void CreateSpellOrAuraScripts(uint32 spellId, std::list<T*>& scriptVector, F&& extractor)
{
SpellScriptsBounds bounds = sObjectMgr->GetSpellScriptsBounds(spellId);
for (SpellScriptsContainer::iterator itr = bounds.first; itr != bounds.second; ++itr)
{
- SpellScriptLoader* tmpscript = ScriptRegistry<SpellScriptLoader>::GetScriptById(itr->second);
- if (!tmpscript)
+ // When the script is disabled continue with the next one
+ if (!itr->second.second)
continue;
- SpellScript* script = tmpscript->GetSpellScript();
-
- if (!script)
- continue;
-
- script->_Init(&tmpscript->GetName(), spellId);
-
- scriptVector.push_back(script);
- }
-}
-
-void ScriptMgr::CreateAuraScripts(uint32 spellId, std::list<AuraScript*>& scriptVector)
-{
- SpellScriptsBounds bounds = sObjectMgr->GetSpellScriptsBounds(spellId);
-
- for (SpellScriptsContainer::iterator itr = bounds.first; itr != bounds.second; ++itr)
- {
- SpellScriptLoader* tmpscript = ScriptRegistry<SpellScriptLoader>::GetScriptById(itr->second);
+ SpellScriptLoader* tmpscript = sScriptMgr->GetSpellScriptLoader(itr->second.first);
if (!tmpscript)
continue;
- AuraScript* script = tmpscript->GetAuraScript();
+ T* script = (*tmpscript.*extractor)();
if (!script)
continue;
@@ -455,19 +1184,19 @@ void ScriptMgr::CreateAuraScripts(uint32 spellId, std::list<AuraScript*>& script
}
}
-void ScriptMgr::CreateSpellScriptLoaders(uint32 spellId, std::vector<std::pair<SpellScriptLoader*, SpellScriptsContainer::iterator> >& scriptVector)
+void ScriptMgr::CreateSpellScripts(uint32 spellId, std::list<SpellScript*>& scriptVector)
{
- SpellScriptsBounds bounds = sObjectMgr->GetSpellScriptsBounds(spellId);
- scriptVector.reserve(std::distance(bounds.first, bounds.second));
+ CreateSpellOrAuraScripts(spellId, scriptVector, &SpellScriptLoader::GetSpellScript);
+}
- for (SpellScriptsContainer::iterator itr = bounds.first; itr != bounds.second; ++itr)
- {
- SpellScriptLoader* tmpscript = ScriptRegistry<SpellScriptLoader>::GetScriptById(itr->second);
- if (!tmpscript)
- continue;
+void ScriptMgr::CreateAuraScripts(uint32 spellId, std::list<AuraScript*>& scriptVector)
+{
+ CreateSpellOrAuraScripts(spellId, scriptVector, &SpellScriptLoader::GetAuraScript);
+}
- scriptVector.push_back(std::make_pair(tmpscript, itr));
- }
+SpellScriptLoader* ScriptMgr::GetSpellScriptLoader(uint32 scriptId)
+{
+ return ScriptRegistry<SpellScriptLoader>::Instance()->GetScriptById(scriptId);
}
void ScriptMgr::OnNetworkStart()
@@ -1495,56 +2224,62 @@ void ScriptMgr::OnGroupDisband(Group* group)
void ScriptMgr::OnHeal(Unit* healer, Unit* reciever, uint32& gain)
{
FOREACH_SCRIPT(UnitScript)->OnHeal(healer, reciever, gain);
+ FOREACH_SCRIPT(PlayerScript)->OnHeal(healer, reciever, gain);
}
void ScriptMgr::OnDamage(Unit* attacker, Unit* victim, uint32& damage)
{
FOREACH_SCRIPT(UnitScript)->OnDamage(attacker, victim, damage);
+ FOREACH_SCRIPT(PlayerScript)->OnDamage(attacker, victim, damage);
}
void ScriptMgr::ModifyPeriodicDamageAurasTick(Unit* target, Unit* attacker, uint32& damage)
{
FOREACH_SCRIPT(UnitScript)->ModifyPeriodicDamageAurasTick(target, attacker, damage);
+ FOREACH_SCRIPT(PlayerScript)->ModifyPeriodicDamageAurasTick(target, attacker, damage);
}
void ScriptMgr::ModifyMeleeDamage(Unit* target, Unit* attacker, uint32& damage)
{
FOREACH_SCRIPT(UnitScript)->ModifyMeleeDamage(target, attacker, damage);
+ FOREACH_SCRIPT(PlayerScript)->ModifyMeleeDamage(target, attacker, damage);
}
void ScriptMgr::ModifySpellDamageTaken(Unit* target, Unit* attacker, int32& damage)
{
FOREACH_SCRIPT(UnitScript)->ModifySpellDamageTaken(target, attacker, damage);
+ FOREACH_SCRIPT(PlayerScript)->ModifySpellDamageTaken(target, attacker, damage);
}
SpellScriptLoader::SpellScriptLoader(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<SpellScriptLoader>::AddScript(this);
+ ScriptRegistry<SpellScriptLoader>::Instance()->AddScript(this);
}
ServerScript::ServerScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<ServerScript>::AddScript(this);
+ ScriptRegistry<ServerScript>::Instance()->AddScript(this);
}
WorldScript::WorldScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<WorldScript>::AddScript(this);
+ ScriptRegistry<WorldScript>::Instance()->AddScript(this);
}
FormulaScript::FormulaScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<FormulaScript>::AddScript(this);
+ ScriptRegistry<FormulaScript>::Instance()->AddScript(this);
}
UnitScript::UnitScript(const char* name, bool addToScripts)
: ScriptObject(name)
{
- ScriptRegistry<UnitScript>::AddScript(this, addToScripts);
+ if (addToScripts)
+ ScriptRegistry<UnitScript>::Instance()->AddScript(this);
}
WorldMapScript::WorldMapScript(const char* name, uint32 mapId)
@@ -1553,7 +2288,7 @@ WorldMapScript::WorldMapScript(const char* name, uint32 mapId)
if (GetEntry() && !GetEntry()->IsWorldMap())
TC_LOG_ERROR("scripts", "WorldMapScript for map %u is invalid.", mapId);
- ScriptRegistry<WorldMapScript>::AddScript(this);
+ ScriptRegistry<WorldMapScript>::Instance()->AddScript(this);
}
InstanceMapScript::InstanceMapScript(const char* name, uint32 mapId)
@@ -1562,7 +2297,7 @@ InstanceMapScript::InstanceMapScript(const char* name, uint32 mapId)
if (GetEntry() && !GetEntry()->IsDungeon())
TC_LOG_ERROR("scripts", "InstanceMapScript for map %u is invalid.", mapId);
- ScriptRegistry<InstanceMapScript>::AddScript(this);
+ ScriptRegistry<InstanceMapScript>::Instance()->AddScript(this);
}
BattlegroundMapScript::BattlegroundMapScript(const char* name, uint32 mapId)
@@ -1571,122 +2306,117 @@ BattlegroundMapScript::BattlegroundMapScript(const char* name, uint32 mapId)
if (GetEntry() && !GetEntry()->IsBattleground())
TC_LOG_ERROR("scripts", "BattlegroundMapScript for map %u is invalid.", mapId);
- ScriptRegistry<BattlegroundMapScript>::AddScript(this);
+ ScriptRegistry<BattlegroundMapScript>::Instance()->AddScript(this);
}
ItemScript::ItemScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<ItemScript>::AddScript(this);
+ ScriptRegistry<ItemScript>::Instance()->AddScript(this);
}
CreatureScript::CreatureScript(const char* name)
: UnitScript(name, false)
{
- ScriptRegistry<CreatureScript>::AddScript(this);
+ ScriptRegistry<CreatureScript>::Instance()->AddScript(this);
}
GameObjectScript::GameObjectScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<GameObjectScript>::AddScript(this);
+ ScriptRegistry<GameObjectScript>::Instance()->AddScript(this);
}
AreaTriggerScript::AreaTriggerScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<AreaTriggerScript>::AddScript(this);
+ ScriptRegistry<AreaTriggerScript>::Instance()->AddScript(this);
}
BattlegroundScript::BattlegroundScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<BattlegroundScript>::AddScript(this);
+ ScriptRegistry<BattlegroundScript>::Instance()->AddScript(this);
}
OutdoorPvPScript::OutdoorPvPScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<OutdoorPvPScript>::AddScript(this);
+ ScriptRegistry<OutdoorPvPScript>::Instance()->AddScript(this);
}
CommandScript::CommandScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<CommandScript>::AddScript(this);
+ ScriptRegistry<CommandScript>::Instance()->AddScript(this);
}
WeatherScript::WeatherScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<WeatherScript>::AddScript(this);
+ ScriptRegistry<WeatherScript>::Instance()->AddScript(this);
}
AuctionHouseScript::AuctionHouseScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<AuctionHouseScript>::AddScript(this);
+ ScriptRegistry<AuctionHouseScript>::Instance()->AddScript(this);
}
ConditionScript::ConditionScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<ConditionScript>::AddScript(this);
+ ScriptRegistry<ConditionScript>::Instance()->AddScript(this);
}
VehicleScript::VehicleScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<VehicleScript>::AddScript(this);
+ ScriptRegistry<VehicleScript>::Instance()->AddScript(this);
}
DynamicObjectScript::DynamicObjectScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<DynamicObjectScript>::AddScript(this);
+ ScriptRegistry<DynamicObjectScript>::Instance()->AddScript(this);
}
TransportScript::TransportScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<TransportScript>::AddScript(this);
+ ScriptRegistry<TransportScript>::Instance()->AddScript(this);
}
AchievementCriteriaScript::AchievementCriteriaScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<AchievementCriteriaScript>::AddScript(this);
+ ScriptRegistry<AchievementCriteriaScript>::Instance()->AddScript(this);
}
PlayerScript::PlayerScript(const char* name)
: UnitScript(name, false)
{
- ScriptRegistry<PlayerScript>::AddScript(this);
+ ScriptRegistry<PlayerScript>::Instance()->AddScript(this);
}
AccountScript::AccountScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<AccountScript>::AddScript(this);
+ ScriptRegistry<AccountScript>::Instance()->AddScript(this);
}
GuildScript::GuildScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<GuildScript>::AddScript(this);
+ ScriptRegistry<GuildScript>::Instance()->AddScript(this);
}
GroupScript::GroupScript(const char* name)
: ScriptObject(name)
{
- ScriptRegistry<GroupScript>::AddScript(this);
+ ScriptRegistry<GroupScript>::Instance()->AddScript(this);
}
-// Instantiate static members of ScriptRegistry.
-template<class TScript> std::map<uint32, TScript*> ScriptRegistry<TScript>::ScriptPointerList;
-template<class TScript> std::vector<TScript*> ScriptRegistry<TScript>::Scripts;
-template<class TScript> uint32 ScriptRegistry<TScript>::_scriptIdCounter = 0;
-
// Specialize for each script type class like so:
template class TC_GAME_API ScriptRegistry<SpellScriptLoader>;
template class TC_GAME_API ScriptRegistry<ServerScript>;
@@ -1714,13 +2444,3 @@ template class TC_GAME_API ScriptRegistry<GuildScript>;
template class TC_GAME_API ScriptRegistry<GroupScript>;
template class TC_GAME_API ScriptRegistry<UnitScript>;
template class TC_GAME_API ScriptRegistry<AccountScript>;
-
-// Undefine utility macros.
-#undef GET_SCRIPT_RET
-#undef GET_SCRIPT
-#undef FOREACH_SCRIPT
-#undef FOR_SCRIPTS_RET
-#undef FOR_SCRIPTS
-#undef SCR_REG_LST
-#undef SCR_REG_ITR
-#undef SCR_REG_MAP
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index 337e7de4861..cc1b65fa593 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -46,6 +46,7 @@ class InstanceMap;
class InstanceScript;
class Item;
class Map;
+class ModuleReference;
class OutdoorPvP;
class Player;
class Quest;
@@ -157,14 +158,8 @@ class TC_GAME_API ScriptObject
protected:
- ScriptObject(const char* name)
- : _name(name)
- {
- }
-
- virtual ~ScriptObject()
- {
- }
+ ScriptObject(const char* name);
+ virtual ~ScriptObject();
private:
@@ -338,7 +333,8 @@ class TC_GAME_API WorldMapScript : public ScriptObject, public MapScript<Map>
WorldMapScript(const char* name, uint32 mapId);
};
-class TC_GAME_API InstanceMapScript : public ScriptObject, public MapScript<InstanceMap>
+class TC_GAME_API InstanceMapScript
+ : public ScriptObject, public MapScript<InstanceMap>
{
protected:
@@ -834,15 +830,6 @@ class TC_GAME_API GroupScript : public ScriptObject
virtual void OnDisband(Group* /*group*/) { }
};
-// Placed here due to ScriptRegistry::AddScript dependency.
-#define sScriptMgr ScriptMgr::instance()
-
-// namespace
-// {
- typedef std::list<std::string> UnusedScriptNamesContainer;
- TC_GAME_API extern UnusedScriptNamesContainer UnusedScriptNames;
-// }
-
// Manages registration, loading, and execution of scripts.
class TC_GAME_API ScriptMgr
{
@@ -852,16 +839,17 @@ class TC_GAME_API ScriptMgr
ScriptMgr();
virtual ~ScriptMgr();
+ void FillSpellSummary();
+ void LoadDatabase();
+
+ void IncreaseScriptCount() { ++_scriptCount; }
+ void DecreaseScriptCount() { --_scriptCount; }
+
public: /* Initialization */
static ScriptMgr* instance();
void Initialize();
- void LoadDatabase();
- void FillSpellSummary();
-
- const char* ScriptsVersion() const { return "Integrated Trinity Scripts"; }
- void IncrementScriptCount() { ++_scriptCount; }
uint32 GetScriptCount() const { return _scriptCount; }
typedef void(*ScriptLoaderCallbackType)();
@@ -873,6 +861,27 @@ class TC_GAME_API ScriptMgr
_script_loader_callback = script_loader_callback;
}
+ public: /* Script contexts */
+ /// Set the current script context, which allows the ScriptMgr
+ /// to accept new scripts in this context.
+ /// Requires a SwapScriptContext() call afterwards to load the new scripts.
+ void SetScriptContext(std::string const& context);
+ /// Returns the current script context.
+ std::string const& GetCurrentScriptContext() const { return _currentContext; }
+ /// Releases all scripts associated with the given script context immediately.
+ /// Requires a SwapScriptContext() call afterwards to finish the unloading.
+ void ReleaseScriptContext(std::string const& context);
+ /// Executes all changed introduced by SetScriptContext and ReleaseScriptContext.
+ /// It is possible to combine multiple SetScriptContext and ReleaseScriptContext
+ /// calls for better performance (bulk changes).
+ void SwapScriptContext(bool initialize = false);
+
+ /// Acquires a strong module reference to the module containing the given script name,
+ /// which prevents the shared library which contains the script from unloading.
+ /// The shared library is lazy unloaded as soon as all references to it are released.
+ std::shared_ptr<ModuleReference> AcquireModuleReferenceOfScriptName(
+ std::string const& scriptname) const;
+
public: /* Unloading */
void Unload();
@@ -881,7 +890,7 @@ class TC_GAME_API ScriptMgr
void CreateSpellScripts(uint32 spellId, std::list<SpellScript*>& scriptVector);
void CreateAuraScripts(uint32 spellId, std::list<AuraScript*>& scriptVector);
- void CreateSpellScriptLoaders(uint32 spellId, std::vector<std::pair<SpellScriptLoader*, std::multimap<uint32, uint32>::iterator> >& scriptVector);
+ SpellScriptLoader* GetSpellScriptLoader(uint32 scriptId);
public: /* ServerScript */
@@ -1094,21 +1103,14 @@ class TC_GAME_API ScriptMgr
void ModifyMeleeDamage(Unit* target, Unit* attacker, uint32& damage);
void ModifySpellDamageTaken(Unit* target, Unit* attacker, int32& damage);
- public: /* Scheduled scripts */
-
- uint32 IncreaseScheduledScriptsCount() { return ++_scheduledScripts; }
- uint32 DecreaseScheduledScriptCount() { return --_scheduledScripts; }
- uint32 DecreaseScheduledScriptCount(size_t count) { return _scheduledScripts -= count; }
- bool IsScriptScheduled() const { return _scheduledScripts > 0; }
-
private:
-
uint32 _scriptCount;
- //atomic op counter for active scripts amount
- std::atomic<uint32> _scheduledScripts;
-
ScriptLoaderCallbackType _script_loader_callback;
+
+ std::string _currentContext;
};
+#define sScriptMgr ScriptMgr::instance()
+
#endif
diff --git a/src/server/game/Scripting/ScriptReloadMgr.cpp b/src/server/game/Scripting/ScriptReloadMgr.cpp
new file mode 100644
index 00000000000..aac0e26f02b
--- /dev/null
+++ b/src/server/game/Scripting/ScriptReloadMgr.cpp
@@ -0,0 +1,1520 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "ScriptReloadMgr.h"
+#include "Errors.h"
+
+#ifndef TRINITY_API_USE_DYNAMIC_LINKING
+
+// This method should never be called
+std::shared_ptr<ModuleReference>
+ ScriptReloadMgr::AcquireModuleReferenceOfContext(std::string const& /*context*/)
+{
+ WPAbort();
+}
+
+// Returns the empty implemented ScriptReloadMgr
+ScriptReloadMgr* ScriptReloadMgr::instance()
+{
+ static ScriptReloadMgr instance;
+ return &instance;
+}
+
+#else
+
+#include <algorithm>
+#include <regex>
+#include <vector>
+#include <future>
+#include <memory>
+#include <fstream>
+#include <type_traits>
+#include <unordered_set>
+#include <unordered_map>
+
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/system/system_error.hpp>
+
+#include "efsw/efsw.hpp"
+
+#include "Log.h"
+#include "Config.h"
+#include "BuiltInConfig.h"
+#include "ScriptMgr.h"
+#include "StartProcess.h"
+#include "MPSCQueue.h"
+#include "GitRevision.h"
+
+namespace fs = boost::filesystem;
+
+#ifdef _WIN32
+ #include <windows.h>
+#else // Posix
+ #include <dlfcn.h>
+#endif
+
+// Promote the sScriptReloadMgr to a HotSwapScriptReloadMgr
+// in this compilation unit.
+#undef sScriptReloadMgr
+#define sScriptReloadMgr static_cast<HotSwapScriptReloadMgr*>(ScriptReloadMgr::instance())
+
+// Returns "" on Windows and "lib" on posix.
+static char const* GetSharedLibraryPrefix()
+{
+#ifdef _WIN32
+ return "";
+#else // Posix
+ return "lib";
+#endif
+}
+
+// Returns "dll" on Windows and "so" on posix.
+static char const* GetSharedLibraryExtension()
+{
+#ifdef _WIN32
+ return "dll";
+#else // Posix
+ return "so";
+#endif
+}
+
+#ifdef _WIN32
+typedef HMODULE HandleType;
+#else // Posix
+typedef void* HandleType;
+#endif
+
+class SharedLibraryUnloader
+{
+public:
+ SharedLibraryUnloader()
+ : _path() { }
+ explicit SharedLibraryUnloader(fs::path const& path)
+ : _path(path) { }
+
+ void operator() (HandleType handle) const
+ {
+ // Unload the associated shared library.
+#ifdef _WIN32
+ bool success = (FreeLibrary(handle) != 0);
+#else // Posix
+ bool success = (dlclose(handle) == 0);
+#endif
+
+ if (!success)
+ {
+ TC_LOG_ERROR("scripts.hotswap", "Failed to unload (syscall) the shared library \"%s\".",
+ _path.generic_string().c_str());
+
+ return;
+ }
+
+ boost::system::error_code error;
+ if (fs::remove(_path, error))
+ {
+ TC_LOG_TRACE("scripts.hotswap", "Lazy unloaded and deleted the shared library \"%s\".",
+ _path.generic_string().c_str());
+ }
+ else
+ {
+ TC_LOG_ERROR("scripts.hotswap", "Failed to delete the shared library \"%s\" (%s).",
+ _path.generic_string().c_str(), error.message().c_str());
+ }
+ }
+
+private:
+ fs::path _path;
+};
+
+typedef std::unique_ptr<typename std::remove_pointer<HandleType>::type, SharedLibraryUnloader> HandleHolder;
+
+typedef char const* (*GetScriptModuleRevisionHashType)();
+typedef void (*AddScriptsType)();
+typedef char const* (*GetScriptModuleType)();
+typedef char const* (*GetBuildDirectiveType)();
+
+class ScriptModule
+ : public ModuleReference
+{
+public:
+ explicit ScriptModule(HandleHolder handle, GetScriptModuleRevisionHashType getScriptModuleRevisionHash,
+ AddScriptsType addScripts, GetScriptModuleType getScriptModule,
+ GetBuildDirectiveType getBuildDirective, fs::path const& path)
+ : _handle(std::forward<HandleHolder>(handle)), _getScriptModuleRevisionHash(getScriptModuleRevisionHash),
+ _addScripts(addScripts), _getScriptModule(getScriptModule),
+ _getBuildDirective(getBuildDirective), _path(path) { }
+
+ ScriptModule(ScriptModule const&) = delete;
+ ScriptModule(ScriptModule&& right) = delete;
+
+ ScriptModule& operator= (ScriptModule const&) = delete;
+ ScriptModule& operator= (ScriptModule&& right) = delete;
+
+ static Optional<std::shared_ptr<ScriptModule>> CreateFromPath(fs::path const& path);
+
+ char const* GetScriptModuleRevisionHash() const override
+ {
+ return _getScriptModuleRevisionHash();
+ }
+
+ void AddScripts() const
+ {
+ return _addScripts();
+ }
+
+ char const* GetScriptModule() const override
+ {
+ return _getScriptModule();
+ }
+
+ char const* GetBuildDirective() const
+ {
+ return _getBuildDirective();
+ }
+
+ fs::path const& GetModulePath() const override
+ {
+ return _path;
+ }
+
+private:
+ HandleHolder _handle;
+
+ GetScriptModuleRevisionHashType _getScriptModuleRevisionHash;
+ AddScriptsType _addScripts;
+ GetScriptModuleType _getScriptModule;
+ GetBuildDirectiveType _getBuildDirective;
+
+ fs::path _path;
+};
+
+template<typename Fn>
+static bool GetFunctionFromSharedLibrary(HandleType handle, std::string const& name, Fn& fn)
+{
+#ifdef _WIN32
+ fn = reinterpret_cast<Fn>(GetProcAddress(handle, name.c_str()));
+#else // Posix
+ fn = reinterpret_cast<Fn>(dlsym(handle, name.c_str()));
+#endif
+ return fn != nullptr;
+}
+
+// Load a shared library from the given path.
+Optional<std::shared_ptr<ScriptModule>> ScriptModule::CreateFromPath(fs::path const& path)
+{
+#ifdef _WIN32
+ HandleType handle = LoadLibrary(path.generic_string().c_str());
+#else // Posix
+ HandleType handle = dlopen(path.c_str(), RTLD_LAZY);
+#endif
+
+ if (!handle)
+ {
+ TC_LOG_ERROR("scripts.hotswap", "Could not load the shared library \"%s\" for reading.",
+ path.generic_string().c_str());
+ return boost::none;
+ }
+
+ // Use RAII to release the library on failure.
+ HandleHolder holder(handle, SharedLibraryUnloader(path));
+
+ GetScriptModuleRevisionHashType getScriptModuleRevisionHash;
+ AddScriptsType addScripts;
+ GetScriptModuleType getScriptModule;
+ GetBuildDirectiveType getBuildDirective;
+
+ if (GetFunctionFromSharedLibrary(handle, "GetScriptModuleRevisionHash", getScriptModuleRevisionHash) &&
+ GetFunctionFromSharedLibrary(handle, "AddScripts", addScripts) &&
+ GetFunctionFromSharedLibrary(handle, "GetScriptModule", getScriptModule) &&
+ GetFunctionFromSharedLibrary(handle, "GetBuildDirective", getBuildDirective))
+ return std::make_shared<ScriptModule>(std::move(holder), getScriptModuleRevisionHash,
+ addScripts, getScriptModule, getBuildDirective, path);
+ else
+ {
+ TC_LOG_ERROR("scripts.hotswap", "Could not extract all required functions from the shared library \"%s\"!",
+ path.generic_string().c_str());
+
+ return boost::none;
+ }
+}
+
+static bool HasValidScriptModuleName(std::string const& name)
+{
+ // Detects scripts_NAME.dll's / .so's
+ static std::regex const regex(
+ Trinity::StringFormat("^%s[sS]cripts_[a-zA-Z0-9_]+\\.%s$",
+ GetSharedLibraryPrefix(),
+ GetSharedLibraryExtension()));
+
+ return std::regex_match(name, regex);
+}
+
+/// File watcher responsible for watching shared libraries
+class LibraryUpdateListener : public efsw::FileWatchListener
+{
+public:
+ LibraryUpdateListener() { }
+ virtual ~LibraryUpdateListener() { }
+
+ void handleFileAction(efsw::WatchID /*watchid*/, std::string const& dir,
+ std::string const& filename, efsw::Action action, std::string oldFilename = "") final override;
+};
+
+static LibraryUpdateListener libraryUpdateListener;
+
+/// File watcher responsible for watching source files
+class SourceUpdateListener : public efsw::FileWatchListener
+{
+ fs::path const path_;
+
+ std::string const script_module_name_;
+
+ efsw::WatchID const watcher_id_;
+
+public:
+ explicit SourceUpdateListener(fs::path path, std::string script_module_name);
+
+ virtual ~SourceUpdateListener();
+
+ void handleFileAction(efsw::WatchID /*watchid*/, std::string const& dir,
+ std::string const& filename, efsw::Action action, std::string oldFilename = "") final override;
+};
+
+namespace std
+{
+ template <>
+ struct hash<fs::path>
+ {
+ hash<string> hasher;
+
+ std::size_t operator()(fs::path const& key) const
+ {
+ return hasher(key.generic_string());
+ }
+ };
+}
+
+/// Invokes a synchronous CMake process with the given arguments
+template<typename... T>
+static int InvokeCMakeCommand(T&&... args)
+{
+ auto const executable = BuiltInConfig::GetCMakeCommand();
+ return Trinity::StartProcess(executable, {
+ executable,
+ std::forward<T>(args)...
+ }, "scripts.hotswap");
+}
+
+/// Invokes an asynchronous CMake process with the given arguments
+template<typename... T>
+static std::shared_ptr<Trinity::AsyncProcessResult> InvokeAsyncCMakeCommand(T&&... args)
+{
+ auto const executable = BuiltInConfig::GetCMakeCommand();
+ return Trinity::StartAsyncProcess(executable, {
+ executable,
+ std::forward<T>(args)...
+ }, "scripts.hotswap");
+}
+
+/// Calculates the C++ project name of the given module which is
+/// the lowercase string of scripts_${module}.
+static std::string CalculateScriptModuleProjectName(std::string const& module)
+{
+ std::string module_project = "scripts_" + module;
+ std::transform(module_project.begin(), module_project.end(),
+ module_project.begin(), ::tolower);
+
+ return module_project;
+}
+
+/// Returns false when there isn't any attached debugger to the process which
+/// could block the rebuild of new shared libraries.
+static bool IsDebuggerBlockingRebuild()
+{
+#ifdef _WIN32
+ if (IsDebuggerPresent())
+ return true;
+#endif
+ return false;
+}
+
+/// ScriptReloadMgr which is used when dynamic linking is enabled
+///
+/// This class manages shared library loading/unloading through watching
+/// the script module directory. Loaded shared libraries are mirrored
+/// into a .cache subdirectory to allow lazy unloading as long as
+/// the shared library is still used which is useful for scripts
+/// which can't be instantly replaced like spells or instances.
+/// Several modules which reference different versions can be kept loaded
+/// to serve scripts of different versions to entities and spells.
+///
+/// Also this class invokes rebuilds as soon as the source of loaded
+/// scripts change and installs the modules correctly through CMake.
+class HotSwapScriptReloadMgr final
+ : public ScriptReloadMgr
+{
+ friend class ScriptReloadMgr;
+ friend class SourceUpdateListener;
+
+ /// Reflects a queued change on a shared library or shared library
+ /// which is waiting for processing
+ enum class ChangeStateRequest : uint8
+ {
+ CHANGE_REQUEST_ADDED,
+ CHANGE_REQUEST_MODIFIED,
+ CHANGE_REQUEST_REMOVED
+ };
+
+ /// Reflects a running job of an invoked asynchronous external process
+ enum class BuildJobType : uint8
+ {
+ BUILD_JOB_NONE,
+ BUILD_JOB_RERUN_CMAKE,
+ BUILD_JOB_COMPILE,
+ BUILD_JOB_INSTALL,
+ };
+
+ // Represents a job which was invoked through a source or shared library change
+ class BuildJob
+ {
+ // Script module which is processed in the current running job
+ std::string script_module_name_;
+ // The C++ project name of the module which is processed
+ std::string script_module_project_name_;
+ // The build directive of the current module which is processed
+ // like "Release" or "Debug". The build directive from the
+ // previous same module is used if there was any.
+ std::string script_module_build_directive_;
+
+ // Type of the current running job
+ BuildJobType type_;
+ // The async process result of the current job
+ std::shared_ptr<Trinity::AsyncProcessResult> async_result_;
+
+ public:
+ explicit BuildJob(std::string script_module_name, std::string script_module_project_name,
+ std::string script_module_build_directive)
+ : script_module_name_(std::move(script_module_name)),
+ script_module_project_name_(std::move(script_module_project_name)),
+ script_module_build_directive_(std::move(script_module_build_directive)),
+ type_(BuildJobType::BUILD_JOB_NONE) { }
+
+ bool IsValid() const
+ {
+ return type_ != BuildJobType::BUILD_JOB_NONE;
+ }
+
+ std::string const& GetModuleName() const { return script_module_name_; }
+
+ std::string const& GetProjectName() const { return script_module_project_name_; }
+
+ std::string const& GetBuildDirective() const { return script_module_build_directive_; }
+
+ BuildJobType GetType() const { return type_; }
+
+ std::shared_ptr<Trinity::AsyncProcessResult> const& GetProcess() const
+ {
+ ASSERT(async_result_, "Tried to access an empty process handle!");
+ return async_result_;
+ }
+
+ /// Updates the current running job with the given type and async result
+ void UpdateCurrentJob(BuildJobType type,
+ std::shared_ptr<Trinity::AsyncProcessResult> async_result)
+ {
+ ASSERT(type != BuildJobType::BUILD_JOB_NONE, "None isn't allowed here!");
+ ASSERT(async_result, "The async result must not be empty!");
+
+ type_ = type;
+ async_result_ = std::move(async_result);
+ }
+ };
+
+ /// Base class for lockfree asynchronous messages to the script reloader
+ class ScriptReloaderMessage
+ {
+ public:
+ virtual ~ScriptReloaderMessage() { }
+
+ /// Invoke this function to run a message thread safe on the reloader
+ virtual void operator() (HotSwapScriptReloadMgr* reloader) = 0;
+ };
+
+ /// Implementation class which wraps functional types and dispatches
+ /// it in the overwritten implementation of the reloader messages.
+ template<typename T>
+ class ScriptReloaderMessageImplementation
+ : public ScriptReloaderMessage
+ {
+ T dispatcher_;
+
+ public:
+ explicit ScriptReloaderMessageImplementation(T dispatcher)
+ : dispatcher_(std::move(dispatcher)) { }
+
+ void operator() (HotSwapScriptReloadMgr* reloader) final override
+ {
+ dispatcher_(reloader);
+ }
+ };
+
+ /// Uses the given functional type and creates a asynchronous reloader
+ /// message on the heap, which requires deletion.
+ template<typename T>
+ auto MakeMessage(T&& dispatcher)
+ -> ScriptReloaderMessageImplementation<typename std::decay<T>::type>*
+ {
+ return new ScriptReloaderMessageImplementation<typename std::decay<T>::type>
+ (std::forward<T>(dispatcher));
+ }
+
+public:
+ HotSwapScriptReloadMgr()
+ : _libraryWatcher(-1), _unique_library_name_counter(0),
+ _last_time_library_changed(0), _last_time_sources_changed(0),
+ _last_time_user_informed(0), terminate_early(false) { }
+
+ virtual ~HotSwapScriptReloadMgr()
+ {
+ // Delete all messages
+ ScriptReloaderMessage* message;
+ while (_messages.Dequeue(message))
+ delete message;
+ }
+
+ /// Returns the absolute path to the script module directory
+ static fs::path GetLibraryDirectory()
+ {
+ return fs::absolute(sConfigMgr->GetStringDefault("HotSwap.ScriptDir", "scripts"));
+ }
+
+ /// Returns the absolute path to the scripts directory in the source tree.
+ static fs::path GetSourceDirectory()
+ {
+ fs::path dir = BuiltInConfig::GetSourceDirectory();
+ dir /= "src";
+ dir /= "server";
+ dir /= "scripts";
+ return dir;
+ }
+
+ /// Initializes the file watchers and loads all existing shared libraries
+ /// into the running server.
+ void Initialize() final override
+ {
+ if (!sWorld->getBoolConfig(CONFIG_HOTSWAP_ENABLED))
+ return;
+
+ if (BuiltInConfig::GetBuildDirectory().find(" ") != std::string::npos)
+ {
+ TC_LOG_ERROR("scripts.hotswap", "Your build directory path \"%s\" "
+ "contains spaces, which isn't allowed for compatibility reasons! "
+ "You need to create a build directory which doesn't contain any space character "
+ "in it's path!",
+ BuiltInConfig::GetBuildDirectory().c_str());
+
+ return;
+ }
+
+ {
+ auto const library_directory = GetLibraryDirectory();
+ if (!fs::exists(library_directory) || !fs::is_directory(library_directory))
+ {
+ TC_LOG_ERROR("scripts.hotswap", "Library directory \"%s\" doesn't exist!.",
+ library_directory.generic_string().c_str());
+ return;
+ }
+ }
+
+ // Get the cache directory path
+ fs::path const cache_path = []
+ {
+ auto path = fs::absolute(sScriptReloadMgr->GetLibraryDirectory());
+ path /= ".cache";
+ return path;
+ }();
+
+ // We use the boost filesystem function versions which accept
+ // an error code to prevent it from throwing exceptions.
+ boost::system::error_code code;
+ if ((!fs::exists(cache_path, code) || (fs::remove_all(cache_path, code) > 0)) &&
+ !fs::create_directory(cache_path, code))
+ {
+ TC_LOG_ERROR("scripts.hotswap", "Couldn't create the cache directory \"%s\".",
+ cache_path.generic_string().c_str());
+ return;
+ }
+
+ // Used to silent compiler warnings
+ (void)code;
+
+ // Correct the CMake prefix when needed
+ if (sWorld->getBoolConfig(CONFIG_HOTSWAP_PREFIX_CORRECTION_ENABLED))
+ DoCMakePrefixCorrectionIfNeeded();
+
+ InitializeDefaultLibraries();
+ InitializeFileWatchers();
+ }
+
+ /// Needs to be called periodically from the worldserver loop
+ /// to invoke queued actions like module loading/unloading and script
+ /// compilation.
+ /// This method should be invoked from a thread safe point to
+ /// prevent misbehavior.
+ void Update() final override
+ {
+ // Consume all messages
+ ScriptReloaderMessage* message;
+ while (_messages.Dequeue(message))
+ {
+ (*message)(this);
+ delete message;
+ }
+
+ DispatchRunningBuildJobs();
+ DispatchModuleChanges();
+ }
+
+ /// Unloads the manager and cancels all runnings jobs immediately
+ void Unload() final override
+ {
+ if (_libraryWatcher >= 0)
+ {
+ _fileWatcher.removeWatch(_libraryWatcher);
+ _libraryWatcher = -1;
+ }
+
+ // If a build is in progress cancel it
+ if (_build_job)
+ {
+ _build_job->GetProcess()->Terminate();
+ _build_job.reset();
+ }
+
+ // Release all strong references to script modules
+ // to trigger unload actions as early as possible,
+ // otherwise the worldserver will crash on exit.
+ _running_script_modules.clear();
+ }
+
+ /// Queue's a thread safe message to the reloader which is executed on
+ /// the next world server update tick.
+ template<typename T>
+ void QueueMessage(T&& message)
+ {
+ _messages.Enqueue(MakeMessage(std::forward<T>(message)));
+ }
+
+ /// Queues an action which marks the given shared library as changed
+ /// which will add, unload or reload it at the next world update tick.
+ /// This method is thread safe.
+ void QueueSharedLibraryChanged(fs::path const& path)
+ {
+ _last_time_library_changed = getMSTime();
+ _libraries_changed.insert(path);
+ }
+
+ /// Queues a notification that a source file was added
+ /// This method is thread unsafe.
+ void QueueAddSourceFile(std::string const& module_name, fs::path const& path)
+ {
+ UpdateSourceChangeRequest(module_name, path, ChangeStateRequest::CHANGE_REQUEST_ADDED);
+ }
+
+ /// Queues a notification that a source file was modified
+ /// This method is thread unsafe.
+ void QueueModifySourceFile(std::string const& module_name, fs::path const& path)
+ {
+ UpdateSourceChangeRequest(module_name, path, ChangeStateRequest::CHANGE_REQUEST_MODIFIED);
+ }
+
+ /// Queues a notification that a source file was removed
+ /// This method is thread unsafe.
+ void QueueRemoveSourceFile(std::string const& module_name, fs::path const& path)
+ {
+ UpdateSourceChangeRequest(module_name, path, ChangeStateRequest::CHANGE_REQUEST_REMOVED);
+ }
+
+private:
+ // Loads all shared libraries which are contained in the
+ // scripts directory on startup.
+ void InitializeDefaultLibraries()
+ {
+ fs::path const libraryDirectory(GetLibraryDirectory());
+ fs::directory_iterator const dir_end;
+
+ uint32 count = 0;
+
+ // Iterate through all shared libraries in the script directory and load it
+ for (fs::directory_iterator dir_itr(libraryDirectory); dir_itr != dir_end ; ++dir_itr)
+ if (fs::is_regular_file(dir_itr->path()) && HasValidScriptModuleName(dir_itr->path().filename().generic_string()))
+ {
+ TC_LOG_INFO("scripts.hotswap", "Loading script module \"%s\"...",
+ dir_itr->path().filename().generic_string().c_str());
+
+ // Don't swap the script context to do bulk loading
+ ProcessLoadScriptModule(dir_itr->path(), false);
+ ++count;
+ }
+
+ TC_LOG_INFO("scripts.hotswap", ">> Loaded %u script modules.", count);
+ }
+
+ // Initialize all enabled file watchers.
+ // Needs to be called after InitializeDefaultLibraries()!
+ void InitializeFileWatchers()
+ {
+ _libraryWatcher = _fileWatcher.addWatch(GetLibraryDirectory().generic_string(), &libraryUpdateListener, false);
+ if (_libraryWatcher >= 0)
+ {
+ TC_LOG_INFO("scripts.hotswap", ">> Library reloader is listening on \"%s\".",
+ GetLibraryDirectory().generic_string().c_str());
+ }
+ else
+ {
+ TC_LOG_ERROR("scripts.hotswap", "Failed to initialize the library reloader on \"%s\".",
+ GetLibraryDirectory().generic_string().c_str());
+ }
+
+ _fileWatcher.watch();
+ }
+
+ /// Updates the current state of the given source path
+ void UpdateSourceChangeRequest(std::string const& module_name,
+ fs::path const& path,
+ ChangeStateRequest state)
+ {
+ _last_time_sources_changed = getMSTime();
+
+ // Write when there is no module with the given name known
+ auto module_itr = _sources_changed.find(module_name);
+
+ // When the file was modified it's enough to mark the module as
+ // dirty by initializing the associated map.
+ if (module_itr == _sources_changed.end())
+ module_itr = _sources_changed.insert(std::make_pair(
+ module_name, decltype(_sources_changed)::mapped_type{})).first;
+
+ // Leave when the file was just modified as explained above
+ if (state == ChangeStateRequest::CHANGE_REQUEST_MODIFIED)
+ return;
+
+ // Insert when the given path isn't existent
+ auto const itr = module_itr->second.find(path);
+ if (itr == module_itr->second.end())
+ {
+ module_itr->second.insert(std::make_pair(path, state));
+ return;
+ }
+
+ ASSERT((itr->second == ChangeStateRequest::CHANGE_REQUEST_ADDED)
+ || (itr->second == ChangeStateRequest::CHANGE_REQUEST_REMOVED),
+ "Stored value is invalid!");
+
+ ASSERT((state == ChangeStateRequest::CHANGE_REQUEST_ADDED)
+ || (state == ChangeStateRequest::CHANGE_REQUEST_REMOVED),
+ "The given state is invalid!");
+
+ ASSERT(state != itr->second,
+ "Tried to apply a state which is stored already!");
+
+ module_itr->second.erase(itr);
+ }
+
+ /// Called periodically on the worldserver tick to process all
+ /// load/unload/reload requests of shared libraries.
+ void DispatchModuleChanges()
+ {
+ // When there are no libraries to change return
+ if (_libraries_changed.empty())
+ return;
+
+ // Wait some time after changes to catch bulk changes
+ if (GetMSTimeDiffToNow(_last_time_library_changed) < 500)
+ return;
+
+ for (auto const& path : _libraries_changed)
+ {
+ bool const is_running =
+ _running_script_module_names.find(path) != _running_script_module_names.end();
+
+ bool const exists = fs::exists(path);
+
+ if (is_running)
+ {
+ if (exists)
+ ProcessReloadScriptModule(path);
+ else
+ ProcessUnloadScriptModule(path);
+ }
+ else if (exists)
+ ProcessLoadScriptModule(path);
+ }
+
+ _libraries_changed.clear();
+ }
+
+ void ProcessLoadScriptModule(fs::path const& path, bool swap_context = true)
+ {
+ ASSERT(_running_script_module_names.find(path) == _running_script_module_names.end(),
+ "Can't load a module which is running already!");
+
+ // Create the cache path and increment the library counter to use an unique name for each library
+ fs::path cache_path = fs::absolute(sScriptReloadMgr->GetLibraryDirectory());
+ cache_path /= ".cache";
+ cache_path /= Trinity::StringFormat("%s.%u%s",
+ path.stem().generic_string().c_str(),
+ _unique_library_name_counter++,
+ path.extension().generic_string().c_str());
+
+ if ([&]
+ {
+ boost::system::error_code code;
+ fs::copy_file(path, cache_path, fs::copy_option::fail_if_exists, code);
+ return code;
+ }())
+ {
+ TC_LOG_FATAL("scripts.hotswap", ">> Failed to create cache entry for module \"%s\"!",
+ path.filename().generic_string().c_str());
+
+ // Find a better solution for this but it's much better
+ // to start the core without scripts
+ std::this_thread::sleep_for(std::chrono::seconds(5));
+ ABORT();
+ return;
+ }
+
+ auto module = ScriptModule::CreateFromPath(cache_path);
+ if (!module)
+ {
+ TC_LOG_FATAL("scripts.hotswap", ">> Failed to load script module \"%s\"!",
+ path.filename().generic_string().c_str());
+
+ // Find a better solution for this but it's much better
+ // to start the core without scripts
+ std::this_thread::sleep_for(std::chrono::seconds(5));
+ ABORT();
+ return;
+ }
+
+ // Limit the git revision hash to 7 characters.
+ std::string module_revision((*module)->GetScriptModuleRevisionHash());
+ if (module_revision.size() >= 7)
+ module_revision = module_revision.substr(0, 7);
+
+ std::string const module_name = (*module)->GetScriptModule();
+ TC_LOG_INFO("scripts.hotswap", ">> Loaded script module \"%s\" (\"%s\" - %s).",
+ path.filename().generic_string().c_str(), module_name.c_str(), module_revision.c_str());
+
+ if (module_revision.empty())
+ {
+ TC_LOG_WARN("scripts.hotswap", ">> Script module \"%s\" has an empty revision hash!",
+ path.filename().generic_string().c_str());
+ }
+ else
+ {
+ // Trim the revision hash
+ std::string my_revision_hash = GitRevision::GetHash();
+ std::size_t const trim = std::min(module_revision.size(), my_revision_hash.size());
+ my_revision_hash = my_revision_hash.substr(0, trim);
+ module_revision = module_revision.substr(0, trim);
+
+ if (my_revision_hash != module_revision)
+ {
+ TC_LOG_WARN("scripts.hotswap", ">> Script module \"%s\" has a different revision hash! "
+ "Binary incompatibility could lead to unknown behaviour!", path.filename().generic_string().c_str());
+ }
+ }
+
+ {
+ auto const itr = _running_script_modules.find(module_name);
+ if (itr != _running_script_modules.end())
+ {
+ TC_LOG_ERROR("scripts.hotswap", ">> Attempt to load a module twice \"%s\" (loaded module is at %s)!",
+ path.generic_string().c_str(), itr->second.first->GetModulePath().generic_string().c_str());
+
+ return;
+ }
+ }
+
+ sScriptMgr->SetScriptContext(module_name);
+ (*module)->AddScripts();
+ TC_LOG_TRACE("scripts.hotswap", ">> Registered all scripts of module %s.", module_name.c_str());
+
+ if (swap_context)
+ sScriptMgr->SwapScriptContext();
+
+ // Create the source listener
+ auto listener = Trinity::make_unique<SourceUpdateListener>(
+ sScriptReloadMgr->GetSourceDirectory() / module_name,
+ module_name);
+
+ // Store the module
+ _known_modules_build_directives.insert(std::make_pair(module_name, (*module)->GetBuildDirective()));
+ _running_script_modules.insert(std::make_pair(module_name,
+ std::make_pair(std::move(*module), std::move(listener))));
+ _running_script_module_names.insert(std::make_pair(path, module_name));
+ }
+
+ void ProcessReloadScriptModule(fs::path const& path)
+ {
+ ProcessUnloadScriptModule(path, false);
+ ProcessLoadScriptModule(path);
+ }
+
+ void ProcessUnloadScriptModule(fs::path const& path, bool finish = true)
+ {
+ auto const itr = _running_script_module_names.find(path);
+
+ ASSERT(itr != _running_script_module_names.end(),
+ "Can't unload a module which isn't running!");
+
+ // Unload the script context
+ sScriptMgr->ReleaseScriptContext(itr->second);
+
+ if (finish)
+ sScriptMgr->SwapScriptContext();
+
+ TC_LOG_INFO("scripts.hotswap", "Released script module \"%s\" (\"%s\")...",
+ path.filename().generic_string().c_str(), itr->second.c_str());
+
+ // Unload the script module
+ auto ref = _running_script_modules.find(itr->second);
+ ASSERT(ref != _running_script_modules.end() &&
+ "Expected the script reference to be present!");
+
+ // Yield a message when there are other owning references to
+ // the module which prevents it from unloading.
+ // The module will be unloaded once all scripts provided from the module
+ // are destroyed.
+ if (!ref->second.first.unique())
+ {
+ TC_LOG_INFO("scripts.hotswap",
+ "Script module %s is still used by %lu spell, aura or instance scripts. "
+ "Will lazy unload the module once all scripts stopped using it, "
+ "to use the latest version of an edited script unbind yourself from "
+ "the instance or re-cast the spell.",
+ ref->second.first->GetScriptModule(), ref->second.first.use_count() - 1);
+ }
+
+ // Remove the owning reference from the reloader
+ _running_script_modules.erase(ref);
+ _running_script_module_names.erase(itr);
+ }
+
+ /// Called periodically on the worldserver tick to process all recompile
+ /// requests. This method invokes one build or install job at the time
+ void DispatchRunningBuildJobs()
+ {
+ if (_build_job)
+ {
+ // Terminate the current build job when an associated source was changed
+ // while compiling and the terminate early option is enabled.
+ if (sWorld->getBoolConfig(CONFIG_HOTSWAP_EARLY_TERMINATION_ENABLED))
+ {
+ if (!terminate_early && _sources_changed.find(_build_job->GetModuleName()) != _sources_changed.end())
+ {
+ /*
+ FIXME: Currently crashes the server
+ TC_LOG_INFO("scripts.hotswap", "Terminating the running build of module \"%s\"...",
+ _build_job->GetModuleName().c_str());
+
+ _build_job->GetProcess()->Terminate();
+ _build_job.reset();
+
+ // Continue with the default execution path
+ DispatchRunningBuildJobs();
+ return;
+ */
+
+ terminate_early = true;
+ return;
+ }
+ }
+
+ // Wait for the current build job to finish, if the job finishes in time
+ // evaluate it and continue with the next one.
+ if (_build_job->GetProcess()->GetFutureResult().
+ wait_for(std::chrono::seconds(0)) == std::future_status::ready)
+ ProcessReadyBuildJob();
+ else
+ return; // Return when the job didn't finish in time
+
+ // Skip this cycle when the previous job scheduled a new one
+ if (_build_job)
+ return;
+ }
+
+ // Avoid burst updates through waiting for a short time after changes
+ if ((_last_time_sources_changed != 0) &&
+ (GetMSTimeDiffToNow(_last_time_sources_changed) < 500))
+ return;
+
+ // If the changed sources are empty do nothing
+ if (_sources_changed.empty())
+ return;
+
+ // Wait until are attached debugger were detached.
+ if (IsDebuggerBlockingRebuild())
+ {
+ if ((_last_time_user_informed == 0) ||
+ (GetMSTimeDiffToNow(_last_time_user_informed) > 7500))
+ {
+ _last_time_user_informed = getMSTime();
+
+ // Informs the user that the attached debugger is blocking the automatic script rebuild.
+ TC_LOG_INFO("scripts.hotswap", "Your attached debugger is blocking the TrinityCore "
+ "automatic script rebuild, please detach it!");
+ }
+
+ return;
+ }
+
+ // Find all source files of a changed script module and removes
+ // it from the changed source list, invoke the build afterwards.
+ bool rebuild_buildfiles;
+ auto module_name = [&]
+ {
+ auto itr = _sources_changed.begin();
+ auto name = itr->first;
+ rebuild_buildfiles = !itr->second.empty();
+
+ if (sLog->ShouldLog("scripts.hotswap", LogLevel::LOG_LEVEL_TRACE))
+ for (auto const& entry : itr->second)
+ {
+ TC_LOG_TRACE("scripts.hotswap", "Source file %s was %s.",
+ entry.first.generic_string().c_str(),
+ ((entry.second == ChangeStateRequest::CHANGE_REQUEST_ADDED) ?
+ "added" : "removed"));
+ }
+
+ _sources_changed.erase(itr);
+ return name;
+ }();
+
+ // Erase the added delete history all modules when we
+ // invoke a cmake rebuild since we add all
+ // added files of other modules to the build as well
+ if (rebuild_buildfiles)
+ {
+ for (auto& entry : _sources_changed)
+ entry.second.clear();
+ }
+
+ ASSERT(!module_name.empty(),
+ "The current module name is invalid!");
+
+ TC_LOG_INFO("scripts.hotswap", "Recompiling Module \"%s\"...",
+ module_name.c_str());
+
+ // Calculate the project name of the script module
+ auto project_name = CalculateScriptModuleProjectName(module_name);
+
+ // Find the best build directive for the module
+ auto build_directive = [&] () -> std::string
+ {
+ auto directive = sConfigMgr->GetStringDefault("HotSwap.ReCompilerBuildType", "");
+ if (!directive.empty())
+ return directive;
+
+ auto const itr = _known_modules_build_directives.find(module_name);
+ if (itr != _known_modules_build_directives.end())
+ return itr->second;
+ else // If no build directive of the module was found use the one from the game library
+ return _BUILD_DIRECTIVE;
+ }();
+
+ // Initiate the new build job
+ _build_job = BuildJob(std::move(module_name),
+ std::move(project_name), std::move(build_directive));
+
+ // Rerun CMake when we need to recreate the build files
+ if (rebuild_buildfiles
+ && sWorld->getBoolConfig(CONFIG_HOTSWAP_BUILD_FILE_RECREATION_ENABLED))
+ DoRerunCMake();
+ else
+ DoCompileCurrentProcessedModule();
+ }
+
+ void ProcessReadyBuildJob()
+ {
+ ASSERT(_build_job->IsValid(), "Invalid build job!");
+
+ // Retrieve the result
+ auto const error = _build_job->GetProcess()->GetFutureResult().get();
+
+ if (terminate_early)
+ {
+ _build_job.reset();
+ terminate_early = false;
+ return;
+ }
+
+ switch (_build_job->GetType())
+ {
+ case BuildJobType::BUILD_JOB_RERUN_CMAKE:
+ {
+ if (!error)
+ {
+ TC_LOG_INFO("scripts.hotswap", ">> Successfully updated the build files!");
+ }
+ else
+ {
+ TC_LOG_INFO("scripts.hotswap", ">> Failed to update the build files at \"%s\", "
+ "it's possible that recently added sources are not included "
+ "in your next builds, rerun CMake manually.",
+ BuiltInConfig::GetBuildDirectory().c_str());
+ }
+ // Continue with building the changes sources
+ DoCompileCurrentProcessedModule();
+ return;
+ }
+ case BuildJobType::BUILD_JOB_COMPILE:
+ {
+ if (!error) // Build was successful
+ {
+ if (sWorld->getBoolConfig(CONFIG_HOTSWAP_INSTALL_ENABLED))
+ {
+ // Continue with the installation when it's enabled
+ TC_LOG_INFO("scripts.hotswap",
+ ">> Successfully build module %s, continue with installing...",
+ _build_job->GetModuleName().c_str());
+
+ DoInstallCurrentProcessedModule();
+ return;
+ }
+
+ // Skip the installation because it's disabled in config
+ TC_LOG_INFO("scripts.hotswap",
+ ">> Successfully build module %s, skipped the installation.",
+ _build_job->GetModuleName().c_str());
+ }
+ else // Build wasn't successful
+ {
+ TC_LOG_ERROR("scripts.hotswap",
+ ">> The build of module %s failed! See the log for details.",
+ _build_job->GetModuleName().c_str());
+ }
+ break;
+ }
+ case BuildJobType::BUILD_JOB_INSTALL:
+ {
+ if (!error)
+ {
+ // Installation was successful
+ TC_LOG_INFO("scripts.hotswap", ">> Successfully installed module %s.",
+ _build_job->GetModuleName().c_str());
+ }
+ else
+ {
+ // Installation wasn't successful
+ TC_LOG_INFO("scripts.hotswap",
+ ">> The installation of module %s failed! See the log for details.",
+ _build_job->GetModuleName().c_str());
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ // Clear the current job
+ _build_job.reset();
+ }
+
+ /// Reruns CMake asynchronously over the build directory
+ void DoRerunCMake()
+ {
+ ASSERT(_build_job, "There isn't any active build job!");
+
+ TC_LOG_INFO("scripts.hotswap", "Rerunning CMake because there were sources added or removed...");
+
+ _build_job->UpdateCurrentJob(BuildJobType::BUILD_JOB_RERUN_CMAKE,
+ InvokeAsyncCMakeCommand(BuiltInConfig::GetBuildDirectory()));
+ }
+
+ /// Invokes a new build of the current active module job
+ void DoCompileCurrentProcessedModule()
+ {
+ ASSERT(_build_job, "There isn't any active build job!");
+
+ TC_LOG_INFO("scripts.hotswap", "Starting asynchronous build job for module %s...",
+ _build_job->GetModuleName().c_str());
+
+ _build_job->UpdateCurrentJob(BuildJobType::BUILD_JOB_COMPILE,
+ InvokeAsyncCMakeCommand(
+ "--build", BuiltInConfig::GetBuildDirectory(),
+ "--target", _build_job->GetProjectName(),
+ "--config", _build_job->GetBuildDirective()));
+ }
+
+ /// Invokes a new asynchronous install of the current active module job
+ void DoInstallCurrentProcessedModule()
+ {
+ ASSERT(_build_job, "There isn't any active build job!");
+
+ TC_LOG_INFO("scripts.hotswap", "Starting asynchronous install job for module %s...",
+ _build_job->GetModuleName().c_str());
+
+ _build_job->UpdateCurrentJob(BuildJobType::BUILD_JOB_INSTALL,
+ InvokeAsyncCMakeCommand(
+ "-DCOMPONENT=" + _build_job->GetProjectName(),
+ "-DBUILD_TYPE=" + _build_job->GetBuildDirective(),
+ "-P", fs::absolute("cmake_install.cmake",
+ BuiltInConfig::GetBuildDirectory()).generic_string()));
+ }
+
+ /// Sets the CMAKE_INSTALL_PREFIX variable in the CMake cache
+ /// to point to the current worldserver position,
+ /// since most users will forget this.
+ void DoCMakePrefixCorrectionIfNeeded()
+ {
+ TC_LOG_INFO("scripts.hotswap", "Correcting your CMAKE_INSTALL_PREFIX in \"%s\"...",
+ BuiltInConfig::GetBuildDirectory().c_str());
+
+ auto const cmake_cache_path = fs::absolute("CMakeCache.txt",
+ BuiltInConfig::GetBuildDirectory());
+
+ // Stop when the CMakeCache wasn't found
+ if (![&]
+ {
+ boost::system::error_code error;
+ if (!fs::exists(cmake_cache_path, error))
+ {
+ TC_LOG_ERROR("scripts.hotswap", ">> CMake cache \"%s\" doesn't exist, "
+ "set the \"BuildDirectory\" option in your worldserver.conf to point"
+ "to your build directory!",
+ cmake_cache_path.generic_string().c_str());
+
+ return false;
+ }
+ else
+ return true;
+ }())
+ return;
+
+ TC_LOG_TRACE("scripts.hotswap", "Checking CMake cache (\"%s\") "
+ "for the correct CMAKE_INSTALL_PREFIX location...",
+ cmake_cache_path.generic_string().c_str());
+
+ std::string cmake_cache_content;
+ {
+ std::ifstream in(cmake_cache_path.generic_string());
+ if (!in.is_open())
+ {
+ TC_LOG_ERROR("scripts.hotswap", ">> Failed to read the CMake cache at \"%s\"!",
+ cmake_cache_path.generic_string().c_str());
+
+ return;
+ }
+
+ std::ostringstream ss;
+ ss << in.rdbuf();
+ cmake_cache_content = ss.str();
+
+ in.close();
+ }
+
+ static std::string const prefix_key = "CMAKE_INSTALL_PREFIX:PATH=";
+
+ // Extract the value of CMAKE_INSTALL_PREFIX
+ auto begin = cmake_cache_content.find(prefix_key);
+ if (begin != std::string::npos)
+ {
+ begin += prefix_key.length();
+ auto const end = cmake_cache_content.find("\n", begin);
+ if (end != std::string::npos)
+ {
+ fs::path value = cmake_cache_content.substr(begin, end - begin);
+
+ auto current_path = fs::current_path();
+
+ #ifndef _WIN32
+ // The worldserver location is ${CMAKE_INSTALL_PREFIX}/bin
+ // on all other platforms then windows
+ current_path = current_path.remove_leaf();
+ #endif
+
+ if (value != current_path)
+ {
+ // Prevent correction of the install prefix
+ // when we are starting the core from inside the build tree
+ bool const is_in_path = [&]
+ {
+ fs::path base = BuiltInConfig::GetBuildDirectory();
+ fs::path branch = value;
+ while (!branch.empty())
+ {
+ if (base == branch)
+ return true;
+
+ branch = branch.remove_leaf();
+ }
+
+ return false;
+ }();
+
+ if (is_in_path)
+ return;
+
+ TC_LOG_INFO("scripts.hotswap", ">> Found outdated CMAKE_INSTALL_PREFIX (\"%s\"), "
+ "worldserver is currently installed at %s...",
+ value.generic_string().c_str(), current_path.generic_string().c_str());
+ }
+ else
+ {
+ TC_LOG_INFO("scripts.hotswap", ">> CMAKE_INSTALL_PREFIX is equal to the current path of execution.");
+ return;
+ }
+ }
+ }
+
+ TC_LOG_INFO("scripts.hotswap", "Invoking CMake cache correction...");
+
+ auto const error = InvokeCMakeCommand(
+ "-DCMAKE_INSTALL_PREFIX:PATH=" + fs::current_path().generic_string(),
+ BuiltInConfig::GetBuildDirectory());
+
+ if (error)
+ {
+ TC_LOG_ERROR("scripts.hotswap", ">> Failed to update the CMAKE_INSTALL_PREFIX! "
+ "This could lead to unexpected behaviour!");
+ }
+ else
+ {
+ TC_LOG_ERROR("scripts.hotswap", ">> Successfully corrected your CMAKE_INSTALL_PREFIX variable"
+ "to point at your current path of execution.");
+ }
+ }
+
+ // File watcher instance and watcher ID's
+ efsw::FileWatcher _fileWatcher;
+ efsw::WatchID _libraryWatcher;
+
+ // Unique library name counter which is used to
+ // generate unique names for every shared library version.
+ uint32 _unique_library_name_counter;
+
+ // Queue which is used for thread safe message processing
+ MPSCQueue<ScriptReloaderMessage> _messages;
+
+ // Change requests to load or unload shared libraries
+ std::unordered_set<fs::path /*path*/> _libraries_changed;
+ // The timestamp which indicates the last time a library was changed
+ uint32 _last_time_library_changed;
+
+ // Contains all running script modules
+ // The associated shared libraries are unloaded immediately
+ // on loosing ownership through RAII.
+ std::unordered_map<std::string /*module name*/,
+ std::pair<std::shared_ptr<ScriptModule>, std::unique_ptr<SourceUpdateListener>>
+ > _running_script_modules;
+ // Container which maps the path of a shared library to it's module name
+ std::unordered_map<fs::path, std::string /*module name*/> _running_script_module_names;
+ // Container which maps the module name to it's last known build directive
+ std::unordered_map<std::string /*module name*/, std::string /*build directive*/> _known_modules_build_directives;
+
+ // Modules which were changed and are queued for recompilation
+ std::unordered_map<std::string /*module*/,
+ std::unordered_map<fs::path /*path*/, ChangeStateRequest /*state*/>> _sources_changed;
+ // Tracks the time since the last module has changed to avoid burst updates
+ uint32 _last_time_sources_changed;
+
+ // Tracks the last timestamp the user was informed about a certain repeating event.
+ uint32 _last_time_user_informed;
+
+ // Represents the current build job which is in progress
+ Optional<BuildJob> _build_job;
+
+ // Is true when the build job dispatcher should stop after
+ // the current job has finished
+ bool terminate_early;
+};
+
+/// Maps efsw actions to strings
+static char const* ActionToString(efsw::Action action)
+{
+ switch (action)
+ {
+ case efsw::Action::Add:
+ return "added";
+ case efsw::Action::Delete:
+ return "deleted";
+ case efsw::Action::Moved:
+ return "moved";
+ default:
+ return "modified";
+ }
+}
+
+void LibraryUpdateListener::handleFileAction(efsw::WatchID watchid, std::string const& dir,
+ std::string const& filename, efsw::Action action, std::string oldFilename)
+{
+ // TC_LOG_TRACE("scripts.hotswap", "Library listener detected change on possible module \"%s\ (%s)".", filename.c_str(), ActionToString(action));
+
+ // Split moved actions into a delete and an add action
+ if (action == efsw::Action::Moved)
+ {
+ ASSERT(!oldFilename.empty(), "Old filename doesn't exist!");
+ handleFileAction(watchid, dir, oldFilename, efsw::Action::Delete);
+ handleFileAction(watchid, dir, filename, efsw::Action::Add);
+ return;
+ }
+
+ sScriptReloadMgr->QueueMessage([=](HotSwapScriptReloadMgr* reloader) mutable
+ {
+ auto const path = fs::absolute(
+ filename,
+ sScriptReloadMgr->GetLibraryDirectory());
+
+ if (!HasValidScriptModuleName(filename))
+ return;
+
+ switch (action)
+ {
+ case efsw::Actions::Add:
+ TC_LOG_TRACE("scripts.hotswap", ">> Loading \"%s\" (%s)...",
+ path.generic_string().c_str(), ActionToString(action));
+ reloader->QueueSharedLibraryChanged(path);
+ break;
+ case efsw::Actions::Delete:
+ TC_LOG_TRACE("scripts.hotswap", ">> Unloading \"%s\" (%s)...",
+ path.generic_string().c_str(), ActionToString(action));
+ reloader->QueueSharedLibraryChanged(path);
+ break;
+ case efsw::Actions::Modified:
+ TC_LOG_TRACE("scripts.hotswap", ">> Reloading \"%s\" (%s)...",
+ path.generic_string().c_str(), ActionToString(action));
+ reloader->QueueSharedLibraryChanged(path);
+ break;
+ default:
+ WPAbort();
+ break;
+ }
+ });
+}
+
+/// Returns true when the given path has a known C++ file extension
+static bool HasCXXSourceFileExtension(fs::path const& path)
+{
+ static std::regex const regex("^\\.(h|hpp|c|cc|cpp)$");
+ return std::regex_match(path.extension().generic_string(), regex);
+}
+
+SourceUpdateListener::SourceUpdateListener(fs::path path, std::string script_module_name)
+ : path_(std::move(path)), script_module_name_(std::move(script_module_name)),
+ watcher_id_(sScriptReloadMgr->_fileWatcher.addWatch(path_.generic_string(), this, true))
+{
+ if (watcher_id_ >= 0)
+ {
+ TC_LOG_TRACE("scripts.hotswap", ">> Attached the source recompiler to \"%s\".",
+ path_.generic_string().c_str());
+ }
+ else
+ {
+ TC_LOG_ERROR("scripts.hotswap", "Failed to initialize thesource recompiler on \"%s\".",
+ path_.generic_string().c_str());
+ }
+}
+
+SourceUpdateListener::~SourceUpdateListener()
+{
+ if (watcher_id_ >= 0)
+ {
+ sScriptReloadMgr->_fileWatcher.removeWatch(watcher_id_);
+
+ TC_LOG_TRACE("scripts.hotswap", ">> Detached the source recompiler from \"%s\".",
+ path_.generic_string().c_str());
+ }
+}
+
+void SourceUpdateListener::handleFileAction(efsw::WatchID watchid, std::string const& dir,
+ std::string const& filename, efsw::Action action, std::string oldFilename)
+{
+ // TC_LOG_TRACE("scripts.hotswap", "Source listener detected change on possible file \"%s/%s\" (%s).", dir.c_str(), filename.c_str(), ActionToString(action));
+
+ // Skip the file change notification if the recompiler is disabled
+ if (!sWorld->getBoolConfig(CONFIG_HOTSWAP_RECOMPILER_ENABLED))
+ return;
+
+ // Split moved actions into a delete and an add action
+ if (action == efsw::Action::Moved)
+ {
+ ASSERT(!oldFilename.empty(), "Old filename doesn't exist!");
+ handleFileAction(watchid, dir, oldFilename, efsw::Action::Delete);
+ handleFileAction(watchid, dir, filename, efsw::Action::Add);
+ return;
+ }
+
+ auto const path = fs::absolute(
+ filename,
+ dir);
+
+ // Check if the file is a C/C++ source file.
+ if (!path.has_extension() || !HasCXXSourceFileExtension(path))
+ return;
+
+ /// Thread safe part
+ sScriptReloadMgr->QueueMessage([=](HotSwapScriptReloadMgr* reloader)
+ {
+ TC_LOG_TRACE("scripts.hotswap", "Detected source change on module \"%s\", "
+ "queued for recompilation...", script_module_name_.c_str());
+
+ switch (action)
+ {
+ case efsw::Actions::Add:
+ TC_LOG_TRACE("scripts.hotswap", "Source file %s of module %s was added.",
+ path.generic_string().c_str(), script_module_name_.c_str());
+ reloader->QueueAddSourceFile(script_module_name_, path);
+ break;
+ case efsw::Actions::Delete:
+ TC_LOG_TRACE("scripts.hotswap", "Source file %s of module %s was deleted.",
+ path.generic_string().c_str(), script_module_name_.c_str());
+ reloader->QueueRemoveSourceFile(script_module_name_, path);
+ break;
+ case efsw::Actions::Modified:
+ TC_LOG_TRACE("scripts.hotswap", "Source file %s of module %s was modified.",
+ path.generic_string().c_str(), script_module_name_.c_str());
+ reloader->QueueModifySourceFile(script_module_name_, path);
+ break;
+ default:
+ WPAbort();
+ break;
+ }
+ });
+}
+
+// Returns the module reference of the given context
+std::shared_ptr<ModuleReference>
+ ScriptReloadMgr::AcquireModuleReferenceOfContext(std::string const& context)
+{
+ auto const itr = sScriptReloadMgr->_running_script_modules.find(context);
+ if (itr != sScriptReloadMgr->_running_script_modules.end())
+ return itr->second.first;
+ else
+ return { };
+}
+
+// Returns the full hot swap implemented ScriptReloadMgr
+ScriptReloadMgr* ScriptReloadMgr::instance()
+{
+ static HotSwapScriptReloadMgr instance;
+ return &instance;
+}
+
+#endif // #ifndef TRINITY_API_USE_DYNAMIC_LINKING
diff --git a/src/server/game/Scripting/ScriptReloadMgr.h b/src/server/game/Scripting/ScriptReloadMgr.h
new file mode 100644
index 00000000000..f9b388f8eb0
--- /dev/null
+++ b/src/server/game/Scripting/ScriptReloadMgr.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SCRIPT_RELOADER_H
+#define SCRIPT_RELOADER_H
+
+#include <memory>
+#include <string>
+#include "Define.h"
+#include <boost/filesystem/path.hpp>
+
+/// Represents a strong reference to a dynamic library which
+/// provides C++ scripts. As long as one reference to the library exists
+/// the library is kept loaded in the server, which makes it possible to lazy
+/// unload several script types on demand (like SpellScripts), and to
+/// provide multiple versions of the same script to the script factories.
+///
+/// Acquire a new reference through using:
+/// `ScriptReloadMgr::AcquireModuleReferenceOfContext`
+class ModuleReference
+{
+public:
+ virtual ~ModuleReference() { }
+
+ /// Returns the git revision hash of the referenced script module
+ virtual char const* GetScriptModuleRevisionHash() const = 0;
+ /// Returns the name of the referenced script module
+ virtual char const* GetScriptModule() const = 0;
+ /// Returns the path to the script module
+ virtual boost::filesystem::path const& GetModulePath() const = 0;
+};
+
+/// Provides the whole physical dynamic library unloading capability.
+/// Loads, Reloads and Unloads dynamic libraries on changes and
+/// informs the ScriptMgr about changes which were made.
+/// The ScriptReloadMgr is also responsible for watching the source directory
+/// and to invoke a build on changes.
+class TC_GAME_API ScriptReloadMgr
+{
+protected:
+ ScriptReloadMgr() { }
+
+public:
+ virtual ~ScriptReloadMgr() { }
+
+ /// Initializes the ScriptReloadMgr
+ virtual void Initialize() { }
+
+ /// Needs to be called periodically to check for updates on script modules.
+ /// Expects to be invoked in a thread safe way which means it's required that
+ /// the current thread is the only one which accesses the world data.
+ virtual void Update() { }
+
+ /// Unloads the ScriptReloadMgr
+ virtual void Unload() { }
+
+ /// Returns an owning reference to the current module of the given context
+ static std::shared_ptr<ModuleReference> AcquireModuleReferenceOfContext(
+ std::string const& context);
+
+ /// Returns the unique ScriptReloadMgr singleton instance
+ static ScriptReloadMgr* instance();
+};
+
+#define sScriptReloadMgr ScriptReloadMgr::instance()
+
+#endif // SCRIPT_RELOADER_H
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 207908c6d51..5585dc8762b 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -1325,7 +1325,7 @@ void AuraEffect::HandleModInvisibility(AuraApplication const* aurApp, uint8 mode
{
// apply glow vision
if (target->GetTypeId() == TYPEID_PLAYER)
- target->SetByteFlag(PLAYER_FIELD_BYTES2, 3, PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
+ target->SetByteFlag(PLAYER_FIELD_BYTES2, PLAYER_FIELD_BYTES_2_OFFSET_AURA_VISION, PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
target->m_invisibility.AddFlag(type);
target->m_invisibility.AddValue(type, GetAmount());
@@ -1337,7 +1337,7 @@ void AuraEffect::HandleModInvisibility(AuraApplication const* aurApp, uint8 mode
// if not have different invisibility auras.
// remove glow vision
if (target->GetTypeId() == TYPEID_PLAYER)
- target->RemoveByteFlag(PLAYER_FIELD_BYTES2, 3, PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
+ target->RemoveByteFlag(PLAYER_FIELD_BYTES2, PLAYER_FIELD_BYTES_2_OFFSET_AURA_VISION, PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
target->m_invisibility.DelFlag(type);
}
@@ -1409,7 +1409,7 @@ void AuraEffect::HandleModStealth(AuraApplication const* aurApp, uint8 mode, boo
target->SetStandFlags(UNIT_STAND_FLAGS_CREEP);
if (target->GetTypeId() == TYPEID_PLAYER)
- target->SetByteFlag(PLAYER_FIELD_BYTES2, 3, PLAYER_FIELD_BYTE2_STEALTH);
+ target->SetByteFlag(PLAYER_FIELD_BYTES2, PLAYER_FIELD_BYTES_2_OFFSET_AURA_VISION, PLAYER_FIELD_BYTE2_STEALTH);
}
else
{
@@ -1421,7 +1421,7 @@ void AuraEffect::HandleModStealth(AuraApplication const* aurApp, uint8 mode, boo
target->RemoveStandFlags(UNIT_STAND_FLAGS_CREEP);
if (target->GetTypeId() == TYPEID_PLAYER)
- target->RemoveByteFlag(PLAYER_FIELD_BYTES2, 3, PLAYER_FIELD_BYTE2_STEALTH);
+ target->RemoveByteFlag(PLAYER_FIELD_BYTES2, PLAYER_FIELD_BYTES_2_OFFSET_AURA_VISION, PLAYER_FIELD_BYTE2_STEALTH);
}
}
@@ -2400,7 +2400,7 @@ void AuraEffect::HandleAuraTrackStealthed(AuraApplication const* aurApp, uint8 m
if (target->HasAuraType(GetAuraType()))
return;
}
- target->ApplyModFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTE_TRACK_STEALTHED, apply);
+ target->ApplyModByteFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_FLAGS, PLAYER_FIELD_BYTE_TRACK_STEALTHED, apply);
}
void AuraEffect::HandleAuraModStalked(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -4808,7 +4808,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
uint32 spellId = 24659;
if (apply && caster)
{
- SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(spellId);
+ SpellInfo const* spell = sSpellMgr->AssertSpellInfo(spellId);
for (uint32 i = 0; i < spell->StackAmount; ++i)
caster->CastSpell(target, spell->Id, true, NULL, NULL, GetCasterGUID());
@@ -4823,7 +4823,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
uint32 spellId = 24662;
if (apply && caster)
{
- SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(spellId);
+ SpellInfo const* spell = sSpellMgr->AssertSpellInfo(spellId);
for (uint32 i = 0; i < spell->StackAmount; ++i)
caster->CastSpell(target, spell->Id, true, NULL, NULL, GetCasterGUID());
break;
@@ -5248,7 +5248,7 @@ void AuraEffect::HandleAuraOverrideSpells(AuraApplication const* aurApp, uint8 m
if (apply)
{
- target->SetUInt16Value(PLAYER_FIELD_BYTES2, 0, overrideId);
+ target->SetUInt16Value(PLAYER_FIELD_BYTES2, PLAYER_BYTES_2_OVERRIDE_SPELLS_UINT16_OFFSET, overrideId);
if (OverrideSpellDataEntry const* overrideSpells = sOverrideSpellDataStore.LookupEntry(overrideId))
for (uint8 i = 0; i < MAX_OVERRIDE_SPELL; ++i)
if (uint32 spellId = overrideSpells->spellId[i])
@@ -5256,7 +5256,7 @@ void AuraEffect::HandleAuraOverrideSpells(AuraApplication const* aurApp, uint8 m
}
else
{
- target->SetUInt16Value(PLAYER_FIELD_BYTES2, 0, 0);
+ target->SetUInt16Value(PLAYER_FIELD_BYTES2, PLAYER_BYTES_2_OVERRIDE_SPELLS_UINT16_OFFSET, 0);
if (OverrideSpellDataEntry const* overrideSpells = sOverrideSpellDataStore.LookupEntry(overrideId))
for (uint8 i = 0; i < MAX_OVERRIDE_SPELL; ++i)
if (uint32 spellId = overrideSpells->spellId[i])
@@ -5302,9 +5302,9 @@ void AuraEffect::HandlePreventResurrection(AuraApplication const* aurApp, uint8
return;
if (apply)
- aurApp->GetTarget()->RemoveByteFlag(PLAYER_FIELD_BYTES, 0, PLAYER_FIELD_BYTE_RELEASE_TIMER);
+ aurApp->GetTarget()->RemoveByteFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_FLAGS, PLAYER_FIELD_BYTE_RELEASE_TIMER);
else if (!aurApp->GetTarget()->GetBaseMap()->Instanceable())
- aurApp->GetTarget()->SetByteFlag(PLAYER_FIELD_BYTES, 0, PLAYER_FIELD_BYTE_RELEASE_TIMER);
+ aurApp->GetTarget()->SetByteFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_FLAGS, PLAYER_FIELD_BYTE_RELEASE_TIMER);
}
void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const
@@ -5974,14 +5974,14 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
caster->CalcAbsorbResist(target, GetSpellInfo()->GetSchoolMask(), DOT, damage, &absorb, &resist, m_spellInfo);
- if (target->GetHealth() < damage)
- damage = uint32(target->GetHealth());
-
TC_LOG_DEBUG("spells.periodic", "PeriodicTick: %s health leech of %s for %u dmg inflicted by %u abs is %u",
GetCasterGUID().ToString().c_str(), target->GetGUID().ToString().c_str(), damage, GetId(), absorb);
caster->SendSpellNonMeleeDamageLog(target, GetId(), damage, GetSpellInfo()->GetSchoolMask(), absorb, resist, false, 0, crit);
+ if (target->GetHealth() < damage)
+ damage = uint32(target->GetHealth());
+
// Set trigger flag
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC;
uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index b2fb2766fb0..fff69ae48df 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -4831,6 +4831,10 @@ SpellCastResult Spell::CheckCast(bool strict)
m_customError = SpellCustomErrors(condInfo.mLastFailedCondition->ErrorTextId);
return SpellCastResult(condInfo.mLastFailedCondition->ErrorType);
}
+
+ if (_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR)
+ return SPELL_FAILED_DONT_REPORT;
+
if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
return SPELL_FAILED_CASTER_AURASTATE;
return SPELL_FAILED_BAD_TARGETS;
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 2a9db6f0449..3f0ff9a0f19 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -1830,7 +1830,7 @@ void Spell::EffectEnergize(SpellEffIndex effIndex)
sSpellMgr->GetSetOfSpellsInSpellGroup(SPELL_GROUP_ELIXIR_BATTLE, avalibleElixirs);
for (std::set<uint32>::iterator itr = avalibleElixirs.begin(); itr != avalibleElixirs.end();)
{
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(*itr);
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(*itr);
if (spellInfo->SpellLevel < m_spellInfo->SpellLevel || spellInfo->SpellLevel > unitTarget->getLevel())
avalibleElixirs.erase(itr++);
else if (sSpellMgr->IsSpellMemberOfSpellGroup(*itr, SPELL_GROUP_ELIXIR_SHATTRATH))
@@ -2110,8 +2110,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex)
else if (player->IsBankPos(pos))
{
ItemPosCountVec dest;
- uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
- if (msg == EQUIP_ERR_OK)
+ if (player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true) == EQUIP_ERR_OK)
{
player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
@@ -2133,7 +2132,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex)
player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
- uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
+ InventoryResult msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
{
diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp
index adf5fc47c77..4f74197fed2 100644
--- a/src/server/game/Spells/SpellHistory.cpp
+++ b/src/server/game/Spells/SpellHistory.cpp
@@ -373,7 +373,7 @@ void SpellHistory::SendCooldownEvent(SpellInfo const* spellInfo, uint32 itemId /
player->SendDirectMessage(&data);
if (startCooldown)
- StartCooldown(sSpellMgr->EnsureSpellInfo(categoryItr->second->SpellId), itemId, spell);
+ StartCooldown(sSpellMgr->AssertSpellInfo(categoryItr->second->SpellId), itemId, spell);
}
WorldPacket data(SMSG_COOLDOWN_EVENT, 4 + 8);
@@ -483,7 +483,7 @@ bool SpellHistory::HasCooldown(SpellInfo const* spellInfo, uint32 itemId /*= 0*/
bool SpellHistory::HasCooldown(uint32 spellId, uint32 itemId /*= 0*/, bool ignoreCategoryCooldown /*= false*/) const
{
- return HasCooldown(sSpellMgr->EnsureSpellInfo(spellId), itemId, ignoreCategoryCooldown);
+ return HasCooldown(sSpellMgr->AssertSpellInfo(spellId), itemId, ignoreCategoryCooldown);
}
uint32 SpellHistory::GetRemainingCooldown(SpellInfo const* spellInfo) const
@@ -542,7 +542,7 @@ void SpellHistory::LockSpellSchool(SpellSchoolMask schoolMask, uint32 lockoutTim
WorldPacket spellCooldowns;
for (uint32 spellId : knownSpells)
{
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(spellId);
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(spellId);
if (spellInfo->IsCooldownStartedOnEvent())
continue;
@@ -688,7 +688,7 @@ void SpellHistory::RestoreCooldownStateAfterDuel()
// add all profession CDs created while in duel (if any)
for (auto itr = _spellCooldowns.begin(); itr != _spellCooldowns.end(); ++itr)
{
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first);
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first);
if (spellInfo->RecoveryTime > 10 * MINUTE * IN_MILLISECONDS ||
spellInfo->CategoryRecoveryTime > 10 * MINUTE * IN_MILLISECONDS)
diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h
index 269a3a90e9d..fea7513b092 100644
--- a/src/server/game/Spells/SpellMgr.h
+++ b/src/server/game/Spells/SpellMgr.h
@@ -692,7 +692,7 @@ class TC_GAME_API SpellMgr
// SpellInfo object management
SpellInfo const* GetSpellInfo(uint32 spellId) const { return spellId < GetSpellInfoStoreSize() ? mSpellInfoMap[spellId] : NULL; }
// Use this only with 100% valid spellIds
- SpellInfo const* EnsureSpellInfo(uint32 spellId) const
+ SpellInfo const* AssertSpellInfo(uint32 spellId) const
{
ASSERT(spellId < GetSpellInfoStoreSize());
SpellInfo const* spellInfo = mSpellInfoMap[spellId];
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 6876f8fa7ef..e2598386466 100644
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -16,6 +16,7 @@
*/
#include "Spell.h"
+#include "ScriptMgr.h"
#include "SpellAuras.h"
#include "SpellScript.h"
#include "SpellMgr.h"
@@ -50,6 +51,12 @@ void _SpellScript::_Init(std::string const* scriptname, uint32 spellId)
m_currentScriptState = SPELL_SCRIPT_STATE_NONE;
m_scriptName = scriptname;
m_scriptSpellId = spellId;
+
+#ifdef TRINITY_API_USE_DYNAMIC_LINKING
+ // Acquire a strong reference to the binary code
+ // to keep it loaded until all spells are destroyed.
+ m_moduleReference = sScriptMgr->AcquireModuleReferenceOfScriptName(*scriptname);
+#endif // #ifndef TRINITY_API_USE_DYNAMIC_LINKING
}
std::string const* _SpellScript::_GetScriptName() const
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index 1d4efd8073d..539bc54cc94 100644
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -22,6 +22,7 @@
#include "SharedDefines.h"
#include "SpellAuraDefines.h"
#include "Spell.h"
+#include "ScriptReloadMgr.h"
#include <stack>
class Unit;
@@ -105,6 +106,16 @@ class TC_GAME_API _SpellScript
uint8 m_currentScriptState;
std::string const* m_scriptName;
uint32 m_scriptSpellId;
+
+ private:
+
+#ifdef TRINITY_API_USE_DYNAMIC_LINKING
+
+ // Strong reference to keep the binary code loaded
+ std::shared_ptr<ModuleReference> m_moduleReference;
+
+#endif // #ifndef TRINITY_API_USE_DYNAMIC_LINKING
+
public:
//
// SpellScript/AuraScript interface base
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 6380aece941..4b64ef0bbd8 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -54,6 +54,7 @@
#include "PoolMgr.h"
#include "GitRevision.h"
#include "ScriptMgr.h"
+#include "ScriptReloadMgr.h"
#include "SkillDiscovery.h"
#include "SkillExtraItems.h"
#include "SmartAI.h"
@@ -1319,6 +1320,14 @@ void World::LoadConfigSettings(bool reload)
m_bool_configs[CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA] = sConfigMgr->GetBoolDefault("Calculate.Creature.Zone.Area.Data", false);
m_bool_configs[CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA] = sConfigMgr->GetBoolDefault("Calculate.Gameoject.Zone.Area.Data", false);
+ // HotSwap
+ m_bool_configs[CONFIG_HOTSWAP_ENABLED] = sConfigMgr->GetBoolDefault("HotSwap.Enabled", true);
+ m_bool_configs[CONFIG_HOTSWAP_RECOMPILER_ENABLED] = sConfigMgr->GetBoolDefault("HotSwap.EnableReCompiler", true);
+ m_bool_configs[CONFIG_HOTSWAP_EARLY_TERMINATION_ENABLED] = sConfigMgr->GetBoolDefault("HotSwap.EnableEarlyTermination", true);
+ m_bool_configs[CONFIG_HOTSWAP_BUILD_FILE_RECREATION_ENABLED] = sConfigMgr->GetBoolDefault("HotSwap.EnableBuildFileRecreation", true);
+ m_bool_configs[CONFIG_HOTSWAP_INSTALL_ENABLED] = sConfigMgr->GetBoolDefault("HotSwap.EnableInstall", true);
+ m_bool_configs[CONFIG_HOTSWAP_PREFIX_CORRECTION_ENABLED] = sConfigMgr->GetBoolDefault("HotSwap.EnablePrefixCorrection", true);
+
// call ScriptMgr if we're reloading the configuration
if (reload)
sScriptMgr->OnConfigLoad(reload);
@@ -1826,6 +1835,8 @@ void World::SetInitialWorldSettings()
m_timers[WUPDATE_PINGDB].SetInterval(getIntConfig(CONFIG_DB_PING_INTERVAL)*MINUTE*IN_MILLISECONDS); // Mysql ping time in minutes
+ m_timers[WUPDATE_CHECK_FILECHANGES].SetInterval(500);
+
//to set mailtimer to return mails every day between 4 and 5 am
//mailtimer is increased when updating auctions
//one second is 1000 -(tested on win system)
@@ -2109,6 +2120,13 @@ void World::Update(uint32 diff)
m_timers[WUPDATE_AHBOT].Reset();
}
+ /// <li> Handle file changes
+ if (m_timers[WUPDATE_CHECK_FILECHANGES].Passed())
+ {
+ sScriptReloadMgr->Update();
+ m_timers[WUPDATE_CHECK_FILECHANGES].Reset();
+ }
+
/// <li> Handle session updates when the timer has passed
ResetTimeDiffRecord();
UpdateSessions(diff);
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index a59d9ef882a..abc0ea452ac 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -81,6 +81,7 @@ enum WorldTimers
WUPDATE_DELETECHARS,
WUPDATE_AHBOT,
WUPDATE_PINGDB,
+ WUPDATE_CHECK_FILECHANGES,
WUPDATE_COUNT
};
@@ -167,6 +168,12 @@ enum WorldBoolConfigs
CONFIG_RESET_DUEL_HEALTH_MANA,
CONFIG_BASEMAP_LOAD_GRIDS,
CONFIG_INSTANCEMAP_LOAD_GRIDS,
+ CONFIG_HOTSWAP_ENABLED,
+ CONFIG_HOTSWAP_RECOMPILER_ENABLED,
+ CONFIG_HOTSWAP_EARLY_TERMINATION_ENABLED,
+ CONFIG_HOTSWAP_BUILD_FILE_RECREATION_ENABLED,
+ CONFIG_HOTSWAP_INSTALL_ENABLED,
+ CONFIG_HOTSWAP_PREFIX_CORRECTION_ENABLED,
BOOL_CONFIG_VALUE_COUNT
};
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
index d12c44c447c..31ba073e77d 100644
--- a/src/server/scripts/CMakeLists.txt
+++ b/src/server/scripts/CMakeLists.txt
@@ -8,69 +8,232 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# Enable precompiled headers when using the GCC compiler.
-
-message(STATUS "SCRIPT PREPARATIONS")
-
-macro(PrepareScripts name out)
- file(GLOB_RECURSE found
- ${name}/*.h
- ${name}/*.cpp
- )
- list(APPEND ${out} ${found})
- message(STATUS " -> Prepared: ${name}")
-endmacro(PrepareScripts)
-
-PrepareScripts(Spells PRIVATE_SOURCES)
-PrepareScripts(Commands PRIVATE_SOURCES)
-
-if(SCRIPTS)
- PrepareScripts(Custom PRIVATE_SOURCES)
- PrepareScripts(World PRIVATE_SOURCES)
- PrepareScripts(OutdoorPvP PRIVATE_SOURCES)
- PrepareScripts(EasternKingdoms PRIVATE_SOURCES)
- PrepareScripts(Kalimdor PRIVATE_SOURCES)
- PrepareScripts(Outland PRIVATE_SOURCES)
- PrepareScripts(Northrend PRIVATE_SOURCES)
- PrepareScripts(Events PRIVATE_SOURCES)
- PrepareScripts(Pet PRIVATE_SOURCES)
+message("")
+
+# Make the script module list available in the current scope
+GetScriptModuleList(SCRIPT_MODULE_LIST)
+
+# Make the native install offset available in this scope
+GetInstallOffset(INSTALL_OFFSET)
+
+# Sets the SCRIPTS_${SCRIPT_MODULE} variables
+# when using predefined templates for script building
+# like dynamic, static, minimal-static...
+# Sets SCRIPTS_DEFAULT_LINKAGE
+if (SCRIPTS MATCHES "dynamic")
+ set(SCRIPTS_DEFAULT_LINKAGE "dynamic")
+elseif(SCRIPTS MATCHES "static")
+ set(SCRIPTS_DEFAULT_LINKAGE "static")
+else()
+ set(SCRIPTS_DEFAULT_LINKAGE "disabled")
+endif()
+# Sets SCRIPTS_USE_WHITELIST
+# Sets SCRIPTS_WHITELIST
+if (SCRIPTS MATCHES "minimal")
+ set(SCRIPTS_USE_WHITELIST ON)
+ # Whitelist which is used when minimal is selected
+ list(APPEND SCRIPTS_WHITELIST Commands Spells)
endif()
-message(STATUS "SCRIPT PREPARATION COMPLETE")
-message("")
+# Set the SCRIPTS_${SCRIPT_MODULE} variables from the
+# variables set above
+foreach(SCRIPT_MODULE ${SCRIPT_MODULE_LIST})
+ ScriptModuleNameToVariable(${SCRIPT_MODULE} SCRIPT_MODULE_VARIABLE)
+ if (${SCRIPT_MODULE_VARIABLE} STREQUAL "default")
+ if(SCRIPTS_USE_WHITELIST)
+ list(FIND SCRIPTS_WHITELIST "${SCRIPT_MODULE}" INDEX)
+ if (${INDEX} GREATER -1)
+ set(${SCRIPT_MODULE_VARIABLE} ${SCRIPTS_DEFAULT_LINKAGE})
+ else()
+ set(${SCRIPT_MODULE_VARIABLE} "disabled")
+ endif()
+ else()
+ set(${SCRIPT_MODULE_VARIABLE} ${SCRIPTS_DEFAULT_LINKAGE})
+ endif()
+ endif()
+ # Build the Graph values
+ if (${SCRIPT_MODULE_VARIABLE} MATCHES "dynamic")
+ GetProjectNameOfScriptModule(${SCRIPT_MODULE} SCRIPT_MODULE_PROJECT_NAME)
+ GetNativeSharedLibraryName(${SCRIPT_MODULE_PROJECT_NAME} SCRIPT_PROJECT_LIBRARY)
+ list(APPEND GRAPH_KEYS ${SCRIPT_MODULE_PROJECT_NAME})
+ set(GRAPH_VALUE_DISPLAY_${SCRIPT_MODULE_PROJECT_NAME} ${SCRIPT_PROJECT_LIBRARY})
+ list(APPEND GRAPH_VALUE_CONTAINS_MODULES_${SCRIPT_MODULE_PROJECT_NAME} ${SCRIPT_MODULE})
+ elseif(${SCRIPT_MODULE_VARIABLE} MATCHES "static")
+ list(APPEND GRAPH_KEYS worldserver)
+ set(GRAPH_VALUE_DISPLAY_worldserver worldserver)
+ list(APPEND GRAPH_VALUE_CONTAINS_MODULES_worldserver ${SCRIPT_MODULE})
+ else()
+ list(APPEND GRAPH_KEYS disabled)
+ set(GRAPH_VALUE_DISPLAY_disabled disabled)
+ list(APPEND GRAPH_VALUE_CONTAINS_MODULES_disabled ${SCRIPT_MODULE})
+ endif()
+endforeach()
-list(APPEND PRIVATE_SOURCES
- ${CMAKE_CURRENT_SOURCE_DIR}/ScriptLoader.h
- ${CMAKE_CURRENT_SOURCE_DIR}/ScriptLoader.cpp)
+list(SORT GRAPH_KEYS)
+list(REMOVE_DUPLICATES GRAPH_KEYS)
+# Display the script graph
+message("* Script configuration (${SCRIPTS}):
+ |")
+
+foreach(GRAPH_KEY ${GRAPH_KEYS})
+ if (NOT GRAPH_KEY STREQUAL "disabled")
+ message(" +- ${GRAPH_VALUE_DISPLAY_${GRAPH_KEY}}")
+ else()
+ message(" | ${GRAPH_VALUE_DISPLAY_${GRAPH_KEY}}")
+ endif()
+ foreach(GRAPH_PROJECT_ENTRY ${GRAPH_VALUE_CONTAINS_MODULES_${GRAPH_KEY}})
+ message(" | +- ${GRAPH_PROJECT_ENTRY}")
+ endforeach()
+ message(" |")
+endforeach()
+
+# Base sources which are used by every script project
if (USE_SCRIPTPCH)
- set(PRIVATE_PCH_HEADER PrecompiledHeaders/ScriptPCH.h)
- set(PRIVATE_PCH_SOURCE PrecompiledHeaders/ScriptPCH.cpp)
+ set(PRIVATE_PCH_HEADER ScriptPCH.h)
+ set(PRIVATE_PCH_SOURCE ScriptPCH.cpp)
endif ()
GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
+# Configures the scriptloader with the given name and stores the output in the LOADER_OUT variable.
+# It is possible to expose multiple subdirectories from the same scriptloader through passing
+# it to the variable arguments
+function(ConfigureScriptLoader SCRIPTLOADER_NAME LOADER_OUT IS_DYNAMIC_SCRIPTLOADER)
+ # Deduces following variables which are referenced by thge template:
+ # TRINITY_IS_DYNAMIC_SCRIPTLOADER
+ # TRINITY_SCRIPTS_FORWARD_DECL
+ # TRINITY_SCRIPTS_INVOKE
+ # TRINITY_CURRENT_SCRIPT_PROJECT
+
+ # To generate export macros
+ set(TRINITY_IS_DYNAMIC_SCRIPTLOADER ${IS_DYNAMIC_SCRIPTLOADER})
+ # To generate forward declarations of the loading functions
+ unset(TRINITY_SCRIPTS_FORWARD_DECL)
+ unset(TRINITY_SCRIPTS_INVOKE)
+ # The current script project which is built in
+ set(TRINITY_CURRENT_SCRIPT_PROJECT ${SCRIPTLOADER_NAME})
+ foreach(LOCALE_SCRIPT_MODULE ${ARGN})
+ # Determine the loader function ("Add##${NameOfDirectory}##Scripts()")
+ set(LOADER_FUNCTION
+ "Add${LOCALE_SCRIPT_MODULE}Scripts()")
+ # Generate the funciton call and the forward declarations
+ set(TRINITY_SCRIPTS_FORWARD_DECL
+ "${TRINITY_SCRIPTS_FORWARD_DECL}void ${LOADER_FUNCTION};\n")
+ set(TRINITY_SCRIPTS_INVOKE
+ "${TRINITY_SCRIPTS_INVOKE} ${LOADER_FUNCTION};\n")
+ endforeach()
+ set(GENERATED_LOADER ${CMAKE_CURRENT_BINARY_DIR}/gen_scriptloader/${SCRIPTLOADER_NAME}/ScriptLoader.cpp)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ScriptLoader.cpp.in.cmake ${GENERATED_LOADER})
+ set(${LOADER_OUT} ${GENERATED_LOADER} PARENT_SCOPE)
+endfunction()
+
+# Generates the actual script projects
+# Fills the STATIC_SCRIPT_MODULES and DYNAMIC_SCRIPT_MODULE_PROJECTS variables
+# which contain the names which scripts are linked statically/dynamically and
+# adds the sources of the static modules to the PRIVATE_SOURCES variable.
+foreach(SCRIPT_MODULE ${SCRIPT_MODULE_LIST})
+ GetPathToScriptModule(${SCRIPT_MODULE} SCRIPT_MODULE_PATH)
+ ScriptModuleNameToVariable(${SCRIPT_MODULE} SCRIPT_MODULE_VARIABLE)
+
+ if ((${SCRIPT_MODULE_VARIABLE} STREQUAL "disabled") OR
+ (${SCRIPT_MODULE_VARIABLE} STREQUAL "static"))
+ # Uninstall disabled modules
+ GetProjectNameOfScriptModule(${SCRIPT_MODULE} SCRIPT_MODULE_PROJECT_NAME)
+ GetNativeSharedLibraryName(${SCRIPT_MODULE_PROJECT_NAME} SCRIPT_MODULE_OUTPUT_NAME)
+ list(APPEND DISABLED_SCRIPT_MODULE_PROJECTS ${INSTALL_OFFSET}/${SCRIPT_MODULE_OUTPUT_NAME})
+ if (${SCRIPT_MODULE_VARIABLE} STREQUAL "static")
+ # Add the module name to STATIC_SCRIPT_MODULES
+ list(APPEND STATIC_SCRIPT_MODULES ${SCRIPT_MODULE})
+ # Add the module content to the whole static module
+ CollectSourceFiles(${SCRIPT_MODULE_PATH} PRIVATE_SOURCES)
+ endif()
+ elseif(${SCRIPT_MODULE_VARIABLE} STREQUAL "dynamic")
+ # Generate an own dynamic module which is loadable on runtime
+ # Add the module content to the whole static module
+ unset(SCRIPT_MODULE_PRIVATE_SOURCES)
+ CollectSourceFiles(${SCRIPT_MODULE_PATH} SCRIPT_MODULE_PRIVATE_SOURCES)
+ # Configure the scriptloader
+ ConfigureScriptLoader(${SCRIPT_MODULE} SCRIPT_MODULE_PRIVATE_SCRIPTLOADER ON ${SCRIPT_MODULE})
+ GetProjectNameOfScriptModule(${SCRIPT_MODULE} SCRIPT_MODULE_PROJECT_NAME)
+ # Add the module name to DYNAMIC_SCRIPT_MODULES
+ list(APPEND DYNAMIC_SCRIPT_MODULE_PROJECTS ${SCRIPT_MODULE_PROJECT_NAME})
+ # Create the script module project
+ add_library(${SCRIPT_MODULE_PROJECT_NAME} SHARED
+ ${PRIVATE_PCH_SOURCE}
+ ${SCRIPT_MODULE_PRIVATE_SOURCES}
+ ${SCRIPT_MODULE_PRIVATE_SCRIPTLOADER})
+ target_link_libraries(${SCRIPT_MODULE_PROJECT_NAME}
+ PUBLIC
+ game)
+ set_target_properties(${SCRIPT_MODULE_PROJECT_NAME}
+ PROPERTIES
+ FOLDER
+ "scripts")
+
+ if(UNIX)
+ install(TARGETS ${SCRIPT_MODULE_PROJECT_NAME}
+ DESTINATION ${INSTALL_OFFSET}
+ COMPONENT ${SCRIPT_MODULE_PROJECT_NAME})
+ elseif(WIN32)
+ install(TARGETS ${SCRIPT_MODULE_PROJECT_NAME}
+ RUNTIME DESTINATION ${INSTALL_OFFSET}
+ COMPONENT ${SCRIPT_MODULE_PROJECT_NAME})
+ if(MSVC)
+ # Place the script modules in the script subdirectory
+ set_target_properties(${SCRIPT_MODULE_PROJECT_NAME} PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/bin/Debug/scripts
+ RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/bin/Release/scripts
+ RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR}/bin/RelWithDebInfo/scripts
+ RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_BINARY_DIR}/bin/MinSizeRel/scripts)
+ endif()
+ endif()
+ else()
+ message(FATAL_ERROR "Unknown value \"${${SCRIPT_MODULE_VARIABLE}}\"!")
+ endif()
+endforeach()
+
+# Add the dynamic script modules to the worldserver as dependency
+set(WORLDSERVER_DYNAMIC_SCRIPT_MODULES_DEPENDENCIES ${DYNAMIC_SCRIPT_MODULE_PROJECTS} PARENT_SCOPE)
+
+ConfigureScriptLoader("static" SCRIPT_MODULE_PRIVATE_SCRIPTLOADER OFF ${STATIC_SCRIPT_MODULES})
+
add_library(scripts STATIC
- ${PRIVATE_SOURCES}
+ ScriptLoader.h
${PRIVATE_PCH_SOURCE}
-)
+ ${SCRIPT_MODULE_PRIVATE_SCRIPTLOADER}
+ ${PRIVATE_SOURCES})
-target_include_directories(scripts
+target_link_libraries(scripts
PUBLIC
- ${CMAKE_CURRENT_SOURCE_DIR}
- PRIVATE
- ${CMAKE_CURRENT_BINARY_DIR})
+ game-interface)
-target_link_libraries(scripts
+target_include_directories(scripts
PUBLIC
- game)
+ ${CMAKE_CURRENT_SOURCE_DIR})
set_target_properties(scripts
- PROPERTIES
- FOLDER
- "server")
+ PROPERTIES
+ FOLDER
+ "scripts")
# Generate precompiled header
if (USE_SCRIPTPCH)
- add_cxx_pch(scripts ${PRIVATE_PCH_HEADER} ${PRIVATE_PCH_SOURCE})
+ list(APPEND ALL_SCRIPT_PROJECTS scripts ${DYNAMIC_SCRIPT_MODULE_PROJECTS})
+ add_cxx_pch("${ALL_SCRIPT_PROJECTS}" ${PRIVATE_PCH_HEADER} ${PRIVATE_PCH_SOURCE})
+endif()
+
+# Remove all shared libraries in the installl directory which
+# are contained in the static library already.
+if (DISABLED_SCRIPT_MODULE_PROJECTS)
+ install(CODE "
+ foreach(SCRIPT_TO_UNINSTALL ${DISABLED_SCRIPT_MODULE_PROJECTS})
+ if (EXISTS \"\${SCRIPT_TO_UNINSTALL}\")
+ message(STATUS \"Uninstalling: \${SCRIPT_TO_UNINSTALL}\")
+ file(REMOVE \"\${SCRIPT_TO_UNINSTALL}\")
+ endif()
+ endforeach()
+ ")
endif()
+
+message("")
diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp
index 6ffb92d9684..4bce2d168a9 100644
--- a/src/server/scripts/Commands/cs_account.cpp
+++ b/src/server/scripts/Commands/cs_account.cpp
@@ -121,8 +121,14 @@ public:
if (!accountName || !password)
return false;
- AccountOpResult result = sAccountMgr->CreateAccount(std::string(accountName), std::string(password), email);
- switch (result)
+ if (strchr(accountName, '@'))
+ {
+ handler->PSendSysMessage(LANG_ACCOUNT_USE_BNET_COMMANDS);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ switch (sAccountMgr->CreateAccount(std::string(accountName), std::string(password), email))
{
case AccountOpResult::AOR_OK:
handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName);
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index 01a048c8795..1d8094885d4 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -124,6 +124,23 @@ public:
return false;
}
+ // Dump camera locations
+ if (CinematicSequencesEntry const* cineSeq = sCinematicSequencesStore.LookupEntry(id))
+ {
+ std::unordered_map<uint32, FlyByCameraCollection>::const_iterator itr = sFlyByCameraStore.find(cineSeq->cinematicCamera);
+ if (itr != sFlyByCameraStore.end())
+ {
+ handler->PSendSysMessage("Waypoints for sequence %u, camera %u", id, cineSeq->cinematicCamera);
+ uint32 count = 1 ;
+ for (FlyByCamera cam : itr->second)
+ {
+ handler->PSendSysMessage("%02u - %7ums [%f, %f, %f] Facing %f (%f degrees)", count, cam.timeStamp, cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w, cam.locations.w * (180 / M_PI));
+ count++;
+ }
+ handler->PSendSysMessage("%u waypoints dumped", itr->second.size());
+ }
+ }
+
handler->GetSession()->GetPlayer()->SendCinematicStart(id);
return true;
}
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp
index 3a062b21c3e..861b45efa95 100644
--- a/src/server/scripts/Commands/cs_modify.cpp
+++ b/src/server/scripts/Commands/cs_modify.cpp
@@ -1339,8 +1339,8 @@ public:
}
// Set gender
- target->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
- target->SetByteValue(PLAYER_BYTES_3, 0, gender);
+ target->SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, gender);
+ target->SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER, gender);
// Change display ID
target->InitDisplayIds();
diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp
index 56b0dbf43d0..eb28a8adae4 100644
--- a/src/server/scripts/Commands/cs_reload.cpp
+++ b/src/server/scripts/Commands/cs_reload.cpp
@@ -251,7 +251,7 @@ public:
static bool HandleReloadAllScriptsCommand(ChatHandler* handler, const char* /*args*/)
{
- if (sScriptMgr->IsScriptScheduled())
+ if (sMapMgr->IsScriptScheduled())
{
handler->PSendSysMessage("DB scripts used currently, please attempt reload later.");
handler->SetSentErrorMessage(true);
@@ -393,7 +393,7 @@ public:
static bool HandleReloadCommandCommand(ChatHandler* handler, const char* /*args*/)
{
- handler->SetLoadCommandTable(true);
+ ChatHandler::invalidateCommandTable();
handler->SendGlobalGMSysMessage("DB table `command` will be reloaded at next chat command use.");
return true;
}
@@ -893,7 +893,7 @@ public:
static bool HandleReloadEventScriptsCommand(ChatHandler* handler, const char* args)
{
- if (sScriptMgr->IsScriptScheduled())
+ if (sMapMgr->IsScriptScheduled())
{
handler->SendSysMessage("DB scripts used currently, please attempt reload later.");
handler->SetSentErrorMessage(true);
@@ -913,7 +913,7 @@ public:
static bool HandleReloadWpScriptsCommand(ChatHandler* handler, const char* args)
{
- if (sScriptMgr->IsScriptScheduled())
+ if (sMapMgr->IsScriptScheduled())
{
handler->SendSysMessage("DB scripts used currently, please attempt reload later.");
handler->SetSentErrorMessage(true);
@@ -946,7 +946,7 @@ public:
static bool HandleReloadSpellScriptsCommand(ChatHandler* handler, const char* args)
{
- if (sScriptMgr->IsScriptScheduled())
+ if (sMapMgr->IsScriptScheduled())
{
handler->SendSysMessage("DB scripts used currently, please attempt reload later.");
handler->SetSentErrorMessage(true);
diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp
index 05941120423..ba1dab28350 100644
--- a/src/server/scripts/Commands/cs_reset.cpp
+++ b/src/server/scripts/Commands/cs_reset.cpp
@@ -102,7 +102,7 @@ public:
player->setFactionForRace(player->getRace());
- player->SetUInt32Value(UNIT_FIELD_BYTES_0, ((player->getRace()) | (player->getClass() << 8) | (player->getGender() << 16) | (powerType << 24)));
+ player->SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_POWER_TYPE, powerType);
// reset only if player not in some form;
if (player->GetShapeshiftForm() == FORM_NONE)
diff --git a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
index 8c781bb9001..b794a653791 100644
--- a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
+++ b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
@@ -89,7 +89,6 @@ void AddSC_boss_sulfuron();
void AddSC_boss_majordomo();
void AddSC_boss_ragnaros();
void AddSC_instance_molten_core();
-void AddSC_instance_ragefire_chasm(); //Ragefire Chasm
void AddSC_the_scarlet_enclave(); //Scarlet Enclave
void AddSC_the_scarlet_enclave_c1();
void AddSC_the_scarlet_enclave_c2();
@@ -268,7 +267,6 @@ void AddEasternKingdomsScripts()
AddSC_boss_majordomo();
AddSC_boss_ragnaros();
AddSC_instance_molten_core();
- AddSC_instance_ragefire_chasm(); //Ragefire Chasm
AddSC_the_scarlet_enclave(); //Scarlet Enclave
AddSC_the_scarlet_enclave_c1();
AddSC_the_scarlet_enclave_c2();
diff --git a/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp b/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp
index f1969a063d6..87edf4781d4 100644
--- a/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp
+++ b/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp
@@ -47,6 +47,7 @@ void AddSC_boss_meathook();
void AddSC_culling_of_stratholme();
void AddSC_instance_culling_of_stratholme();
void AddSC_instance_dire_maul(); //Dire Maul
+void AddSC_instance_ragefire_chasm(); //Ragefire Chasm
void AddSC_boss_celebras_the_cursed(); //Maraudon
void AddSC_boss_landslide();
void AddSC_boss_noxxion();
@@ -143,6 +144,7 @@ void AddKalimdorScripts()
AddSC_culling_of_stratholme();
AddSC_instance_culling_of_stratholme();
AddSC_instance_dire_maul(); //Dire Maul
+ AddSC_instance_ragefire_chasm(); //Ragefire Chasm
AddSC_boss_celebras_the_cursed(); //Maraudon
AddSC_boss_landslide();
AddSC_boss_noxxion();
diff --git a/src/server/scripts/Kalimdor/zone_the_barrens.cpp b/src/server/scripts/Kalimdor/zone_the_barrens.cpp
index 852cd62c277..b113615ca50 100644
--- a/src/server/scripts/Kalimdor/zone_the_barrens.cpp
+++ b/src/server/scripts/Kalimdor/zone_the_barrens.cpp
@@ -552,7 +552,7 @@ public:
{
if (!HasEscortState(STATE_ESCORT_ESCORTING))
{
- if (me->getStandState() == UNIT_STAND_STATE_DEAD)
+ if (me->GetStandState() == UNIT_STAND_STATE_DEAD)
me->SetStandState(UNIT_STAND_STATE_STAND);
IsPostEvent = false;
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
index bc8c7f877a9..3d21388ca11 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
@@ -809,7 +809,7 @@ class spell_blood_queen_pact_of_the_darkfallen_dmg : public SpellScriptLoader
// this is an additional effect to be executed
void PeriodicTick(AuraEffect const* aurEff)
{
- SpellInfo const* damageSpell = sSpellMgr->EnsureSpellInfo(SPELL_PACT_OF_THE_DARKFALLEN_DAMAGE);
+ SpellInfo const* damageSpell = sSpellMgr->AssertSpellInfo(SPELL_PACT_OF_THE_DARKFALLEN_DAMAGE);
int32 damage = damageSpell->Effects[EFFECT_0].CalcValue();
float multiplier = 0.3375f + 0.1f * uint32(aurEff->GetTickNumber()/10); // do not convert to 0.01f - we need tick number/10 as INT (damage increases every 10 ticks)
damage = int32(damage * multiplier);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
index 9b0693ec95e..d77842fff0a 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
@@ -1843,7 +1843,7 @@ class spell_igb_rocket_pack : public SpellScriptLoader
void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
- SpellInfo const* damageInfo = sSpellMgr->EnsureSpellInfo(SPELL_ROCKET_PACK_DAMAGE);
+ SpellInfo const* damageInfo = sSpellMgr->AssertSpellInfo(SPELL_ROCKET_PACK_DAMAGE);
GetTarget()->CastCustomSpell(SPELL_ROCKET_PACK_DAMAGE, SPELLVALUE_BASE_POINT0, 2 * (damageInfo->Effects[EFFECT_0].CalcValue() + aurEff->GetTickNumber() * aurEff->GetAmplitude()), NULL, TRIGGERED_FULL_MASK);
GetTarget()->CastSpell(NULL, SPELL_ROCKET_BURST, TRIGGERED_FULL_MASK);
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
index f4e9d4673f2..280a0aaa13a 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
@@ -1257,7 +1257,7 @@ class spell_putricide_mutated_plague : public SpellScriptLoader
return;
uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell;
- SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(triggerSpell);
+ SpellInfo const* spell = sSpellMgr->AssertSpellInfo(triggerSpell);
spell = sSpellMgr->GetSpellForDifficultyFromSpell(spell, caster);
int32 damage = spell->Effects[EFFECT_0].CalcValue(caster);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
index 309d5d4c62f..0714f2426bc 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
@@ -359,9 +359,9 @@ static bool IsEncounterFinished(Unit* who)
if (!mkii || !vx001 || !aerial)
return false;
- if (mkii->getStandState() == UNIT_STAND_STATE_DEAD &&
- vx001->getStandState() == UNIT_STAND_STATE_DEAD &&
- aerial->getStandState() == UNIT_STAND_STATE_DEAD)
+ if (mkii->GetStandState() == UNIT_STAND_STATE_DEAD &&
+ vx001->GetStandState() == UNIT_STAND_STATE_DEAD &&
+ aerial->GetStandState() == UNIT_STAND_STATE_DEAD)
{
who->Kill(mkii);
who->Kill(vx001);
diff --git a/src/server/scripts/ScriptLoader.cpp b/src/server/scripts/ScriptLoader.cpp
deleted file mode 100644
index 57c848d5981..00000000000
--- a/src/server/scripts/ScriptLoader.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include "ScriptLoader.h"
-#include "World.h"
-
-void AddSpellsScripts();
-void AddCommandsScripts();
-
-#ifdef SCRIPTS
-void AddWorldScripts();
-void AddEasternKingdomsScripts();
-void AddKalimdorScripts();
-void AddOutlandScripts();
-void AddNorthrendScripts();
-void AddEventsScripts();
-void AddPetScripts();
-void AddOutdoorPvPScripts();
-void AddCustomScripts();
-#endif
-
-void AddScripts()
-{
- AddSpellsScripts();
- AddCommandsScripts();
-#ifdef SCRIPTS
- AddWorldScripts();
- AddEasternKingdomsScripts();
- AddKalimdorScripts();
- AddOutlandScripts();
- AddNorthrendScripts();
- AddEventsScripts();
- AddPetScripts();
- AddOutdoorPvPScripts();
- AddCustomScripts();
-#endif
-}
diff --git a/src/server/scripts/ScriptLoader.cpp.in.cmake b/src/server/scripts/ScriptLoader.cpp.in.cmake
new file mode 100644
index 00000000000..33c336a9a93
--- /dev/null
+++ b/src/server/scripts/ScriptLoader.cpp.in.cmake
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+// This file was created automatically from your script configuration!
+// Use CMake to reconfigure this file, never change it on your own!
+
+#cmakedefine TRINITY_IS_DYNAMIC_SCRIPTLOADER
+
+#include "Define.h"
+#include <vector>
+#include <string>
+
+@TRINITY_SCRIPTS_FORWARD_DECL@
+#ifdef TRINITY_IS_DYNAMIC_SCRIPTLOADER
+# include "revision_data.h"
+# define TC_SCRIPT_API TC_API_EXPORT
+extern "C" {
+
+/// Exposed in script modules to return the script module revision hash.
+TC_SCRIPT_API char const* GetScriptModuleRevisionHash()
+{
+ return _HASH;
+}
+
+/// Exposed in script module to return the name of the script module
+/// contained in this shared library.
+TC_SCRIPT_API char const* GetScriptModule()
+{
+ return "@TRINITY_CURRENT_SCRIPT_PROJECT@";
+}
+
+#else
+# include "ScriptLoader.h"
+# define TC_SCRIPT_API
+#endif
+
+/// Exposed in script modules to register all scripts to the ScriptMgr.
+TC_SCRIPT_API void AddScripts()
+{
+@TRINITY_SCRIPTS_INVOKE@}
+
+/// Exposed in script modules to get the build directive of the module.
+TC_SCRIPT_API char const* GetBuildDirective()
+{
+ return _BUILD_DIRECTIVE;
+}
+
+#ifdef TRINITY_IS_DYNAMIC_SCRIPTLOADER
+} // extern "C"
+#endif
diff --git a/src/server/scripts/PrecompiledHeaders/ScriptPCH.cpp b/src/server/scripts/ScriptPCH.cpp
index 41fecf3c60d..41fecf3c60d 100644
--- a/src/server/scripts/PrecompiledHeaders/ScriptPCH.cpp
+++ b/src/server/scripts/ScriptPCH.cpp
diff --git a/src/server/scripts/PrecompiledHeaders/ScriptPCH.h b/src/server/scripts/ScriptPCH.h
index 1cd25309055..1cd25309055 100644
--- a/src/server/scripts/PrecompiledHeaders/ScriptPCH.h
+++ b/src/server/scripts/ScriptPCH.h
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index d210eda9045..724019a1b19 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -226,7 +226,7 @@ class spell_dk_anti_magic_zone : public SpellScriptLoader
void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/)
{
- SpellInfo const* talentSpell = sSpellMgr->EnsureSpellInfo(SPELL_DK_ANTI_MAGIC_SHELL_TALENT);
+ SpellInfo const* talentSpell = sSpellMgr->AssertSpellInfo(SPELL_DK_ANTI_MAGIC_SHELL_TALENT);
amount = talentSpell->Effects[EFFECT_0].CalcValue(GetCaster());
if (Player* player = GetCaster()->ToPlayer())
amount += int32(2 * player->GetTotalAttackPowerValue(BASE_ATTACK));
@@ -1634,7 +1634,7 @@ class spell_dk_will_of_the_necropolis : public SpellScriptLoader
{
// min pct of hp is stored in effect 0 of talent spell
uint8 rank = GetSpellInfo()->GetRank();
- SpellInfo const* talentProto = sSpellMgr->EnsureSpellInfo(sSpellMgr->GetSpellWithRank(SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1, rank));
+ SpellInfo const* talentProto = sSpellMgr->AssertSpellInfo(sSpellMgr->GetSpellWithRank(SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1, rank));
int32 remainingHp = int32(GetTarget()->GetHealth() - dmgInfo.GetDamage());
int32 minHp = int32(GetTarget()->CountPctFromMaxHealth(talentProto->Effects[EFFECT_0].CalcValue(GetCaster())));
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index ce729277e42..8b8c5300a9e 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -1245,7 +1245,7 @@ class spell_gen_defend : public SpellScriptLoader
void Register() override
{
- SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(m_scriptSpellId);
+ SpellInfo const* spell = sSpellMgr->AssertSpellInfo(m_scriptSpellId);
// Defend spells cast by NPCs (add visuals)
if (spell->Effects[EFFECT_0].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
@@ -2148,7 +2148,7 @@ class spell_gen_mounted_charge: public SpellScriptLoader
void Register() override
{
- SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(m_scriptSpellId);
+ SpellInfo const* spell = sSpellMgr->AssertSpellInfo(m_scriptSpellId);
if (spell->HasEffect(SPELL_EFFECT_SCRIPT_EFFECT))
OnEffectHitTarget += SpellEffectFn(spell_gen_mounted_charge_SpellScript::HandleScriptEffect, EFFECT_FIRST_FOUND, SPELL_EFFECT_SCRIPT_EFFECT);
diff --git a/src/server/scripts/Spells/spell_holiday.cpp b/src/server/scripts/Spells/spell_holiday.cpp
index a3359fdf6f9..6442eb8acca 100644
--- a/src/server/scripts/Spells/spell_holiday.cpp
+++ b/src/server/scripts/Spells/spell_holiday.cpp
@@ -65,7 +65,7 @@ class spell_love_is_in_the_air_romantic_picnic : public SpellScriptLoader
Unit* caster = GetCaster();
// If our player is no longer sit, remove all auras
- if (target->getStandState() != UNIT_STAND_STATE_SIT)
+ if (target->GetStandState() != UNIT_STAND_STATE_SIT)
{
target->RemoveAura(SPELL_ROMANTIC_PICNIC_ACHIEV);
target->RemoveAura(GetAura());
@@ -84,7 +84,7 @@ class spell_love_is_in_the_air_romantic_picnic : public SpellScriptLoader
target->VisitNearbyWorldObject(INTERACTION_DISTANCE*2, searcher);
for (std::list<Player*>::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
{
- if ((*itr) != target && (*itr)->HasAura(GetId())) // && (*itr)->getStandState() == UNIT_STAND_STATE_SIT)
+ if ((*itr) != target && (*itr)->HasAura(GetId())) // && (*itr)->GetStandState() == UNIT_STAND_STATE_SIT)
{
if (caster)
{
diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp
index 4d7cc277ff6..82d9d134445 100644
--- a/src/server/scripts/Spells/spell_hunter.cpp
+++ b/src/server/scripts/Spells/spell_hunter.cpp
@@ -763,7 +763,7 @@ class spell_hun_readiness : public SpellScriptLoader
// immediately finishes the cooldown on your other Hunter abilities except Bestial Wrath
GetCaster()->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool
{
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first);
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first);
///! If spellId in cooldown map isn't valid, the above will return a null pointer.
if (spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER &&
diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp
index d08968fbf55..2f4e4fa6f44 100644
--- a/src/server/scripts/Spells/spell_mage.cpp
+++ b/src/server/scripts/Spells/spell_mage.cpp
@@ -180,7 +180,7 @@ class spell_mage_cold_snap : public SpellScriptLoader
{
GetCaster()->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool
{
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first);
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first);
return spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfo->GetSchoolMask() & SPELL_SCHOOL_MASK_FROST) &&
spellInfo->Id != SPELL_MAGE_COLD_SNAP && spellInfo->GetRecoveryTime() > 0;
}, true);
@@ -405,7 +405,7 @@ class spell_mage_ignite : public SpellScriptLoader
{
PreventDefaultAction();
- SpellInfo const* igniteDot = sSpellMgr->EnsureSpellInfo(SPELL_MAGE_IGNITE);
+ SpellInfo const* igniteDot = sSpellMgr->AssertSpellInfo(SPELL_MAGE_IGNITE);
int32 pct = 8 * GetSpellInfo()->GetRank();
int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), pct) / igniteDot->GetMaxTicks());
diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp
index 8bd4b3eb070..d9fd36f5fd4 100644
--- a/src/server/scripts/Spells/spell_paladin.cpp
+++ b/src/server/scripts/Spells/spell_paladin.cpp
@@ -1195,7 +1195,7 @@ class spell_pal_light_s_beacon : public SpellScriptLoader
if (!procSpell)
return;
- uint32 healSpellId = procSpell->IsRankOf(sSpellMgr->EnsureSpellInfo(SPELL_PALADIN_HOLY_LIGHT)) ? SPELL_PALADIN_BEACON_OF_LIGHT_HEAL_1 : SPELL_PALADIN_BEACON_OF_LIGHT_HEAL_3;
+ uint32 healSpellId = procSpell->IsRankOf(sSpellMgr->AssertSpellInfo(SPELL_PALADIN_HOLY_LIGHT)) ? SPELL_PALADIN_BEACON_OF_LIGHT_HEAL_1 : SPELL_PALADIN_BEACON_OF_LIGHT_HEAL_3;
uint32 heal = CalculatePct(eventInfo.GetHealInfo()->GetHeal(), aurEff->GetAmount());
Unit* beaconTarget = GetCaster();
diff --git a/src/server/scripts/Spells/spell_pet.cpp b/src/server/scripts/Spells/spell_pet.cpp
index 7393a7d3bcb..cde291cd82b 100644
--- a/src/server/scripts/Spells/spell_pet.cpp
+++ b/src/server/scripts/Spells/spell_pet.cpp
@@ -916,7 +916,7 @@ public:
if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt
{
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
AddPct(mod, spellInfo->Effects[EFFECT_0].CalcValue());
}
@@ -959,7 +959,7 @@ public:
if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt
{
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
mod += CalculatePct(1.0f, spellInfo->Effects[EFFECT_1].CalcValue());
}
@@ -989,7 +989,7 @@ public:
if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt
{
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
mod += CalculatePct(1.0f, spellInfo->Effects[EFFECT_1].CalcValue());
}
diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp
index ecf5b7b5acf..51f03346df1 100644
--- a/src/server/scripts/Spells/spell_priest.cpp
+++ b/src/server/scripts/Spells/spell_priest.cpp
@@ -236,7 +236,7 @@ class spell_pri_glyph_of_prayer_of_healing : public SpellScriptLoader
{
PreventDefaultAction();
- SpellInfo const* triggeredSpellInfo = sSpellMgr->EnsureSpellInfo(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL);
+ SpellInfo const* triggeredSpellInfo = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL);
int32 heal = int32(CalculatePct(int32(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()) / triggeredSpellInfo->GetMaxTicks());
GetTarget()->CastCustomSpell(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL, SPELLVALUE_BASE_POINT0, heal, eventInfo.GetProcTarget(), true, NULL, aurEff);
}
diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp
index 9b577d4e140..affc4d1c26c 100644
--- a/src/server/scripts/Spells/spell_rogue.cpp
+++ b/src/server/scripts/Spells/spell_rogue.cpp
@@ -450,7 +450,7 @@ class spell_rog_preparation : public SpellScriptLoader
Unit* caster = GetCaster();
caster->GetSpellHistory()->ResetCooldowns([caster](SpellHistory::CooldownStorageType::iterator itr) -> bool
{
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first);
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first);
if (spellInfo->SpellFamilyName != SPELLFAMILY_ROGUE)
return false;
diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp
index 7cc6fe888e9..a0a6189cbe2 100644
--- a/src/server/scripts/Spells/spell_warlock.cpp
+++ b/src/server/scripts/Spells/spell_warlock.cpp
@@ -271,7 +271,7 @@ class spell_warl_demonic_circle_summon : public SpellScriptLoader
// WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST; allowing him to cast the WARLOCK_DEMONIC_CIRCLE_TELEPORT.
// If not in range remove the WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST.
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(SPELL_WARLOCK_DEMONIC_CIRCLE_TELEPORT);
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_WARLOCK_DEMONIC_CIRCLE_TELEPORT);
if (GetTarget()->IsWithinDist(circle, spellInfo->GetMaxRange(true)))
{
@@ -362,7 +362,7 @@ class spell_warl_demonic_empowerment : public SpellScriptLoader
break;
case CREATURE_FAMILY_VOIDWALKER:
{
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER);
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER);
int32 hp = int32(targetCreature->CountPctFromMaxHealth(GetCaster()->CalculateSpellDamage(targetCreature, spellInfo, 0)));
targetCreature->CastCustomSpell(targetCreature, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER, &hp, NULL, NULL, true);
//unitTarget->CastSpell(unitTarget, 54441, true);
diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp
index d224c234cb4..ea9ccc956e5 100644
--- a/src/server/scripts/Spells/spell_warrior.cpp
+++ b/src/server/scripts/Spells/spell_warrior.cpp
@@ -271,7 +271,7 @@ class spell_warr_deep_wounds : public SpellScriptLoader
{
ApplyPct(damage, 16 * GetSpellInfo()->GetRank());
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC);
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC);
uint32 ticks = uint32(spellInfo->GetDuration()) / spellInfo->Effects[EFFECT_0].Amplitude;
// Add remaining ticks to damage done
diff --git a/src/server/scripts/World/duel_reset.cpp b/src/server/scripts/World/duel_reset.cpp
index 7982a5639ec..b04f3ec0aa7 100644
--- a/src/server/scripts/World/duel_reset.cpp
+++ b/src/server/scripts/World/duel_reset.cpp
@@ -105,7 +105,7 @@ class DuelResetScript : public PlayerScript
{
SpellHistory::Clock::time_point now = SpellHistory::Clock::now();
uint32 cooldownDuration = itr->second.CooldownEnd > now ? std::chrono::duration_cast<std::chrono::milliseconds>(itr->second.CooldownEnd - now).count() : 0;
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first);
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first);
return spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS
&& spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS
&& !itr->second.OnHold
@@ -119,7 +119,7 @@ class DuelResetScript : public PlayerScript
// remove cooldowns on spells that have < 10 min CD and has no onHold
player->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool
{
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first);
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first);
return spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS
&& spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS
&& !itr->second.OnHold;
diff --git a/src/server/shared/CMakeLists.txt b/src/server/shared/CMakeLists.txt
index 1ab340a4f3e..e99a81a084b 100644
--- a/src/server/shared/CMakeLists.txt
+++ b/src/server/shared/CMakeLists.txt
@@ -24,8 +24,8 @@ GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
add_definitions(-DTRINITY_API_EXPORT_SHARED)
add_library(shared
- ${PRIVATE_SOURCES}
${PRIVATE_PCH_SOURCE}
+ ${PRIVATE_SOURCES}
)
CollectIncludeDirectories(
diff --git a/src/server/shared/DataStores/DBCStore.h b/src/server/shared/DataStores/DBCStore.h
index b93bbdaea12..7c2cab1e36a 100644
--- a/src/server/shared/DataStores/DBCStore.h
+++ b/src/server/shared/DataStores/DBCStore.h
@@ -25,6 +25,121 @@
#include "DatabaseWorkerPool.h"
#include "Implementation/WorldDatabase.h"
#include "DatabaseEnv.h"
+#include <G3D/Vector3.h>
+#include <G3D/AABox.h>
+
+ // Structures for M4 file. Source: https://wowdev.wiki
+template<typename T>
+struct M2SplineKey
+{
+ T p0;
+ T p1;
+ T p2;
+};
+
+struct M2Header
+{
+ char Magic[4]; // "MD20"
+ uint32 Version; // The version of the format.
+ uint32 lName; // Length of the model's name including the trailing \0
+ uint32 ofsName; // Offset to the name, it seems like models can get reloaded by this name.should be unique, i guess.
+ uint32 GlobalModelFlags; // 0x0001: tilt x, 0x0002: tilt y, 0x0008: add 2 fields in header, 0x0020: load .phys data (MoP+), 0x0080: has _lod .skin files (MoP?+), 0x0100: is camera related.
+ uint32 nGlobalSequences;
+ uint32 ofsGlobalSequences; // A list of timestamps.
+ uint32 nAnimations;
+ uint32 ofsAnimations; // Information about the animations in the model.
+ uint32 nAnimationLookup;
+ uint32 ofsAnimationLookup; // Mapping of global IDs to the entries in the Animation sequences block.
+ uint32 nBones; // MAX_BONES = 0x100
+ uint32 ofsBones; // Information about the bones in this model.
+ uint32 nKeyBoneLookup;
+ uint32 ofsKeyBoneLookup; // Lookup table for key skeletal bones.
+ uint32 nVertices;
+ uint32 ofsVertices; // Vertices of the model.
+ uint32 nViews; // Views (LOD) are now in .skins.
+ uint32 nSubmeshAnimations;
+ uint32 ofsSubmeshAnimations; // Submesh color and alpha animations definitions.
+ uint32 nTextures;
+ uint32 ofsTextures; // Textures of this model.
+ uint32 nTransparency;
+ uint32 ofsTransparency; // Transparency of textures.
+ uint32 nUVAnimation;
+ uint32 ofsUVAnimation;
+ uint32 nTexReplace;
+ uint32 ofsTexReplace; // Replaceable Textures.
+ uint32 nRenderFlags;
+ uint32 ofsRenderFlags; // Blending modes / render flags.
+ uint32 nBoneLookupTable;
+ uint32 ofsBoneLookupTable; // A bone lookup table.
+ uint32 nTexLookup;
+ uint32 ofsTexLookup; // The same for textures.
+ uint32 nTexUnits; // possibly removed with cata?!
+ uint32 ofsTexUnits; // And texture units. Somewhere they have to be too.
+ uint32 nTransLookup;
+ uint32 ofsTransLookup; // Everything needs its lookup. Here are the transparencies.
+ uint32 nUVAnimLookup;
+ uint32 ofsUVAnimLookup;
+ G3D::AABox BoundingBox; // min/max( [1].z, 2.0277779f ) - 0.16f seems to be the maximum camera height
+ float BoundingSphereRadius;
+ G3D::AABox CollisionBox;
+ float CollisionSphereRadius;
+ uint32 nBoundingTriangles;
+ uint32 ofsBoundingTriangles; // Our bounding volumes. Similar structure like in the old ofsViews.
+ uint32 nBoundingVertices;
+ uint32 ofsBoundingVertices;
+ uint32 nBoundingNormals;
+ uint32 ofsBoundingNormals;
+ uint32 nAttachments;
+ uint32 ofsAttachments; // Attachments are for weapons etc.
+ uint32 nAttachLookup;
+ uint32 ofsAttachLookup; // Of course with a lookup.
+ uint32 nEvents;
+ uint32 ofsEvents; // Used for playing sounds when dying and a lot else.
+ uint32 nLights;
+ uint32 ofsLights; // Lights are mainly used in loginscreens but in wands and some doodads too.
+ uint32 nCameras; // Format of Cameras changed with version 271!
+ uint32 ofsCameras; // The cameras are present in most models for having a model in the Character-Tab.
+ uint32 nCameraLookup;
+ uint32 ofsCameraLookup; // And lookup-time again.
+ uint32 nRibbonEmitters;
+ uint32 ofsRibbonEmitters; // Things swirling around. See the CoT-entrance for light-trails.
+ uint32 nParticleEmitters;
+ uint32 ofsParticleEmitters; // Spells and weapons, doodads and loginscreens use them. Blood dripping of a blade? Particles.
+ uint32 nBlendMaps; // This has to deal with blending. Exists IFF (flags & 0x8) != 0. When set, textures blending is overriden by the associated array. See M2/WotLK#Blend_mode_overrides
+ uint32 ofsBlendMaps; // Same as above. Points to an array of uint16 of nBlendMaps entries -- From WoD information.};
+};
+
+struct M2Array
+{
+ uint32_t number;
+ uint32 offset_elements;
+};
+struct M2Track
+{
+ uint16_t interpolation_type;
+ uint16_t global_sequence;
+ M2Array timestamps;
+ M2Array values;
+};
+
+struct M2Camera
+{
+ uint32_t type; // 0: portrait, 1: characterinfo; -1: else (flyby etc.); referenced backwards in the lookup table.
+ float fov; // No radians, no degrees. Multiply by 35 to get degrees.
+ float far_clip;
+ float near_clip;
+ M2Track positions; // How the camera's position moves. Should be 3*3 floats.
+ G3D::Vector3 position_base;
+ M2Track target_positions; // How the target moves. Should be 3*3 floats.
+ G3D::Vector3 target_position_base;
+ M2Track rolldata; // The camera can have some roll-effect. Its 0 to 2*Pi.
+};
+
+struct FlyByCamera
+{
+ uint32 timeStamp;
+ G3D::Vector4 locations;
+};
struct SqlDbc
{
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index a779075e2ed..d24a91ed458 100644
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -23,16 +23,7 @@
#include "Errors.h"
#include "ByteConverter.h"
#include "Util.h"
-
-#include <exception>
-#include <list>
-#include <map>
-#include <string>
-#include <vector>
#include <cstring>
-#include <time.h>
-#include <cmath>
-#include <type_traits>
class MessageBuffer;
diff --git a/src/server/shared/Realm/Realm.cpp b/src/server/shared/Realm/Realm.cpp
index 0c8f4d1d492..11c52f281a9 100644
--- a/src/server/shared/Realm/Realm.cpp
+++ b/src/server/shared/Realm/Realm.cpp
@@ -16,3 +16,38 @@
*/
#include "Realm.h"
+
+ip::tcp::endpoint Realm::GetAddressForClient(ip::address const& clientAddr) const
+{
+ ip::address realmIp;
+
+ // Attempt to send best address for client
+ if (clientAddr.is_loopback())
+ {
+ // Try guessing if realm is also connected locally
+ if (LocalAddress.is_loopback() || ExternalAddress.is_loopback())
+ realmIp = clientAddr;
+ else
+ {
+ // Assume that user connecting from the machine that bnetserver is located on
+ // has all realms available in his local network
+ realmIp = LocalAddress;
+ }
+ }
+ else
+ {
+ if (clientAddr.is_v4() &&
+ (clientAddr.to_v4().to_ulong() & LocalSubnetMask.to_v4().to_ulong()) ==
+ (LocalAddress.to_v4().to_ulong() & LocalSubnetMask.to_v4().to_ulong()))
+ {
+ realmIp = LocalAddress;
+ }
+ else
+ realmIp = ExternalAddress;
+ }
+
+ ip::tcp::endpoint endpoint(realmIp, Port);
+
+ // Return external IP
+ return endpoint;
+}
diff --git a/src/server/shared/Realm/Realm.h b/src/server/shared/Realm/Realm.h
index 83a344dd817..241ccd2bca8 100644
--- a/src/server/shared/Realm/Realm.h
+++ b/src/server/shared/Realm/Realm.h
@@ -37,7 +37,7 @@ enum RealmFlags
REALM_FLAG_FULL = 0x80
};
-struct RealmHandle
+struct TC_SHARED_API RealmHandle
{
RealmHandle() : Realm(0) { }
RealmHandle(uint32 index) : Realm(index) { }
@@ -53,20 +53,20 @@ struct RealmHandle
/// Type of server, this is values from second column of Cfg_Configs.dbc
enum RealmType
{
- REALM_TYPE_NORMAL = 0,
- REALM_TYPE_PVP = 1,
- REALM_TYPE_NORMAL2 = 4,
- REALM_TYPE_RP = 6,
- REALM_TYPE_RPPVP = 8,
+ REALM_TYPE_NORMAL = 0,
+ REALM_TYPE_PVP = 1,
+ REALM_TYPE_NORMAL2 = 4,
+ REALM_TYPE_RP = 6,
+ REALM_TYPE_RPPVP = 8,
- MAX_CLIENT_REALM_TYPE = 14,
+ MAX_CLIENT_REALM_TYPE = 14,
- REALM_TYPE_FFA_PVP = 16 // custom, free for all pvp mode like arena PvP in all zones except rest activated places and sanctuaries
- // replaced by REALM_PVP in realm list
+ REALM_TYPE_FFA_PVP = 16 // custom, free for all pvp mode like arena PvP in all zones except rest activated places and sanctuaries
+ // replaced by REALM_PVP in realm list
};
// Storage object for a realm
-struct Realm
+struct TC_SHARED_API Realm
{
RealmHandle Id;
uint32 Build;
@@ -75,11 +75,13 @@ struct Realm
ip::address LocalSubnetMask;
uint16 Port;
std::string Name;
- uint8 Type; // icon
+ uint8 Type;
RealmFlags Flags;
uint8 Timezone;
AccountTypes AllowedSecurityLevel;
float PopulationLevel;
+
+ ip::tcp::endpoint GetAddressForClient(ip::address const& clientAddr) const;
};
#endif // Realm_h__
diff --git a/src/server/authserver/Realms/RealmList.cpp b/src/server/shared/Realm/RealmList.cpp
index f1b25d8554d..e941800cd76 100644
--- a/src/server/authserver/Realms/RealmList.cpp
+++ b/src/server/shared/Realm/RealmList.cpp
@@ -16,20 +16,25 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "Common.h"
-#include "Database/DatabaseEnv.h"
#include "RealmList.h"
-#include <boost/asio/ip/tcp.hpp>
+#include "Database/DatabaseEnv.h"
+#include "Util.h"
-namespace boost { namespace asio { namespace ip { class address; } } }
+RealmList::RealmList() : _updateInterval(0), _updateTimer(nullptr), _resolver(nullptr)
+{
+}
-RealmList::RealmList() : _updateInterval(0), _updateTimer(nullptr), _resolver(nullptr) { }
RealmList::~RealmList()
{
- delete _resolver;
delete _updateTimer;
}
+RealmList* RealmList::Instance()
+{
+ static RealmList instance;
+ return &instance;
+}
+
// Load the realm list from the database
void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInterval)
{
@@ -38,7 +43,7 @@ void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInte
_resolver = new boost::asio::ip::tcp::resolver(ioService);
// Get the content of the realmlist table in the database
- UpdateRealms(true, boost::system::error_code());
+ UpdateRealms(boost::system::error_code());
}
void RealmList::Close()
@@ -67,16 +72,22 @@ void RealmList::UpdateRealm(RealmHandle const& id, uint32 build, const std::stri
realm.Port = port;
}
-void RealmList::UpdateRealms(bool init, boost::system::error_code const& error)
+void RealmList::UpdateRealms(boost::system::error_code const& error)
{
if (error)
return;
- TC_LOG_INFO("server.authserver", "Updating Realm List...");
+ TC_LOG_DEBUG("server.authserver", "Updating Realm List...");
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST);
PreparedQueryResult result = LoginDatabase.Query(stmt);
+ std::map<RealmHandle, std::string> existingRealms;
+ for (auto const& p : _realms)
+ existingRealms[p.first] = p.second.Name;
+
+ _realms.clear();
+
// Circle through results and add them to the realm map
if (result)
{
@@ -95,8 +106,8 @@ void RealmList::UpdateRealms(bool init, boost::system::error_code const& error)
boost::asio::ip::tcp::resolver::iterator endPoint = _resolver->resolve(externalAddressQuery, ec);
if (endPoint == end || ec)
{
- TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[2].GetString().c_str());
- return;
+ TC_LOG_ERROR("server.authserver", "Could not resolve address %s for realm \"%s\" id %u", fields[2].GetString().c_str(), name.c_str(), realmId);
+ continue;
}
ip::address externalAddress = (*endPoint).endpoint().address();
@@ -105,8 +116,8 @@ void RealmList::UpdateRealms(bool init, boost::system::error_code const& error)
endPoint = _resolver->resolve(localAddressQuery, ec);
if (endPoint == end || ec)
{
- TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[3].GetString().c_str());
- return;
+ TC_LOG_ERROR("server.authserver", "Could not resolve localAddress %s for realm \"%s\" id %u", fields[3].GetString().c_str(), name.c_str(), realmId);
+ continue;
}
ip::address localAddress = (*endPoint).endpoint().address();
@@ -115,8 +126,8 @@ void RealmList::UpdateRealms(bool init, boost::system::error_code const& error)
endPoint = _resolver->resolve(localSubmaskQuery, ec);
if (endPoint == end || ec)
{
- TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[4].GetString().c_str());
- return;
+ TC_LOG_ERROR("server.authserver", "Could not resolve localSubnetMask %s for realm \"%s\" id %u", fields[4].GetString().c_str(), name.c_str(), realmId);
+ continue;
}
ip::address localSubmask = (*endPoint).endpoint().address();
@@ -138,8 +149,12 @@ void RealmList::UpdateRealms(bool init, boost::system::error_code const& error)
UpdateRealm(id, build, name, externalAddress, localAddress, localSubmask, port, icon, flag,
timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop);
- if (init)
+ if (!existingRealms.count(id))
TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), externalAddress.to_string().c_str(), port);
+ else
+ TC_LOG_DEBUG("server.authserver", "Updating realm \"%s\" at %s:%u.", name.c_str(), externalAddress.to_string().c_str(), port);
+
+ existingRealms.erase(id);
}
catch (std::exception& ex)
{
@@ -150,10 +165,13 @@ void RealmList::UpdateRealms(bool init, boost::system::error_code const& error)
while (result->NextRow());
}
+ for (auto itr = existingRealms.begin(); itr != existingRealms.end(); ++itr)
+ TC_LOG_INFO("server.authserver", "Removed realm \"%s\".", itr->second.c_str());
+
if (_updateInterval)
{
_updateTimer->expires_from_now(boost::posix_time::seconds(_updateInterval));
- _updateTimer->async_wait(std::bind(&RealmList::UpdateRealms, this, false, std::placeholders::_1));
+ _updateTimer->async_wait(std::bind(&RealmList::UpdateRealms, this, std::placeholders::_1));
}
}
diff --git a/src/server/authserver/Realms/RealmList.h b/src/server/shared/Realm/RealmList.h
index e35975b215a..3b81337e762 100644
--- a/src/server/authserver/Realms/RealmList.h
+++ b/src/server/shared/Realm/RealmList.h
@@ -29,16 +29,12 @@
using namespace boost::asio;
/// Storage object for the list of realms on the server
-class RealmList
+class TC_SHARED_API RealmList
{
public:
typedef std::map<RealmHandle, Realm> RealmMap;
- static RealmList* instance()
- {
- static RealmList instance;
- return &instance;
- }
+ static RealmList* Instance();
~RealmList();
@@ -51,7 +47,7 @@ public:
private:
RealmList();
- void UpdateRealms(bool init, boost::system::error_code const& error);
+ void UpdateRealms(boost::system::error_code const& error);
void UpdateRealm(RealmHandle const& id, uint32 build, const std::string& name, ip::address const& address, ip::address const& localAddr,
ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population);
@@ -61,5 +57,5 @@ private:
boost::asio::ip::tcp::resolver* _resolver;
};
-#define sRealmList RealmList::instance()
+#define sRealmList RealmList::Instance()
#endif
diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt
index 7fb4c6d2b75..0de8d6054f3 100644
--- a/src/server/worldserver/CMakeLists.txt
+++ b/src/server/worldserver/CMakeLists.txt
@@ -29,8 +29,8 @@ endif()
GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
add_executable(worldserver
- ${PRIVATE_SOURCES}
${PRIVATE_PCH_SOURCE}
+ ${PRIVATE_SOURCES}
)
if( NOT WIN32 )
@@ -48,6 +48,7 @@ set_target_properties(worldserver PROPERTIES LINK_FLAGS "${worldserver_LINK_FLAG
target_link_libraries(worldserver
PUBLIC
scripts
+ game
gsoap
readline)
@@ -68,6 +69,11 @@ set_target_properties(worldserver
FOLDER
"server")
+# Add all dynamic projects as dependency to the worldserver
+if (WORLDSERVER_DYNAMIC_SCRIPT_MODULES_DEPENDENCIES)
+ add_dependencies(worldserver ${WORLDSERVER_DYNAMIC_SCRIPT_MODULES_DEPENDENCIES})
+endif()
+
if( WIN32 )
if ( MSVC )
add_custom_command(TARGET worldserver
diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp
index c047c1fafc3..2b5553b4bb0 100644
--- a/src/server/worldserver/Main.cpp
+++ b/src/server/worldserver/Main.cpp
@@ -39,6 +39,7 @@
#include "InstanceSaveMgr.h"
#include "ObjectAccessor.h"
#include "ScriptMgr.h"
+#include "ScriptReloadMgr.h"
#include "ScriptLoader.h"
#include "OutdoorPvP/OutdoorPvPMgr.h"
#include "BattlegroundMgr.h"
@@ -271,6 +272,7 @@ extern int main(int argc, char** argv)
sOutdoorPvPMgr->Die();
sMapMgr->UnloadAll(); // unload all grids (including locked in memory)
sScriptMgr->Unload();
+ sScriptReloadMgr->Unload();
// set server offline
LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realm.Id.Realm);
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 7c512d8ae6e..c2694c640c5 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -12,6 +12,7 @@
# SERVER LOGGING
# SERVER SETTINGS
# UPDATE SETTINGS
+# HOTSWAP SETTINGS
# WARDEN SETTINGS
# PLAYER INTERACTION
# CREATURE SETTINGS
@@ -1280,6 +1281,78 @@ Updates.CleanDeadRefMaxCount = 3
###################################################################################################
###################################################################################################
+# HOTSWAP SETTINGS
+#
+# HotSwap.Enabled (Requires compilation with DYNAMIC_LINKING=1)
+# Description: Enables dynamic script hotswapping.
+# Reloads scripts on changes.
+# Default: 1 - (Enabled)
+# 0 - (Disabled)
+
+HotSwap.Enabled = 1
+
+#
+# HotSwap.ScriptDir
+# Description: Directory containing the script shared libraries (.dll/.so).
+# Example: "/usr/local/scripts"
+# Default: "scripts"
+
+HotSwap.ScriptDir = "scripts"
+
+# HotSwap.EnableReCompiler
+# Description: Enables the dynamic script recompiler.
+# Watches your script source directories and recompiles the
+# script modules on changes.
+# Default: 1 - (Enabled)
+# 0 - (Disabled)
+
+HotSwap.EnableReCompiler = 1
+
+# HotSwap.EnableEarlyTermination
+# Description: Terminate the build of a module when an associated
+# source file was changed meanwhile.
+# Default: 1 - (Enabled)
+# 0 - (Disabled)
+
+HotSwap.EnableEarlyTermination = 1
+
+# HotSwap.EnableBuildFileRecreation
+# Description: Recreate build files when sources to a module
+# were added or removed.
+# Default: 1 - (Enabled)
+# 0 - (Disabled)
+
+HotSwap.EnableBuildFileRecreation = 1
+
+#
+# HotSwap.EnableInstall
+# Description: Enables cmake install after automatic builds have finished
+# Default: 1 - (Enabled)
+# 0 - (Disabled)
+
+HotSwap.EnableInstall = 1
+
+#
+# HotSwap.EnablePrefixCorrection
+# Description: Allows the core to automatic set the CMAKE_INSTALL_PREFIX
+# to it's current location in the filesystem.
+# Default: 1 - (Enabled)
+# 0 - (Disabled)
+
+HotSwap.EnablePrefixCorrection = 1
+
+# HotSwap.ReCompilerBuildType
+# Description: Defines the build type of the builds invoked by the recompiler.
+# Default: "" - Built-in build type of the module is used.
+# "Release" - Release builds only
+# "Debug" - Debug builds only
+
+HotSwap.ReCompilerBuildType = ""
+
+#
+###################################################################################################
+
+###################################################################################################
# WARDEN SETTINGS
#
# Warden.Enabled
@@ -3220,7 +3293,6 @@ AuctionHouseBot.Class.Key = 1
AuctionHouseBot.Class.Misc = 5
AuctionHouseBot.Class.Glyph = 3
-
#
###################################################################################################
@@ -3551,6 +3623,7 @@ Logger.mmaps=3,Server
#Logger.rbac=3,Console Server
#Logger.scripts=3,Console Server
#Logger.scripts.ai=3,Console Server
+#Logger.scripts.hotswap=3,Console Server
#Logger.server.authserver=3,Console Server
#Logger.spells=3,Console Server
#Logger.spells.periodic=3,Console Server
diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp
index f3a761fd437..1d84fc75d27 100644
--- a/src/tools/map_extractor/System.cpp
+++ b/src/tools/map_extractor/System.cpp
@@ -53,12 +53,13 @@ char input_path[MAX_PATH_LENGTH] = ".";
// **************************************************
enum Extract
{
- EXTRACT_MAP = 1,
- EXTRACT_DBC = 2
+ EXTRACT_MAP = 1,
+ EXTRACT_DBC = 2,
+ EXTRACT_CAMERA = 4
};
// Select data for extract
-int CONF_extract = EXTRACT_MAP | EXTRACT_DBC;
+int CONF_extract = EXTRACT_MAP | EXTRACT_DBC | EXTRACT_CAMERA;
// This option allow limit minimum height to some value (Allow save some memory)
bool CONF_allow_height_limit = true;
float CONF_use_minHeight = -500.0f;
@@ -103,7 +104,7 @@ void Usage(char* prg)
"%s -[var] [value]\n"\
"-i set input path (max %d characters)\n"\
"-o set output path (max %d characters)\n"\
- "-e extract only MAP(1)/DBC(2) - standard: both(3)\n"\
+ "-e extract only MAP(1)/DBC(2)/Camera(4) - standard: all(7)\n"\
"-f height stored as int (less map size but lost some accuracy) 1 by default\n"\
"Example: %s -f 0 -i \"c:\\games\\game\"", prg, MAX_PATH_LENGTH - 1, MAX_PATH_LENGTH - 1, prg);
exit(1);
@@ -151,7 +152,7 @@ void HandleArgs(int argc, char * arg[])
if(c + 1 < argc) // all ok
{
CONF_extract=atoi(arg[(c++) + 1]);
- if(!(CONF_extract > 0 && CONF_extract < 4))
+ if(!(CONF_extract > 0 && CONF_extract < 8))
Usage(arg[0]);
}
else
@@ -1025,6 +1026,56 @@ void ExtractDBCFiles(int locale, bool basicLocale)
printf("Extracted %u DBC files\n\n", count);
}
+void ExtractCameraFiles(int locale, bool basicLocale)
+{
+ printf("Extracting camera files...\n");
+ DBCFile camdbc("DBFilesClient\\CinematicCamera.dbc");
+
+ if (!camdbc.open())
+ {
+ printf("Unable to open CinematicCamera.dbc. Camera extract aborted.\n");
+ return;
+ }
+
+ // get camera file list from DBC
+ std::vector<std::string> camerafiles;
+ size_t cam_count = camdbc.getRecordCount();
+
+ for (uint32 i = 0; i < cam_count; ++i)
+ {
+ std::string camFile(camdbc.getRecord(i).getString(1));
+ size_t loc = camFile.find(".mdx");
+ if (loc != std::string::npos)
+ camFile.replace(loc, 4, ".m2");
+ camerafiles.push_back(std::string(camFile));
+ }
+
+ std::string path = output_path;
+ path += "/Cameras/";
+ CreateDir(path);
+ if (!basicLocale)
+ {
+ path += langs[locale];
+ path += "/";
+ CreateDir(path);
+ }
+
+ // extract M2s
+ uint32 count = 0;
+ for (std::string thisFile : camerafiles)
+ {
+ std::string filename = path;
+ filename += (thisFile.c_str() + strlen("Cameras\\"));
+
+ if (boost::filesystem::exists(filename))
+ continue;
+
+ if (ExtractFile(thisFile.c_str(), filename))
+ ++count;
+ }
+ printf("Extracted %u camera files\n", count);
+}
+
void LoadLocaleMPQFiles(int const locale)
{
std::string fileName = Trinity::StringFormat("%s/Data/%s/locale-%s.MPQ", input_path, langs[locale], langs[locale]);
@@ -1111,6 +1162,19 @@ int main(int argc, char * arg[])
return 0;
}
+ if (CONF_extract & EXTRACT_CAMERA)
+ {
+ printf("Using locale: %s\n", langs[FirstLocale]);
+
+ // Open MPQs
+ LoadLocaleMPQFiles(FirstLocale);
+ LoadCommonMPQFiles();
+
+ ExtractCameraFiles(FirstLocale, true);
+ // Close MPQs
+ CloseMPQFiles();
+ }
+
if (CONF_extract & EXTRACT_MAP)
{
printf("Using locale: %s\n", langs[FirstLocale]);