diff options
134 files changed, 3751 insertions, 1813 deletions
diff --git a/cmake/compiler/gcc/settings.cmake b/cmake/compiler/gcc/settings.cmake index 3a2745702c8..8247831fdd8 100644 --- a/cmake/compiler/gcc/settings.cmake +++ b/cmake/compiler/gcc/settings.cmake @@ -3,14 +3,12 @@ add_definitions(-D_BUILD_DIRECTIVE='"${CMAKE_BUILD_TYPE}"') add_definitions(-fno-delete-null-pointer-checks) -if( USE_SFMT) - if(PLATFORM EQUAL 32) - # Required on 32-bit systems to enable SSE2 (standard on x64) - add_definitions(-msse2 -mfpmath=sse) - endif() - add_definitions(-DHAVE_SSE2 -D__SSE2__) - message(STATUS "GCC: SFMT enabled, SSE2 flags forced") +if(PLATFORM EQUAL 32) + # Required on 32-bit systems to enable SSE2 (standard on x64) + add_definitions(-msse2 -mfpmath=sse) endif() +add_definitions(-DHAVE_SSE2 -D__SSE2__) +message(STATUS "GCC: SSE2 flags forced") if( WITH_WARNINGS ) add_definitions(-Wall -Wfatal-errors -Wextra) diff --git a/cmake/compiler/icc/settings.cmake b/cmake/compiler/icc/settings.cmake index 0e614ef97f8..b7e4cb742b3 100644 --- a/cmake/compiler/icc/settings.cmake +++ b/cmake/compiler/icc/settings.cmake @@ -1,13 +1,10 @@ # Set build-directive (used in core to tell which buildtype we used) add_definitions(-D_BUILD_DIRECTIVE="${CMAKE_BUILD_TYPE}") -if( USE_SFMT) - if(PLATFORM EQUAL 32) - add_definitions(-axSSE2) - else() - add_definitions(-xSSE2) - endif() - message(STATUS "ICC: SFMT enabled, SSE2 flags forced") +if(PLATFORM EQUAL 32) + add_definitions(-axSSE2) +else() + add_definitions(-xSSE2) endif() if( WITH_WARNINGS ) diff --git a/cmake/compiler/msvc/settings.cmake b/cmake/compiler/msvc/settings.cmake index eb55dc66c50..3d8fe43b6aa 100644 --- a/cmake/compiler/msvc/settings.cmake +++ b/cmake/compiler/msvc/settings.cmake @@ -20,11 +20,8 @@ else() set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE") message(STATUS "MSVC: Enabled large address awareness") - # Test if we need SSE2-support - if(USE_SFMT) - add_definitions(/arch:SSE2) - message(STATUS "MSVC: Enabled SSE2 support") - endif() + add_definitions(/arch:SSE2) + message(STATUS "MSVC: Enabled SSE2 support") endif() # Set build-directive (used in core to tell which buildtype we used) diff --git a/cmake/options.cmake b/cmake/options.cmake index 71424cc3776..11ebe6ddd12 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -13,6 +13,5 @@ option(SCRIPTS "Build core with scripts included" option(TOOLS "Build map/vmap 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(USE_SFMT "Use SFMT as random numbergenerator" 1) option(WITH_WARNINGS "Show all warnings during compile" 0) option(WITH_COREDEBUG "Include additional debug-code in core" 0) diff --git a/cmake/platform/unix/settings.cmake b/cmake/platform/unix/settings.cmake index 81f438befc9..dd8b7c081f3 100644 --- a/cmake/platform/unix/settings.cmake +++ b/cmake/platform/unix/settings.cmake @@ -1,6 +1,8 @@ # Package overloads - Linux if(CMAKE_SYSTEM_NAME MATCHES "Linux") - set(JEMALLOC_LIBRARY "jemalloc") + if (NOT NOJEM) + set(JEMALLOC_LIBRARY "jemalloc") + endif() endif() # set default configuration directory diff --git a/cmake/showoptions.cmake b/cmake/showoptions.cmake index 31e1b412b32..47ad7b0889b 100644 --- a/cmake/showoptions.cmake +++ b/cmake/showoptions.cmake @@ -50,13 +50,6 @@ else() message("* Build scripts w/PCH : No") endif() -if( USE_SFMT ) - message("* Use SFMT for RNG : Yes") - add_definitions(-DUSE_SFMT_FOR_RNG) -else() - message("* Use SFMT for RNG : No (default)") -endif() - if( WITH_WARNINGS ) message("* Show all warnings : Yes") else() @@ -78,4 +71,10 @@ if( WIN32 ) endif() endif( WIN32 ) +if ( NOJEM ) + message("") + message("*** WARNING: jemalloc linking has been disabled!") + message("*** Please note that this is for DEBUGGING WITH VALGRIND only!") + message("*** DO NOT DISABLE IT UNLESS YOU KNOW WHAT YOU'RE DOING!") +endif() message("") diff --git a/dep/CMakeLists.txt b/dep/CMakeLists.txt index 9c13ad59bc5..d658ba43ffe 100644 --- a/dep/CMakeLists.txt +++ b/dep/CMakeLists.txt @@ -15,8 +15,8 @@ elseif( MSVC ) endif() if(CMAKE_SYSTEM_NAME MATCHES "Linux") - if(SERVERS) - add_subdirectory(jemalloc) + if(SERVERS AND NOT NOJEM) + add_subdirectory(jemalloc) endif() endif() diff --git a/dep/PackageList.txt b/dep/PackageList.txt index 7ab307ecfc5..ef1b9b58fca 100644 --- a/dep/PackageList.txt +++ b/dep/PackageList.txt @@ -20,10 +20,6 @@ libMPQ (a library for reading MPQ files) https://libmpq.org/ Version: 1.0.4 -MersenneTwister (a very fast random number generator) - http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html - Version: 0.4.2 - MySQL (the world's most popular open source database software) http://www.mysql.com/ Version: 5.5.9 (GA) diff --git a/dep/mersennetwister/MersenneTwister.h b/dep/mersennetwister/MersenneTwister.h deleted file mode 100644 index 1cff879643f..00000000000 --- a/dep/mersennetwister/MersenneTwister.h +++ /dev/null @@ -1,405 +0,0 @@ -// MersenneTwister.h -// Mersenne Twister random number generator -- a C++ class MTRand -// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus -// Richard J. Wagner v1.0 15 May 2003 rjwagner@writeme.com - -// The Mersenne Twister is an algorithm for generating random numbers. It -// was designed with consideration of the flaws in various other generators. -// The period, 2^19937-1, and the order of equidistribution, 623 dimensions, -// are far greater. The generator is also fast; it avoids multiplication and -// division, and it benefits from caches and pipelines. For more information -// see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html - -// Reference -// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally -// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on -// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. - -// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, -// Copyright (C) 2000 - 2003, Richard J. Wagner -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The names of its contributors may not be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The original code included the following notice: -// -// When you use this, send an email to: matumoto@math.keio.ac.jp -// with an appropriate reference to your work. -// -// It would be nice to CC: rjwagner@writeme.com and Cokus@math.washington.edu -// when you write. - -#ifndef MERSENNETWISTER_H -#define MERSENNETWISTER_H - -// Not thread safe (unless auto-initialization is avoided and each thread has -// its own MTRand object) - -#include"Define.h" - -#include <limits.h> -#include <time.h> -#include <math.h> - -class MTRand { -// Data -public: - typedef ::uint32 uint32; - enum { N = 624 }; // length of state vector - enum { SAVE = N + 1 }; // length of array for save() - -protected: - enum { M = 397 }; // period parameter - - uint32 state[N]; // internal state - uint32 *pNext; // next value to get from state - int left; // number of values left before reload needed - -//Methods -public: - MTRand( const uint32& oneSeed ); // initialize with a simple uint32 - MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array - MTRand(); // auto-initialize with /dev/urandom or time() and clock() - MTRand(const MTRand&); // prevent copy constructor - MTRand& operator=(const MTRand&); // no-op operator= - - // Do NOT use for CRYPTOGRAPHY without securely hashing several returned - // values together, otherwise the generator state can be learned after - // reading 624 consecutive values. - - // Access to 32-bit random numbers - double rand(); // real number in [0,1] - double rand( const double& n ); // real number in [0,n] - double randExc(); // real number in [0,1) - double randExc( const double& n ); // real number in [0,n) - double randDblExc(); // real number in (0,1) - double randDblExc( const double& n ); // real number in (0,n) - uint32 randInt(); // integer in [0,2^32-1] - uint32 randInt( const uint32& n ); // integer in [0,n] for n < 2^32 - double operator()() { return rand(); } // same as rand() - - // Access to 53-bit random numbers (capacity of IEEE double precision) - double rand53(); // real number in [0,1) - - // Access to nonuniform random number distributions - double randNorm( const double& mean = 0.0, const double& variance = 0.0 ); - - // Re-seeding functions with same behavior as initializers - void seed( const uint32 oneSeed ); - void seed( uint32 *const bigSeed, const uint32 seedLength = N ); - void seed(); - - // Saving and loading generator state - void save( uint32* saveArray ) const; // to array of size SAVE - void load( uint32 *const loadArray ); // from such array - /* Trinity not use streams for random values output - friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ); - friend std::istream& operator>>( std::istream& is, MTRand& mtrand ); - */ -protected: - void initialize( const uint32 oneSeed ); - void reload(); - uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; } - uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; } - uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; } - uint32 mixBits( const uint32& u, const uint32& v ) const - { return hiBit(u) | loBits(v); } - uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const - { return m ^ (mixBits(s0,s1)>>1) ^ uint32(-(int32)(loBit(s1) & 0x9908b0dfUL)); } - static uint32 hash( time_t t, clock_t c ); -}; - -inline MTRand::MTRand(const MTRand&) - { seed(); } - -inline MTRand& MTRand::operator=(const MTRand&) - { return *this; } - -inline MTRand::MTRand( const uint32& oneSeed ) - { seed(oneSeed); } - -inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength ) - { seed(bigSeed,seedLength); } - -inline MTRand::MTRand() - { seed(); } - -inline double MTRand::rand() - { return double(randInt()) * (1.0/4294967295.0); } - -inline double MTRand::rand( const double& n ) - { return rand() * n; } - -inline double MTRand::randExc() - { return double(randInt()) * (1.0/4294967296.0); } - -inline double MTRand::randExc( const double& n ) - { return randExc() * n; } - -inline double MTRand::randDblExc() - { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); } - -inline double MTRand::randDblExc( const double& n ) - { return randDblExc() * n; } - -inline double MTRand::rand53() -{ - uint32 a = randInt() >> 5, b = randInt() >> 6; - return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada -} - -inline double MTRand::randNorm( const double& mean, const double& variance ) -{ - // Return a real number from a normal (Gaussian) distribution with given - // mean and variance by Box-Muller method - double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance; - double phi = 2.0 * 3.14159265358979323846264338328 * randExc(); - return mean + r * cos(phi); -} - -inline MTRand::uint32 MTRand::randInt() -{ - // Pull a 32-bit integer from the generator state - // Every other access function simply transforms the numbers extracted here - - if( left == 0 ) reload(); - --left; - - register uint32 s1; - s1 = *pNext++; - s1 ^= (s1 >> 11); - s1 ^= (s1 << 7) & 0x9d2c5680UL; - s1 ^= (s1 << 15) & 0xefc60000UL; - return ( s1 ^ (s1 >> 18) ); -} - -inline MTRand::uint32 MTRand::randInt( const uint32& n ) -{ - // Find which bits are used in n - // Optimized by Magnus Jonsson (magnus@smartelectronix.com) - uint32 used = n; - used |= used >> 1; - used |= used >> 2; - used |= used >> 4; - used |= used >> 8; - used |= used >> 16; - - // Draw numbers until one is found in [0,n] - uint32 i; - do - i = randInt() & used; // toss unused bits to shorten search - while( i > n ); - return i; -} - -inline void MTRand::seed( const uint32 oneSeed ) -{ - // Seed the generator with a simple uint32 - initialize(oneSeed); - reload(); -} - -inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength ) -{ - // Seed the generator with an array of uint32's - // There are 2^19937-1 possible initial states. This function allows - // all of those to be accessed by providing at least 19937 bits (with a - // default seed length of N = 624 uint32's). Any bits above the lower 32 - // in each element are discarded. - // Just call seed() if you want to get array from /dev/urandom - initialize(19650218UL); - register int i = 1; - register uint32 j = 0; - register int k = ( N > int(seedLength) ? N : int(seedLength) ); - for (; k; --k ) - { - state[i] = - state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL ); - state[i] += ( bigSeed[j] & 0xffffffffUL ) + j; - state[i] &= 0xffffffffUL; - ++i; ++j; - if( i >= N ) { state[0] = state[N-1]; i = 1; } - if( j >= seedLength ) j = 0; - } - for (k = N - 1; k; --k ) - { - state[i] = - state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL ); - state[i] -= i; - state[i] &= 0xffffffffUL; - ++i; - if( i >= N ) { state[0] = state[N-1]; i = 1; } - } - state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array - reload(); -} - -inline void MTRand::seed() -{ - // Seed the generator with hash of time() and clock() values - seed( hash( time(NULL), clock() ) ); -} - -inline void MTRand::initialize( const uint32 seed ) -{ - // Initialize generator state with seed - // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. - // In previous versions, most significant bits (MSBs) of the seed affect - // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. - register uint32 *s = state; - register uint32 *r = state; - register int i = 1; - *s++ = seed & 0xffffffffUL; - for (; i < N; ++i ) - { - *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL; - r++; - } -} - -inline void MTRand::reload() -{ - // Generate N new values in state - // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) - register uint32 *p = state; - register int i; - for (i = N - M; i--; ++p ) - *p = twist( p[M], p[0], p[1] ); - for (i = M; --i; ++p ) - *p = twist( p[M-N], p[0], p[1] ); - *p = twist( p[M-N], p[0], state[0] ); - - left = N, pNext = state; -} - -inline MTRand::uint32 MTRand::hash( time_t t, clock_t c ) -{ - // Get a uint32 from t and c - // Better than uint32(x) in case x is floating point in [0,1] - // Based on code by Lawrence Kirby (fred@genesis.demon.co.uk) - - static uint32 differ = 0; // guarantee time-based seeds will change - - uint32 h1 = 0; - unsigned char *p = (unsigned char *) &t; - for (size_t i = 0; i < sizeof(t); ++i ) - { - h1 *= UCHAR_MAX + 2U; - h1 += p[i]; - } - uint32 h2 = 0; - p = (unsigned char *) &c; - for (size_t j = 0; j < sizeof(c); ++j ) - { - h2 *= UCHAR_MAX + 2U; - h2 += p[j]; - } - return ( h1 + differ++ ) ^ h2; -} - -inline void MTRand::save( uint32* saveArray ) const -{ - register uint32 *sa = saveArray; - register const uint32 *s = state; - register int i = N; - for (; i--; *sa++ = *s++ ) {} - *sa = left; -} - -inline void MTRand::load( uint32 *const loadArray ) -{ - register uint32 *s = state; - register uint32 *la = loadArray; - register int i = N; - for (; i--; *s++ = *la++ ) {} - left = *la; - pNext = &state[N-left]; -} - -/* Trinity not use streams for random values output -inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ) -{ - register const MTRand::uint32 *s = mtrand.state; - register int i = mtrand.N; - for (; i--; os << *s++ << "\t" ) {} - return os << mtrand.left; -} - -inline std::istream& operator>>( std::istream& is, MTRand& mtrand ) -{ - register MTRand::uint32 *s = mtrand.state; - register int i = mtrand.N; - for (; i--; is >> *s++ ) {} - is >> mtrand.left; - mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left]; - return is; -} -*/ - -#endif // MERSENNETWISTER_H - -// Change log: -// -// v0.1 - First release on 15 May 2000 -// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus -// - Translated from C to C++ -// - Made completely ANSI compliant -// - Designed convenient interface for initialization, seeding, and -// obtaining numbers in default or user-defined ranges -// - Added automatic seeding from /dev/urandom or time() and clock() -// - Provided functions for saving and loading generator state -// -// v0.2 - Fixed bug which reloaded generator one step too late -// -// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew -// -// v0.4 - Removed trailing newline in saved generator format to be consistent -// with output format of built-in types -// -// v0.5 - Improved portability by replacing static const int's with enum's and -// clarifying return values in seed(); suggested by Eric Heimburg -// - Removed MAXINT constant; use 0xffffffffUL instead -// -// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits -// - Changed integer [0,n] generator to give better uniformity -// -// v0.7 - Fixed operator precedence ambiguity in reload() -// - Added access for real numbers in (0,1) and (0,n) -// -// v0.8 - Included time.h header to properly support time_t and clock_t -// -// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto -// - Allowed for seeding with arrays of any length -// - Added access for real numbers in [0,1) with 53-bit resolution -// - Added access for real numbers from normal (Gaussian) distributions -// - Increased overall speed by optimizing twist() -// - Doubled speed of integer [0,n] generation -// - Fixed out-of-range number generation on 64-bit machines -// - Improved portability by substituting literal constants for long enum's -// - Changed license from GNU LGPL to BSD - diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql index 3a9bd6fb08b..305ba679bf2 100644 --- a/sql/base/auth_database.sql +++ b/sql/base/auth_database.sql @@ -1,8 +1,8 @@ --- MySQL dump 10.13 Distrib 5.5.19, for Win64 (x86) +-- MySQL dump 10.13 Distrib 5.5.21, for Win64 (x86) -- -- Host: localhost Database: auth -- ------------------------------------------------------ --- Server version 5.5.19 +-- Server version 5.5.21 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -88,8 +88,8 @@ DROP TABLE IF EXISTS `account_banned`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `account_banned` ( `id` int(11) NOT NULL DEFAULT '0' COMMENT 'Account id', - `bandate` bigint(40) NOT NULL DEFAULT '0', - `unbandate` bigint(40) NOT NULL DEFAULT '0', + `bandate` int(10) unsigned NOT NULL DEFAULT '0', + `unbandate` int(10) unsigned NOT NULL DEFAULT '0', `bannedby` varchar(50) NOT NULL, `banreason` varchar(255) NOT NULL, `active` tinyint(4) NOT NULL DEFAULT '1', @@ -114,9 +114,9 @@ DROP TABLE IF EXISTS `ip_banned`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `ip_banned` ( - `ip` varchar(32) NOT NULL DEFAULT '127.0.0.1', - `bandate` bigint(40) NOT NULL, - `unbandate` bigint(40) NOT NULL, + `ip` varchar(15) NOT NULL DEFAULT '127.0.0.1', + `bandate` int(10) unsigned NOT NULL, + `unbandate` int(10) unsigned NOT NULL, `bannedby` varchar(50) NOT NULL DEFAULT '[Console]', `banreason` varchar(255) NOT NULL DEFAULT 'no reason', PRIMARY KEY (`ip`,`bandate`) @@ -194,7 +194,7 @@ CREATE TABLE `realmlist` ( `address` varchar(32) NOT NULL DEFAULT '127.0.0.1', `port` int(11) NOT NULL DEFAULT '8085', `icon` tinyint(3) unsigned NOT NULL DEFAULT '0', - `color` tinyint(3) unsigned NOT NULL DEFAULT '2', + `flag` tinyint(3) unsigned NOT NULL DEFAULT '2', `timezone` tinyint(3) unsigned NOT NULL DEFAULT '0', `allowedSecurityLevel` tinyint(3) unsigned NOT NULL DEFAULT '0', `population` float unsigned NOT NULL DEFAULT '0', @@ -250,4 +250,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2012-02-19 13:18:35 +-- Dump completed on 2012-03-26 18:21:51 diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index c38dced90dd..f0e919a5bcd 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -1,8 +1,8 @@ --- MySQL dump 10.13 Distrib 5.5.9, for Win64 (x86) +-- MySQL dump 10.13 Distrib 5.5.21, for Win64 (x86) -- -- Host: localhost Database: characters -- ------------------------------------------------------ --- Server version 5.5.9 +-- Server version 5.5.21 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -2270,3 +2270,5 @@ UNLOCK TABLES; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2012-03-25 21:14:19 diff --git a/sql/updates/auth/2012_03_25_00_auth_misc.sql b/sql/updates/auth/2012_03_25_00_auth_misc.sql new file mode 100644 index 00000000000..f34882af8f6 --- /dev/null +++ b/sql/updates/auth/2012_03_25_00_auth_misc.sql @@ -0,0 +1,8 @@ +ALTER TABLE `account_banned` + CHANGE `bandate` `bandate` INT(10) UNSIGNED DEFAULT 0 NOT NULL, + CHANGE `unbandate` `unbandate` INT(10) UNSIGNED DEFAULT 0 NOT NULL; + +ALTER TABLE `ip_banned` + CHANGE `ip` `ip` VARCHAR(15) CHARSET utf8 COLLATE utf8_general_ci DEFAULT '127.0.0.1' NOT NULL, + CHANGE `bandate` `bandate` INT(10) UNSIGNED NOT NULL, + CHANGE `unbandate` `unbandate` INT(10) UNSIGNED NOT NULL; diff --git a/sql/updates/auth/2012_03_26_00_auth_realmlist.sql b/sql/updates/auth/2012_03_26_00_auth_realmlist.sql new file mode 100644 index 00000000000..0a570a31773 --- /dev/null +++ b/sql/updates/auth/2012_03_26_00_auth_realmlist.sql @@ -0,0 +1,2 @@ +ALTER TABLE `realmlist` + CHANGE `color` `flag` tinyint(3) unsigned NOT NULL DEFAULT '2'; diff --git a/sql/updates/world/2012_03_19_00_world_smart_scripts.sql b/sql/updates/world/2012_03_19_00_world_smart_scripts.sql new file mode 100644 index 00000000000..20241efa9cc --- /dev/null +++ b/sql/updates/world/2012_03_19_00_world_smart_scripts.sql @@ -0,0 +1,21 @@ +-- SAI for Unrestrained Dragonhawk +UPDATE `creature_template` SET `AIName`='SmartAI',`ScriptName`='' WHERE `entry`=25236; +DELETE FROM `smart_scripts` WHERE (`entryorguid`=25236 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 +(25236,0,0,1,62,0,100,0,9143,0,0,0,11,45353,0,0,0,0,0,7,0,0,0,0,0,0,0,'Unrestrained Dragonhawk - On Gossip option select - cast "Quest - Sunwell Daily - Ship Bombing Run Return" on player'), +(25236,0,1,0,61,0,100,0,0,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Unrestrained Dragonhawk - On Gossip option select - Close Gossip'); +-- Unrestrained Dragonhawk Gossip +UPDATE `creature_template` SET `gossip_menu_id`=9143 WHERE `entry`=25236; +-- Gossip_menu from UDB +DELETE FROM `gossip_menu` WHERE `entry`=9143; +INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES +(9143,12371); +-- Gossip_menu_option Update from UDB +DELETE FROM `gossip_menu_option` WHERE `menu_id`=9143; +INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`) VALUES +(9143,0,0, '<Ride the dragonhawk to Sun''s Reach.>',1,1,0,0,0,0, ''); +-- Gossip option Conditions +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9143; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(15,9143,0,0,9,11542,0,0,0,'','Show gossip option if player has quest 11542 but not complete'), +(15,9143,0,1,9,11543,0,0,0,'','Show gossip option if player has quest 11543 but not complete'); diff --git a/sql/updates/world/2012_03_20_00_world_gossip.sql b/sql/updates/world/2012_03_20_00_world_gossip.sql new file mode 100644 index 00000000000..00214d805e7 --- /dev/null +++ b/sql/updates/world/2012_03_20_00_world_gossip.sql @@ -0,0 +1,88 @@ +-- Creature Gossip_menu_id Update from sniff +UPDATE `creature_template` SET `gossip_menu_id`=9052 WHERE `entry`=24965; -- Vindicator Xayann +UPDATE `creature_template` SET `gossip_menu_id`=9050 WHERE `entry`=24975; -- Mar'nah +UPDATE `creature_template` SET `gossip_menu_id`=9126 WHERE `entry`=25032; -- Eldara Dawnrunner +UPDATE `creature_template` SET `gossip_menu_id`=9087 WHERE `entry`=25046; -- Smith Hauthaa +UPDATE `creature_template` SET `gossip_menu_id`=9064 WHERE `entry`=25057; -- Battlemage Arynna +UPDATE `creature_template` SET `gossip_menu_id`=9062, `AIName`='SmartAI', `ScriptName`='' WHERE `entry`=25059; -- Ayren Cloudbreaker +UPDATE `creature_template` SET `gossip_menu_id`=9063 WHERE `entry`=25061; -- Harbinger Inuuro +UPDATE `creature_template` SET `gossip_menu_id`=9127 WHERE `entry`=25069; -- Magister Ilastar +UPDATE `creature_template` SET `gossip_menu_id`=9115 WHERE `entry`=25112; -- Anchorite Ayuri +UPDATE `creature_template` SET `gossip_menu_id`=9105 WHERE `entry`=25169; -- Archmage Ne'thul +UPDATE `creature_template` SET `gossip_menu_id`=9286 WHERE `entry`=25632; -- Vindicator Moorba +UPDATE `creature_template` SET `gossip_menu_id`=9285 WHERE `entry`=25638; -- Captain Selana +UPDATE `creature_template` SET `gossip_menu_id`=9198 WHERE `entry`=25950; -- Shaani + +-- Gossip Menu insert from sniff +DELETE FROM `gossip_menu` WHERE `entry`=9050 AND `text_id`=12237; +DELETE FROM `gossip_menu` WHERE `entry`=9052 AND `text_id`=12241; +DELETE FROM `gossip_menu` WHERE `entry`=9062 AND `text_id`=12252; +DELETE FROM `gossip_menu` WHERE `entry`=9063 AND `text_id`=12256; +DELETE FROM `gossip_menu` WHERE `entry`=9064 AND `text_id`=12258; +DELETE FROM `gossip_menu` WHERE `entry`=9087 AND `text_id`=12286; +DELETE FROM `gossip_menu` WHERE `entry`=9115 AND `text_id`=12323; +DELETE FROM `gossip_menu` WHERE `entry`=9126 AND `text_id`=12338; +DELETE FROM `gossip_menu` WHERE `entry`=9127 AND `text_id`=12340; +DELETE FROM `gossip_menu` WHERE `entry`=9198 AND `text_id`=12497; +DELETE FROM `gossip_menu` WHERE `entry`=9285 AND `text_id`=12596; +DELETE FROM `gossip_menu` WHERE `entry`=9286 AND `text_id`=12597; +DELETE FROM `gossip_menu` WHERE `entry`=9287 AND `text_id`=12598; +DELETE FROM `gossip_menu` WHERE `entry`=9288 AND `text_id`=12599; +DELETE FROM `gossip_menu` WHERE `entry`=9289 AND `text_id`=12600; +DELETE FROM `gossip_menu` WHERE `entry`=9290 AND `text_id`=12601; +DELETE FROM `gossip_menu` WHERE `entry`=9293 AND `text_id`=12604; +INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES +(9050,12237), +(9052,12241), +(9062,12252), +(9063,12256), +(9064,12258), +(9087,12286), +(9115,12323), +(9126,12338), +(9127,12340), +(9198,12497), +(9285,12596), +(9286,12597), +(9287,12598), +(9288,12599), +(9289,12600), +(9290,12601), +(9293,12604); + +-- Creature Gossip_menu_option insert from sniff +DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (9050,9087,9126,9198,9285,9287,9288,9289) AND `id`=0; +DELETE FROM `gossip_menu_option` WHERE `menu_id`=9062 AND `id` IN (0,1); +DELETE FROM `gossip_menu_option` WHERE `menu_id`=9286 AND `id`=2; +INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`,`option_text`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`)VALUES +(9050,0,1,'Let me browse your goods.',3,128,0,0,0,0,''), +(9062,0,0,'Speaking of action, I''ve been ordered to undertake an air strike.',1,1,0,0,0,0,''), +(9062,1,0,'I need to intercept the Dawnblade reinforcements.',1,1,0,0,0,0,''), +(9087,0,1,'Let me browse your goods.',3,128,0,0,0,0,''), +(9126,0,1,'Let me browse your goods.',3,128,0,0,0,0,''), +(9198,0,1,'Let me browse your goods.',3,128,0,0,0,0,''), +(9285,0,0,'Give me a situation report, Captain.',1,1,9287,0,0,0,''), +(9286,2,0,'What is the current state of the Sunwell''s Gates?',1,1,9293,0,0,0,''), +(9287,0,0,'What went wrong?',1,1,9288,0,0,0,''), +(9288,0,0,'Why did they stop?',1,1,9289,0,0,0,''), +(9289,0,0,'Your insight is appreciated.',1,1,9290,0,0,0,''); + +-- Conditions +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9062 AND `SourceEntry` IN (0,1); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(15,9062,0,0,0,9,11532,0,0,0,0,'','Show gossip option only if player has taken quest 11532'), +(15,9062,0,0,1,9,11533,0,0,0,0,'','Show gossip option only if player has taken quest 11533'), +(15,9062,1,0,0,9,11542,0,0,0,0,'','Show gossip option only if player has taken quest 11542'), +(15,9062,1,0,1,9,11543,0,0,0,0,'','Show gossip option only if player has taken quest 11543'); + +-- SmartAI +DELETE FROM `smart_scripts` WHERE `entryorguid`=25059 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 +(25059,0,0,2,62,0,100,0,9062,0,0,0,11,45071,0,0,0,0,0,7,0,0,0,0,0,0,0,'Ayren Cloudbreaker - On Gossip option select - Cast "Quest - Sunwell Daily - Dead Scar Bombing Run" on player'), +(25059,0,1,2,62,0,100,0,9062,1,0,0,11,45113,0,0,0,0,0,7,0,0,0,0,0,0,0,'Ayren Cloudbreaker - On Gossip option select - Cast "Quest - Sunwell Daily - Ship Bombing Run" on player'), +(25059,0,2,0,61,0,100,0,0,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Ayren Cloudbreaker - On Gossip option select - Close Gossip'); + +-- Spell scripts from sniff +DELETE FROM `spell_scripts` WHERE `id`=45071; +INSERT INTO `spell_scripts` (`id`,`effIndex`,`delay`,`command`,`datalong`,`datalong2`,`dataint`,`x`,`y`,`z`,`o`) VALUES +(45071,2,0,16,12318,1,0,0,0,0,0); -- Play sound diff --git a/sql/updates/world/2012_03_21_00_world_creature.sql b/sql/updates/world/2012_03_21_00_world_creature.sql new file mode 100644 index 00000000000..def72f74cd6 --- /dev/null +++ b/sql/updates/world/2012_03_21_00_world_creature.sql @@ -0,0 +1,71 @@ +-- ToC missing trigger spawns + +SET @GUID := 88412; +SET @NPC_TRIGGER1 := 34704; -- Val'kyr Twins Bullet Stalker Dark +SET @NPC_TRIGGER2 := 34720; -- Val'kyr Twins Bullet Stalker Light + +UPDATE `creature_template` SET `flags_extra`=128 WHERE `entry` IN (@NPC_TRIGGER1,@NPC_TRIGGER2); +DELETE FROM `creature` WHERE `guid` BETWEEN @GUID+0 AND @GUID+61; +INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`) VALUES +(@GUID+0,@NPC_TRIGGER1,649,15,1,0,0,619.771,143.71,395.244,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+1,@NPC_TRIGGER1,649,15,1,0,0,515.352,115.349,395.288,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+2,@NPC_TRIGGER1,649,15,1,0,0,605.514,103.863,395.29,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+3,@NPC_TRIGGER1,649,15,1,0,0,615.137,156.997,395.28,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+4,@NPC_TRIGGER1,649,15,1,0,0,539.179,184.132,395.282,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+5,@NPC_TRIGGER1,649,15,1,0,0,547.76,184.634,395.289,2.93215,7200,0,0,1,0,0,0,0,0), +(@GUID+6,@NPC_TRIGGER1,649,15,1,0,0,549.764,86.4444,395.266,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+7,@NPC_TRIGGER1,649,15,1,0,0,511.417,127.158,395.266,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+8,@NPC_TRIGGER1,649,15,1,0,0,597.38,183.672,395.28,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+9,@NPC_TRIGGER1,649,15,1,0,0,573.578,187.665,395.492,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+10,@NPC_TRIGGER1,649,15,1,0,0,620.465,134.66,395.233,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+11,@NPC_TRIGGER1,649,15,1,0,0,560.484,187.743,395.959,2.93215,7200,0,0,1,0,0,0,0,0), +(@GUID+12,@NPC_TRIGGER1,649,15,1,0,0,577.299,186.854,395.289,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+13,@NPC_TRIGGER1,649,15,1,0,0,563.467,81.9323,395.288,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+14,@NPC_TRIGGER1,649,15,1,0,0,534.748,92.6424,395.289,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+15,@NPC_TRIGGER1,649,15,1,0,0,518.503,170.649,395.289,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+16,@NPC_TRIGGER1,649,15,1,0,0,514.566,159.918,395.287,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+17,@NPC_TRIGGER1,649,15,1,0,0,568.049,187.67,395.563,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+18,@NPC_TRIGGER1,649,15,1,0,0,522.955,102.127,395.29,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+19,@NPC_TRIGGER1,649,15,1,0,0,611.656,114.281,395.288,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+20,@NPC_TRIGGER1,649,15,1,0,0,616.432,126.418,395.264,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+21,@NPC_TRIGGER1,649,15,1,0,0,526.833,181.783,395.285,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+22,@NPC_TRIGGER1,649,15,1,0,0,578.722,87.4444,395.272,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+23,@NPC_TRIGGER1,649,15,1,0,0,509.743,149.005,395.253,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+24,@NPC_TRIGGER1,649,15,1,0,0,592.736,93.6667,395.289,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+25,@NPC_TRIGGER1,649,15,1,0,0,506.038,139.517,395.288,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+26,@NPC_TRIGGER1,649,15,1,0,0,608.116,171.731,395.289,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+27,@NPC_TRIGGER1,649,15,1,0,0,586.344,184.078,395.283,4.60767,7200,0,0,1,0,0,0,0,0), +(@GUID+28,@NPC_TRIGGER1,649,15,1,0,0,554.818,187.568,395.288,2.93215,7200,0,0,1,0,0,0,0,0), +(@GUID+29,@NPC_TRIGGER2,649,15,1,0,0,557.743,187.729,395.915,0,7200,0,0,1,0,0,0,0,0), +(@GUID+30,@NPC_TRIGGER2,649,15,1,0,0,544.094,184.648,395.286,0,7200,0,0,1,0,0,0,0,0), +(@GUID+31,@NPC_TRIGGER2,649,15,1,0,0,551.328,187.646,395.596,0,7200,0,0,1,0,0,0,0,0), +(@GUID+32,@NPC_TRIGGER2,649,15,1,0,0,615.137,150.818,395.269,0,7200,0,0,1,0,0,0,0,0), +(@GUID+33,@NPC_TRIGGER2,649,15,1,0,0,571.158,187.691,395.629,0,7200,0,0,1,0,0,0,0,0), +(@GUID+34,@NPC_TRIGGER2,649,15,1,0,0,606.686,106.731,395.289,0,7200,0,0,1,0,0,0,0,0), +(@GUID+35,@NPC_TRIGGER2,649,15,1,0,0,612.118,118.844,395.287,0,7200,0,0,1,0,0,0,0,0), +(@GUID+36,@NPC_TRIGGER2,649,15,1,0,0,546.057,88.7691,395.284,0,7200,0,0,1,0,0,0,0,0), +(@GUID+37,@NPC_TRIGGER2,649,15,1,0,0,517.722,169.069,395.289,0,7200,0,0,1,0,0,0,0,0), +(@GUID+38,@NPC_TRIGGER2,649,15,1,0,0,507.181,142.285,395.255,0,7200,0,0,1,0,0,0,0,0), +(@GUID+39,@NPC_TRIGGER2,649,15,1,0,0,515.399,159.75,395.287,0,7200,0,0,1,0,0,0,0,0), +(@GUID+40,@NPC_TRIGGER2,649,15,1,0,0,592.151,183.8,395.279,0,7200,0,0,1,0,0,0,0,0), +(@GUID+41,@NPC_TRIGGER2,649,15,1,0,0,510.759,127.333,395.263,0,7200,0,0,1,0,0,0,0,0), +(@GUID+42,@NPC_TRIGGER2,649,15,1,0,0,524.257,178.134,395.29,0,7200,0,0,1,0,0,0,0,0), +(@GUID+43,@NPC_TRIGGER2,649,15,1,0,0,570.779,86.2986,395.253,0,7200,0,0,1,0,0,0,0,0), +(@GUID+44,@NPC_TRIGGER2,649,15,1,0,0,588.675,93.0938,395.289,0,7200,0,0,1,0,0,0,0,0), +(@GUID+45,@NPC_TRIGGER2,649,15,1,0,0,603.528,175.476,395.289,0,7200,0,0,1,0,0,0,0,0), +(@GUID+46,@NPC_TRIGGER2,649,15,1,0,0,509.639,133.26,395.247,0,7200,0,0,1,0,0,0,0,0), +(@GUID+47,@NPC_TRIGGER2,649,15,1,0,0,618.965,139.174,395.288,0,7200,0,0,1,0,0,0,0,0), +(@GUID+48,@NPC_TRIGGER2,649,15,1,0,0,514.785,118.731,395.287,0,7200,0,0,1,0,0,0,0,0), +(@GUID+49,@NPC_TRIGGER2,649,15,1,0,0,581.243,184.062,395.287,0,7200,0,0,1,0,0,0,0,0), +(@GUID+50,@NPC_TRIGGER2,649,15,1,0,0,577.757,184.436,395.289,0,7200,0,0,1,0,0,0,0,0), +(@GUID+51,@NPC_TRIGGER2,649,15,1,0,0,580.486,89.691,395.287,0,7200,0,0,1,0,0,0,0,0), +(@GUID+52,@NPC_TRIGGER2,649,15,1,0,0,511.132,151.156,395.264,0,7200,0,0,1,0,0,0,0,0), +(@GUID+53,@NPC_TRIGGER2,649,15,1,0,0,615.401,130.816,395.263,0,7200,0,0,1,0,0,0,0,0), +(@GUID+54,@NPC_TRIGGER2,649,15,1,0,0,599.307,98.8003,395.29,0,7200,0,0,1,0,0,0,0,0), +(@GUID+55,@NPC_TRIGGER2,649,15,1,0,0,520.212,108.429,395.289,0,7200,0,0,1,0,0,0,0,0), +(@GUID+56,@NPC_TRIGGER2,649,15,1,0,0,610.983,164.696,395.288,0,7200,0,0,1,0,0,0,0,0), +(@GUID+57,@NPC_TRIGGER2,649,15,1,0,0,526.337,99.5556,395.29,0,7200,0,0,1,0,0,0,0,0), +(@GUID+58,@NPC_TRIGGER2,649,15,1,0,0,563.997,187.644,395.489,0,7200,0,0,1,0,0,0,0,0), +(@GUID+59,@NPC_TRIGGER2,649,15,1,0,0,555.695,86.0208,395.253,0,7200,0,0,1,0,0,0,0,0), +(@GUID+60,@NPC_TRIGGER2,649,15,1,0,0,535.924,184.207,395.279,0,7200,0,0,1,0,0,0,0,0), +(@GUID+61,@NPC_TRIGGER2,649,15,1,0,0,538.024,92.441,395.289,0,7200,0,0,1,0,0,0,0,0); diff --git a/sql/updates/world/2012_03_22_00_world_creature_template.sql b/sql/updates/world/2012_03_22_00_world_creature_template.sql new file mode 100644 index 00000000000..e6c03ed589c --- /dev/null +++ b/sql/updates/world/2012_03_22_00_world_creature_template.sql @@ -0,0 +1,2 @@ +-- Flame Sphere should not be visible to players(only their visual) +UPDATE `creature_template` SET `flags_extra`=128 WHERE `entry` IN (30106,31686,31687); diff --git a/sql/updates/world/2012_03_22_01_world_conditions.sql b/sql/updates/world/2012_03_22_01_world_conditions.sql new file mode 100644 index 00000000000..074328137a5 --- /dev/null +++ b/sql/updates/world/2012_03_22_01_world_conditions.sql @@ -0,0 +1,2 @@ +-- Manual: Heavy Frostweave Bandage should be lootable if you have at least 390 skills in First Aid +UPDATE `conditions` SET `ConditionValue2`=390 WHERE `SourceTypeOrReferenceId`=1 AND `SourceEntry`=39152 AND `ConditionTypeOrReference`=7 AND `ConditionValue1`=129; diff --git a/sql/updates/world/2012_03_23_00_world_ip2nation.sql b/sql/updates/world/2012_03_23_00_world_ip2nation.sql new file mode 100644 index 00000000000..dadeaddf85a --- /dev/null +++ b/sql/updates/world/2012_03_23_00_world_ip2nation.sql @@ -0,0 +1,21 @@ +DROP TABLE IF EXISTS ip2nation; + +CREATE TABLE ip2nation ( + ip int(11) unsigned NOT NULL default '0', + country char(2) NOT NULL default '', + KEY ip (ip) +); + +DROP TABLE IF EXISTS ip2nationCountries; + +CREATE TABLE ip2nationCountries ( + code varchar(4) NOT NULL default '', + iso_code_2 varchar(2) NOT NULL default '', + iso_code_3 varchar(3) default '', + iso_country varchar(255) NOT NULL default '', + country varchar(255) NOT NULL default '', + lat float NOT NULL default '0', + lon float NOT NULL default '0', + PRIMARY KEY (code), + KEY code (code) +); diff --git a/sql/updates/world/2012_03_24_00_world_misc.sql b/sql/updates/world/2012_03_24_00_world_misc.sql new file mode 100644 index 00000000000..e6f6ce77307 --- /dev/null +++ b/sql/updates/world/2012_03_24_00_world_misc.sql @@ -0,0 +1,22 @@ +-- Beam Visual +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=60342; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(13,1,60342,0,0,31,0,3,29308,0,0,0,'','Beam Visual target Prince Taldaram'); + +-- script texts for Prince Taldaram +DELETE FROM `creature_text` WHERE `entry`=29308; +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES +(29308,0,0,'The hum of magic energy in the air diminishes...',16,0,100,0,0,0,'prince taldaram SAY_1'), +(29308,1,0,'Intruders! Who trespasses in the Old Kingdom?',14,0,100,0,0,0,'prince taldaram SAY_WARNING'), +(29308,2,0,'I will feast on your remains.',14,0,100,0,0,14360,'prince taldaram SAY_AGGRO'), +(29308,3,0,'',14,10,100,0,0,14365,'prince taldaram SAY_SLAY_0'), +(29308,3,1,'I will drink no blood before it''s time.',14,0,100,0,0,14366,'prince taldaram SAY_SLAY_1'), +(29308,3,2,'One final embrace.',14,0,100,0,0,14367,'prince taldaram SAY_SLAY_2'), +(29308,4,0,'Still I hunger. Still... I... thirst.',14,0,100,0,0,14368,'prince taldaram SAY_DEATH'), +(29308,5,0,'So... appetizing.',14,0,100,0,0,14363,'prince taldaram SAY_FEED1'), +(29308,5,1,'Fresh, warm blood. It has been too long.',14,0,100,0,0,14364,'prince taldaram SAY_FEED2'), +(29308,6,0,'Your heartbeat is... music to my ears.',14,0,100,0,0,14361,'prince taldaram SAY_VANISH1'), +(29308,6,1,'I am nowhere... I am everywhere. I am the watcher, unseen.',14,0,100,0,0,14362,'prince taldaram SAY_VANISH2'); + +-- cleanup +DELETE FROM `script_texts` WHERE `npc_entry`=29308; diff --git a/sql/updates/world/2012_03_24_01_world_creature_loot_template.sql b/sql/updates/world/2012_03_24_01_world_creature_loot_template.sql new file mode 100644 index 00000000000..078c48a47b7 --- /dev/null +++ b/sql/updates/world/2012_03_24_01_world_creature_loot_template.sql @@ -0,0 +1,290 @@ +-- ----------------------------------- +-- -- Loot for The Siege of Ulduar -- +-- ----------------------------------- + +-- Old Cleanups: +DELETE FROM `reference_loot_template` WHERE `entry` IN ( 34116,34117,34118,34119,34120,34121,34157,34158,34159,34160,34161,34162); +-- ------------------- +-- -- Set Variables -- +-- ------------------- +-- 10 man mode npcids +SET @FlameLevi10 :=33113; +SET @IgnisFM10 :=33118; +SET @Razorscale10 :=33186; +SET @XT002_10 :=33293; +-- 25 man mode npcids (via procedure) +call `sp_get_npc_diffentry`(@FlameLevi10,1,@FlameLevi25); +call `sp_get_npc_diffentry`(@IgnisFM10,1,@IgnisFM25); +call `sp_get_npc_diffentry`(@Razorscale10,1,@Razorscale25); +call `sp_get_npc_diffentry`(@XT002_10,1,@XT002_25); + +SET @Emblem := 47241; +SET @Orb := 45087; +-- ------------------------------------- +-- -- Set Reference Loot Template ids -- +-- ------------------------------------- + +SET @EmblemRef := 34349; -- First Free ID +SET @OrbRef := @EmblemRef+1; +SET @Flame10Ref := @EmblemRef+2; +SET @Flame25Ref := @EmblemRef+3; +SET @Ignis10Ref := @EmblemRef+4; +SET @Ignis25Ref := @EmblemRef+5; +SET @Razor10Ref := @EmblemRef+6; +SET @Razor25Ref := @EmblemRef+7; +SET @XT002_10Ref := @EmblemRef+8; +SET @XT002_25Ref := @EmblemRef+9; +-- Flame Levithian +DELETE FROM `reference_loot_template` WHERE `entry` BETWEEN @EmblemRef AND @EmblemRef+9; +INSERT INTO `reference_loot_template` (`entry`,`item`,`ChanceOrQuestChance`,`lootmode`,`groupid`,`mincountOrRef`,`maxcount`) VALUES +-- Emblem Ref +(@EmblemRef,47241,0,1,1,1,1), -- Emblem of Triumph 1x +-- OrbRef +(@OrbRef,45087,0,1,1,1,1), -- Runed Orb 1x +-- Flame Levithian 10man +(@Flame10Ref,45286,0,1,1,1,1), -- Pyrite Infuser +(@Flame10Ref,45287,0,1,1,1,1), -- Firesoul +(@Flame10Ref,45288,0,1,1,1,1), -- Firestrider Chestguard +(@Flame10Ref,45289,0,1,1,1,1), -- Lifespark Visage +(@Flame10Ref,45291,0,1,1,1,1), -- Combustion Bracers +(@Flame10Ref,45284,0,1,1,1,1), -- Kinetic Ripper +(@Flame10Ref,45282,0,1,1,1,1), -- Ironsoul +(@Flame10Ref,45285,0,1,1,1,1), -- Might of the Leviathan +(@Flame10Ref,45292,0,1,1,1,1), -- Energy Siphon +(@Flame10Ref,45283,0,1,1,1,1), -- Flamewatch Armguards +-- Flame Levithian 25man +(@Flame25Ref,45117,0,1,1,1,1), -- Constructors Handwraps +(@Flame25Ref,45119,0,1,1,1,1), -- Embrace of the Leviathan +(@Flame25Ref,45113,0,1,1,1,1), -- Glowing Ring of Reclamation +(@Flame25Ref,45115,0,1,1,1,1), -- Leviathan Fueling Manual +(@Flame25Ref,45108,0,1,1,1,1), -- Mechanists Bindings +(@Flame25Ref,45106,0,1,1,1,1), -- Strenght of the Automaton +(@Flame25Ref,45109,0,1,1,1,1), -- Gloves of the Fiery Behemoth +(@Flame25Ref,45114,0,1,1,1,1), -- Steamcallers Totem +(@Flame25Ref,45118,0,1,1,1,1), -- Steamworkers Goggles +(@Flame25Ref,45116,0,1,1,1,1), -- Freya's Choker of Warding +(@Flame25Ref,45111,0,1,1,1,1), -- Mimiron's Inferno Couplings +(@Flame25Ref,45112,0,1,1,1,1), -- The Leviathan's Coil +(@Flame25Ref,45107,0,1,1,1,1), -- Iron Riveted War Helm + +-- Ignis the Furnace Master 10man +(@Ignis10Ref,45309,0,1,1,1,1), -- Rifle of the Platinum Guard +(@Ignis10Ref,45310,0,1,1,1,1), -- Gauntlets of the Iron Furnace +(@Ignis10Ref,45311,0,1,1,1,1), -- Relentless Edge +(@Ignis10Ref,45312,0,1,1,1,1), -- Gloves of Smoldering Touch +(@Ignis10Ref,45313,0,1,1,1,1), -- Furnace Stone +(@Ignis10Ref,45314,0,1,1,1,1), -- Igniter Rod +(@Ignis10Ref,45316,0,1,1,1,1), -- Armbraces of the Vibrant Flame +(@Ignis10Ref,45317,0,1,1,1,1), -- Shawl of the Caretaker +(@Ignis10Ref,45318,0,1,1,1,1), -- Drape of Fuming Anger +(@Ignis10Ref,45321,0,1,1,1,1), -- Pauldrons of Tempered Will +-- Ignis the Furnace Master 25man +(@Ignis25Ref,45157,0,1,1,1,1), -- Cindershard Ring +(@Ignis25Ref,45158,0,1,1,1,1), -- Heart of Iron +(@Ignis25Ref,45161,0,1,1,1,1), -- Girdle of Embers +(@Ignis25Ref,45162,0,1,1,1,1), -- Flamestalker Boots +(@Ignis25Ref,45164,0,1,1,1,1), -- Helm of the Furnace Master +(@Ignis25Ref,45165,0,1,1,1,1), -- Worldcarver +(@Ignis25Ref,45166,0,1,1,1,1), -- Charred Saronite Greaves +(@Ignis25Ref,45167,0,1,1,1,1), -- Lifeforge Breastplate +(@Ignis25Ref,45168,0,1,1,1,1), -- Pyrelight Circle +(@Ignis25Ref,45169,0,1,1,1,1), -- Totem of the Dancing Flame +(@Ignis25Ref,45170,0,1,1,1,1), -- Scepter of Creation +(@Ignis25Ref,45171,0,1,1,1,1), -- Intensity +(@Ignis25Ref,45185,0,1,1,1,1), -- Flamewrought Cinch +(@Ignis25Ref,45186,0,1,1,1,1), -- Soot-Covered Mantle +(@Ignis25Ref,45187,0,1,1,1,1), -- Wristguards of the Firetender + +-- Razorscale 10man +(@Razor10Ref,45298,0,1,1,1,1), -- RazoRazorcale Talon +(@Razor10Ref,45299,0,1,1,1,1), -- Dragonsteel Faceplate +(@Razor10Ref,45301,0,1,1,1,1), -- BraceRazor of the Smothering Inferno +(@Razor10Ref,45302,0,1,1,1,1), -- Treads of the Invader +(@Razor10Ref,45303,0,1,1,1,1), -- Band of Draconic Guile +(@Razor10Ref,45304,0,1,1,1,1), -- Stormtempered Girdle +(@Razor10Ref,45305,0,1,1,1,1), -- Breastplate of the Afterlife +(@Razor10Ref,45306,0,1,1,1,1), -- Binding of the Dragon Matriarch +(@Razor10Ref,45307,0,1,1,1,1), -- Ironscale Leggings +(@Razor10Ref,45308,0,1,1,1,1), -- Eye of the Broodmother +-- Razorscale 25man +(@Razor25Ref,45137,0,1,1,1,1), -- Veranus' Bane +(@Razor25Ref,45138,0,1,1,1,1), -- Drape of the Drakerider +(@Razor25Ref,45139,0,1,1,1,1), -- Dragonslayer's Brace +(@Razor25Ref,45140,0,1,1,1,1), -- RazoRazorcale Shoulderguards +(@Razor25Ref,45141,0,1,1,1,1), -- Proto-hide Leggings +(@Razor25Ref,45142,0,1,1,1,1), -- RemoRazore +(@Razor25Ref,45143,0,1,1,1,1), -- Saronite Mesh Legguards +(@Razor25Ref,45144,0,1,1,1,1), -- Sigil of Deflection +(@Razor25Ref,45146,0,1,1,1,1), -- Shackles of the Odalisque +(@Razor25Ref,45147,0,1,1,1,1), -- Guiding Star +(@Razor25Ref,45148,0,1,1,1,1), -- Living Flame +(@Razor25Ref,45149,0,1,1,1,1), -- BraceRazor of the Broodmother +(@Razor25Ref,45150,0,1,1,1,1), -- Collar of the Wyrmhunter +(@Razor25Ref,45151,0,1,1,1,1), -- Belt of the Fallen Wyrm +(@Razor25Ref,45510,0,1,1,1,1), -- Libram of Discord + +-- XT-002 Deconstructor 10man +(@XT002_10Ref,45675,0,1,1,1,1), -- Power Enchancing Loop +(@XT002_10Ref,45676,0,1,1,1,1), -- Chestplate of Vicious Potency +(@XT002_10Ref,45677,0,1,1,1,1), -- Treacherous shoulderpads +(@XT002_10Ref,45679,0,1,1,1,1), -- Gloves of Taut grip +(@XT002_10Ref,45680,0,1,1,1,1), -- Armbands of the construct +(@XT002_10Ref,45682,0,1,1,1,1), -- Pulsing spellshield +(@XT002_10Ref,45685,0,1,1,1,1), -- Plasma Foil +(@XT002_10Ref,45686,0,1,1,1,1), -- Vest of the glowing Cresent +(@XT002_10Ref,45687,0,1,1,1,1), -- Helm of Veiled Energies +(@XT002_10Ref,45694,0,1,1,1,1), -- Conductive cord +(@XT002_10Ref,45867,0,2,2,1,1), -- Breasktplate of the Stoneshaper +(@XT002_10Ref,45868,0,2,2,1,1), -- Aesir's Edge +(@XT002_10Ref,45869,0,2,2,1,1), -- Fluxing Energy Coils +(@XT002_10Ref,45870,0,2,2,1,1), -- Magnetized Projectile Emitter +(@XT002_10Ref,45871,0,2,2,1,1), -- Seal of Ulduar +-- XT-002 Deconstructor 25man +(@XT002_25Ref,45254,0,1,1,1,1), -- Sigil of the Vengeful Heart +(@XT002_25Ref,45251,0,1,1,1,1), -- Shoulderplates of the Deconstructor +(@XT002_25Ref,45247,0,1,1,1,1), -- Signet of the Earthshaker +(@XT002_25Ref,45256,0,1,1,1,1), -- Twisted Visage +(@XT002_25Ref,45250,0,1,1,1,1), -- Crazed Construct Ring +(@XT002_25Ref,45257,0,1,1,1,1), -- Quartz Crystal Wand +(@XT002_25Ref,45260,0,1,1,1,1), -- Boots of Hasty Revival +(@XT002_25Ref,45252,0,1,1,1,1), -- Horologist's Wristguards +(@XT002_25Ref,45253,0,1,1,1,1), -- Mantle of Wavering Calm +(@XT002_25Ref,45258,0,1,1,1,1), -- Sandals of Rash Temperament +(@XT002_25Ref,45249,0,1,1,1,1), -- Brass-lined Boots +(@XT002_25Ref,45246,0,1,1,1,1), -- Golem-Shard Sticker +(@XT002_25Ref,45248,0,1,1,1,1), -- Clockwork Legplates +(@XT002_25Ref,45259,0,1,1,1,1), -- Quartz-studded Harness +(@XT002_25Ref,45255,0,1,1,1,1); -- Thunderfall Totem +-- ----------------------------------------------------------------------------------------------- +-- -- END OF REFERENCES -- -- END OF REFERENCES -- -- END OF REFERENCES -- -- END OF REFERENCES -- +-- -- END OF REFERENCES -- -- END OF REFERENCES -- -- END OF REFERENCES -- -- END OF REFERENCES -- +-- -- END OF REFERENCES -- -- END OF REFERENCES -- -- END OF REFERENCES -- -- END OF REFERENCES -- +-- ----------------------------------------------------------------------------------------------- + +-- Flame Levithian 10Man: +-- NORMAL MODE : 2x [Normal Loot Item] + 1x [Emblem of Valor] +-- ONE TOWER : 2x [Normal Loot Item] + 2x [Emblem of Conquest] + CHANCE TO [Recipe] +-- TWO TOWERS : 2x [Normal Loot Item] + 2x [Emblem of Conquest] + 1x [Runed Orb] + CHANCE TO [Recipe] +-- THREE TOWERS: 2x [Normal Loot Item] + 3x [Emblem of Conquest] + 1x [Runed Orb] + CHANCE TO [Recipe] + 1x [Recipe] +-- FOUR TOWERS : 2x [Normal Loot Item] + 3x [Emblem of Conquest] + 1x [Runed Orb] + CHANCE TO [Recipe] + 1x [Recipe] + 1x [Hard Loot Item] +-- Flame Levithian 25 man +-- NORMAL MODE : 3x [Normal Loot Item] + 1x [Emblem of Conquest] + CHANCE TO [Runed Orb] + CHANCE TO [Recipe] +-- ONE TOWER : 3x [Normal Loot Item] + 2x [Emblem of Conquest] + CHANCE TO [Runed Orb] + CHANCE TO [Recipe] +-- TWO TOWERS : 3x [Normal Loot Item] + 2x [Emblem of Conquest] + CHANCE TO [Runed Orb] + CHANCE TO [Recipe] + 2x [Runed Orb] +-- THREE TOWERS: 3x [Normal Loot Item] + 3x [Emblem of Conquest] + CHANCE TO [Runed Orb] + CHANCE TO [Recipe] + 2x [Runed Orb] + [Recipe] +-- FOUR TOWERS : 3x [Normal Loot Item] + 3x [Emblem of Conquest] + CHANCE TO [Runed Orb] + CHANCE TO [Recipe] + 2x [Runed Orb] + [Recipe] + 1x [Hard Loot Item] + +DELETE FROM `creature_loot_template` WHERE `entry` IN (@FlameLevi10,@FlameLevi25,@IgnisFM10,@IgnisFM25,@Razorscale10,@Razorscale25,@XT002_10,@XT002_25); +INSERT INTO `creature_loot_template` (`entry`,`item`,`ChanceOrQuestChance`,`lootmode`,`groupid`,`mincountOrRef`,`maxcount`) VALUES +-- --------------------------- +-- -- Flame Levithian 10man -- +-- --------------------------- +(@FlameLevi10,1,100,1,0,-@EmblemRef,1), -- 1x emblem +(@FlameLevi10,2,100,1,0,-@Flame10Ref,2), -- 2 from 10man reference +-- Hardmode: 1 tower left +(@FlameLevi10,3,100,2,0,-@EmblemRef,2), -- 2x emblem +(@FlameLevi10,4,100,2,0,-@Flame10Ref,2), -- 2 from 10man reference +-- Hardmode: 2 towers left +(@FlameLevi10,5,100,4,0,-@EmblemRef,2), -- 2x emblem +(@FlameLevi10,6,100,4,0,-@Flame10Ref,2), -- 2 from 10man reference +-- Hardmode: 3 towers left +(@FlameLevi10,7,100,8,0,-@EmblemRef,3), -- 3x emblem +(@FlameLevi10,8,100,8,0,-@Flame10Ref,2), -- 2 from 10man reference +-- Hardmode: 4 towers left +(@FlameLevi10,9,100,16,0,-@EmblemRef,3), -- 3x emblem +(@FlameLevi10,10,100,16,0,-@Flame10Ref,2), -- 2 from 10man reference +-- one from hardmodeloot: +(@FlameLevi10,45296,0,16,1,1,1), -- Twirling Blades +(@FlameLevi10,45293,0,16,1,1,1), -- Handguards of Potent Cures +(@FlameLevi10,45295,0,16,1,1,1), -- Gilded Steel Legplates +(@FlameLevi10,45300,0,16,1,1,1), -- Mantle of Fiery Vengeance +(@FlameLevi10,45297,0,16,1,1,1), -- Shimmering Seal +-- Shared Loot over the modes (masked) +-- Non-Normal (Modes 2|4|8|16) +(@FlameLevi10,11,5,30,0,-34154,1), -- 1 from recepies (chanced) +-- More then 1 tower up (Modes 4|8|16) +(@FlameLevi10,@Orb,100,28,0,1,3), -- Runed Orb (1-3) +-- More then 2 towers up (Modes 8|16) +(@FlameLevi10,12,100,24,0,-34154,1), -- 1 from recepies +-- --------------------------- +-- -- Flame Levithian 25man -- +-- --------------------------- +(@FlameLevi25,1,100,1,0,-@EmblemRef,1), -- 1x emblem +(@FlameLevi25,2,100,1,0,-@Flame25Ref,3), -- 3 from 25man reference +-- Hardmode: 1 tower left +(@FlameLevi25,3,100,2,0,-@EmblemRef,2), -- 2x emblem +(@FlameLevi25,4,100,2,0,-@Flame25Ref,3), -- 3 from 25man reference +-- Hardmode: 2 towers left +(@FlameLevi25,5,100,4,0,-@EmblemRef,2), -- 2x emblem +(@FlameLevi25,6,100,4,0,-@Flame25Ref,3), -- 3 from 25man reference +-- Hardmode: 3 towers left +(@FlameLevi25,7,100,8,0,-@EmblemRef,3), -- 3x emblem +(@FlameLevi25,8,100,8,0,-@Flame25Ref,3), -- 3 from 25man reference +-- Hardmode: 4 towers left +(@FlameLevi25,9,100,16,0,-@EmblemRef,3), -- 3x emblem +(@FlameLevi25,10,100,16,0,-@Flame25Ref,3), -- 3 from 25man reference +-- one from hardmodeloot: +(@FlameLevi25,45132,0,16,1,1,1), -- Golden Saronite Dragon +(@FlameLevi25,45133,0,16,1,1,1), -- Pendant of Fiery Havoc +(@FlameLevi25,45134,0,16,1,1,1), -- Plated Leggings of Ruination +(@FlameLevi25,45135,0,16,1,1,1), -- Boots of Fiery Resolution +(@FlameLevi25,45136,0,16,1,1,1), -- Shoulderpads of Dormant Energies +(@FlameLevi25,45086,0,16,1,1,1), -- Rising Sun +(@FlameLevi25,45110,0,16,1,1,1), -- Titanguard +-- Shared Loot over the modes (masked) +-- All Modes (1|2|4|8|16): +(@FlameLevi25,11,5,31,0,-@OrbRef,1), -- Runed Orb (1x Chanced) +(@FlameLevi25,45038,8,1,0,1,1), -- Fragment of Val'anyr (quest only!?) +(@FlameLevi25,12,5,31,0,-34154,1), -- 1 from recepies (chanced) +-- More then 1 tower up (Modes 4|8|16) +(@FlameLevi25,13,100,28,0,-@OrbRef,2), -- Runed Orb (2x garanteed) +-- More then 2 towers up (Modes 8|16) +(@FlameLevi25,14,100,24,0,-34154,1), -- 1 from recepies +-- ------------------------------ +-- -- IGNIS THE FURNACE MASTER -- +-- ------------------------------ +-- Ignis the Furnace Master 10man +(@IgnisFM10,1,100,1,0,-@Ignis10Ref,2), -- 2 items from Ref loot +(@IgnisFM10,@Emblem,100,1,0,1,1), -- 1 Emblem +-- Ignis the Furnace Master 25man +(@IgnisFM25,1,100,1,0,-@Ignis25Ref,3), -- 3 items from Ref loot +(@IgnisFM25,@Emblem,100,1,0,2,2), -- 2 Emblem +(@IgnisFM25,3,10,1,0,-34154,1), -- 1 from recepies +(@IgnisFM25,45038,8,1,0,1,1), -- Fragment of Val'anyr (quest only!?) +(@IgnisFM25,45087,75,1,0,1,1), -- Runed Orb +-- ---------------- +-- -- RAZORSCALE -- +-- ---------------- +-- Razorscale 10man +(@Razorscale10,1,100,1,0,-@Razor10Ref ,2), -- 2 items from ref loot +(@Razorscale10,@Emblem,100,1,0,1,1), -- Emblem of Triumph +-- Razorscale 25man +(@Razorscale25,1,100,1,0,-@Razor25Ref,3), -- 3 items from Ref loot +(@Razorscale25,@Emblem,100,1,0,1,2), -- 2 Emblems +(@Razorscale25,2,10,1,0,-34154,1), -- 1 from recepies +(@Razorscale25,45038,8,1,0,1,1), -- Fragment of Val'anyr (quest only!?) +(@Razorscale25,45087,75,1,0,1,1), -- Runed Orb +-- ------------------------- +-- -- XT002 DECONSTRUCTOR -- +-- ------------------------- +-- X002 Deconstructor 10man (and hardmode) +(@XT002_10,1,100,3,0,-@XT002_10Ref,2), -- 2items from Ref loot +(@XT002_10,@Emblem,100,3,0,1,1), -- 1x Emblem +-- Hard mode 10man only: +(@XT002_10,45442,0,2,1,1,1), -- Sorthalis,Hammer of the Watchers +(@XT002_10,45443,0,2,1,1,1), -- Charm of Meticulous Timing +(@XT002_10,45444,0,2,1,1,1), -- Gloves of the Steady Hand +(@XT002_10,45445,0,2,1,1,1), -- Breastplate of the Devoted +(@XT002_10,45446,0,2,1,1,1), -- Grasps of Reason +-- X002 Deconstructor 25man (and hardmode) +(@XT002_25,1,100,3,0,-@XT002_25Ref,3), -- 3 items from Ref loot +(@XT002_25,2,10,3,0,-34154,1), -- 1 from recepies +(@XT002_25,45038,8,3,0,1,1), -- Fragment of Val'anyr (quest only!?) +(@XT002_25,45087,75,3,0,1,1), -- Runed Orb +(@XT002_25,47241,100,3,0,1,2), -- 2 Emblem of Triumph +-- Hard Mode 25man only: +(@XT002_25,45442,0,2,1,1,1), -- Sorthalis,Hammer of the Watchers +(@XT002_25,45443,0,2,1,1,1), -- Charm of Meticulous Timing +(@XT002_25,45444,0,2,1,1,1), -- Gloves of the Steady Hand +(@XT002_25,45445,0,2,1,1,1), -- Breastplate of the Devoted +(@XT002_25,45446,0,2,1,1,1); -- Grasps of Reason diff --git a/sql/updates/world/2012_03_24_02_world_creature_loot_template.sql b/sql/updates/world/2012_03_24_02_world_creature_loot_template.sql new file mode 100644 index 00000000000..cdac3335aed --- /dev/null +++ b/sql/updates/world/2012_03_24_02_world_creature_loot_template.sql @@ -0,0 +1,136 @@ +-- (re) Add reference 26042 +SET @NEC := 26042; -- Northrend Emotion Cooking Recipe Reference +DELETE FROM `reference_loot_template` WHERE `entry`=@NEC; +INSERT INTO `reference_loot_template` (`entry`,`item`,`ChanceOrQuestChance`,`lootmode`,`groupid`,`mincountOrRef`,`maxcount`) VALUES +(@NEC,43507,0,1,1,1,1), -- Recipe: Tasty cupcake +(@NEC,43508,0,1,1,1,1), -- Recipe: Last Week's Mammoth +(@NEC,43509,0,1,1,1,1), -- Recipe: Bad Clams +(@NEC,43510,0,1,1,1,1); -- Recipe: Haunted Herring + +DELETE FROM `creature_loot_template` WHERE `entry` IN (2436,5928,5936,12239,12240,12241,12242,12243,14527,14529,14531,16506,16836,17307,21166,23809,23954,23963,23964,23983,24175,25234,28027,28113,28138,28494,29554,30177,30954,31779,40419); +UPDATE `creature_template`SET `lootid`=entry WHERE `entry` IN (2436,5928,5936,12239,12240,12241,12242,12243,14527,14529,14531,16506,16836,21166,23809,23963,23964,23983,25234,28027,28138,28494,29554,30954,31779,40419); +UPDATE `creature_template` SET `lootid`=0 WHERE `entry` IN (17307,23954,24175,28113,30177); +INSERT INTO `creature_loot_template` (`entry`,`item`,`ChanceOrQuestChance`,`lootmode`,`groupid`,`mincountOrRef`,`maxcount`) VALUES +-- Farmer Kent (friendly?) +(2436,3692,-100,1,0,1,1), -- Hilsbrad Human Skull +-- Sorrow Wing +(5928,5808,-50,1,0,1,1), -- Pridewing Venom Sac +(5928,5137,80,1,0,1,1), -- Bright Eyeball +(5928,5136,10,1,0,1,1), -- Torn Furry Ear +(5928,1,100,1,0,-@NEC,1), -- Random world green drop ilvl 25-30 +-- Orca +(5936,26000,3,1,1,-26000,1), -- Northrend World Grey Reference #1 +(5936,26001,3,1,1,-26001,1), -- Northrend World Grey Reference #2 +(5936,26003,1,1,1,-26003,1), -- Northrend World Green Reference #1 +(5936,26004,1,1,1,-26004,1), -- Northrend World Green Reference #2 +(5936,26005,1,1,1,-26005,1), -- Northrend World Green Reference #3 +(5936,26006,1,1,1,-26006,1), -- Northrend World Green Reference #4 +(5936,26017,0.5,1,1,-26017,1), -- Northrend World Blue Reference #1 +(5936,26018,0.5,1,1,-26018,1), -- Northrend World Blue Reference #2 +(5936,26019,0.5,1,1,-26019,1), -- Northrend World Blue Reference #3 +(5936,26020,0.5,1,1,-26020,1), -- Northrend World Blue Reference #4 +-- Add Theradric Crystal Carving (17684) to the following creatures +(12239,17684,-25,1,0,1,1), -- Spirit of Gelk +(12240,17684,-25,1,0,1,1), -- Spirit of Kolk +(12241,17684,-25,1,0,1,1), -- Spirit of Magra +(12242,17684,-25,1,0,1,1), -- Spirit of Maraudos +(12243,17684,-25,1,0,1,1), -- Spirit of Veng +(14527,18952,-100,1,0,1,1), -- Simone the Inconspicuous - Simone's Head +(14529,18953,-100,1,0,1,1), -- Franklin the Friendly - Klinfran's Head +(14531,18955,-100,1,0,1,1), -- Artorius the Amiable - Artorius's Head +(16506,22708,-100,1,0,1,1), -- Naxxramas Worshipper - Fate of Ramaladni +(16836,23460,-100,1,0,1,1), -- Escaped Dreghood - Broken Blood Sample +(21166,30451,-15,1,0,1,1), -- Illidari Dreadlord - Lohn'goron, Bow of the Torn-heart +-- Vengeance Landing Cannoneer +(23809,26000,3,1,1,-26000,1), -- Northrend World Grey Reference #1 +(23809,26001,3,1,1,-26001,1), -- Northrend World Grey Reference #2 +(23809,26005,1,1,1,-26005,1), -- Northrend World Green Reference #3 +-- Sergeant Lorric +(23963,26000,3,1,1,-26000,1), -- Northrend World Grey Reference #1 +(23963,26001,3,1,1,-26001,1), -- Northrend World Grey Reference #2 +(23963,26003,1,1,1,-26003,1), -- Northrend World Green Reference #1 +(23963,26004,1,1,1,-26004,1), -- Northrend World Green Reference #2 +(23963,26017,0.5,1,1,-26017,1), -- Northrend World Blue Reference #1 +(23963,26018,0.5,1,1,-26018,1), -- Northrend World Blue Reference #2 +(23963,26044,2,1,0,-@NEC,1), -- Northrend Emotion Cooking Recipes +-- Lieutenant Celeyne +(23964,26000,3,1,1,-26000,1), -- Northrend World Grey Reference #1 +(23964,26001,3,1,1,-26001,1), -- Northrend World Grey Reference #2 +(23964,26003,1,1,1,-26003,1), -- Northrend World Green Reference #1 +(23964,26004,1,1,1,-26004,1), -- Northrend World Green Reference #2 +(23964,26017,0.5,1,1,-26017,1), -- Northrend World Blue Reference #1 +(23964,26018,0.5,1,1,-26018,1), -- Northrend World Blue Reference #2 +(23964,26044,2,1,0,-@NEC,1), -- Northrend Emotion Cooking Recipes +-- North Fleet Marine +(23983,26000,3,1,1,-26000,1), -- Northrend World Grey Reference #1 +(23983,26001,3,1,1,-26001,1), -- Northrend World Grey Reference #2 +(23983,26003,1,1,1,-26003,1), -- Northrend World Green Reference #1 +(23983,26004,1,1,1,-26004,1), -- Northrend World Green Reference #2 +(23983,26017,0.5,1,1,-26017,1), -- Northrend World Blue Reference #1 +(23983,26018,0.5,1,1,-26018,1), -- Northrend World Blue Reference #2 +(23983,26044,2,1,0,-@NEC,1), -- Northrend Emotion Cooking Recipes +-- Stormfleet Deckhand +(25234,26000,3,1,1,-26000,1), -- Northrend World Grey Reference #1 +(25234,26003,1,1,1,-26003,1), -- Northrend World Green Reference #1 +-- High-Oracle Soo-say +(28027,17058,50,1,0,1,1), -- Fish Oil +(28027,17057,30,1,0,1,1), -- Shiny Fish Scales +(28027,33470,15,1,0,2,4), -- Frostweave Cloth +(28027,35951,10,1,0,1,3), -- Poached Emperor Salmon +(28027,38642,-1,1,0,1,1), -- Golden Engagement Ring +-- Elder Harkek +(28138,33470,40,1,0,2,4), -- Frostweave Cloth +(28138,33447,4,1,0,1,1), -- Runic Healing Potion +(28138,38642,-1,1,0,1,1), -- Golden Engagement Ring +-- Kutube'sa +(28494,26001,3,1,1,-26001,1), -- Northrend World Grey Reference #2 +(28494,26002,3,1,1,-26002,1), -- Northrend World Grey Reference #3 +(28494,26010,1,1,1,-26010,1), -- Northrend World Green Reference #4 +(28494,26011,1,1,1,-26011,1), -- Northrend World Green Reference #5 +(28494,26012,1,1,1,-26012,1), -- Northrend World Green Reference #6 +(28494,26023,0.5,1,1,-26023,1), -- Northrend World Blue Reference #3 +(28494,26025,0.5,1,1,-26025,1), -- Northrend World Blue Reference #4 +(28494,26026,0.5,1,1,-26026,1), -- Northrend World Blue Reference #5 +(28494,26044,2,1,0,-@NEC,1), -- Northrend Emotion Cooking Recipes +(28494,39152,35,1,0,1,1), -- Manual: Heavy Frostweave Bandage +(28494,43297,1,1,0,1,1), -- Damaged Necklace +-- Snowblind Devotee +(29554,26001,3,1,1,-26001,1), -- Northrend World Grey Reference #2 +(29554,26002,3,1,1,-26002,1), -- Northrend World Grey Reference #3 +(29554,26009,1,1,1,-26009,1), -- Northrend World Green Reference #3 +(29554,26010,1,1,1,-26010,1), -- Northrend World Green Reference #4 +(29554,26011,1,1,1,-26011,1), -- Northrend World Green Reference #5 +(29554,26012,1,1,1,-26012,1), -- Northrend World Green Reference #6 +(29554,26013,1,1,1,-26013,1), -- Northrend World Green Reference #7 +(29554,26023,0.5,1,1,-26023,1), -- Northrend World Blue Reference #3 +(29554,26024,0.5,1,1,-26024,1), -- Northrend World Blue Reference #4 +(29554,26025,0.5,1,1,-26025,1), -- Northrend World Blue Reference #5 +(29554,26026,0.5,1,1,-26026,1), -- Northrend World Blue Reference #6 +(29554,26044,2,1,0,-@NEC,1), -- Northrend Emotion Cooking Recipes +(29554,39152,35,1,0,1,1), -- Manual: Heavy Frostweave Bandage +(29554,43297,1,1,0,1,1), -- Damaged Necklace +-- Rokir +(30954,26001,6,1,1,-26001,1), -- Northrend World Grey Reference #2 +(30954,26002,6,1,1,-26002,1), -- Northrend World Grey Reference #3 +(30954,26014,2,1,1,-26014,1), -- Northrend World Green Reference #8 +(30954,26015,2,1,1,-26015,1), -- Northrend World Green Reference #9 +-- Skeletal Archmage +(31779,26001,3,1,1,-26001,1), -- Northrend World Grey Reference #2 +(31779,26002,3,1,1,-26002,1), -- Northrend World Grey Reference #3 +(31779,26013,1,1,1,-26013,1), -- Northrend World Green Reference #7 +(31779,26014,1,1,1,-26014,1), -- Northrend World Green Reference #8 +(31779,26015,1,1,1,-26015,1), -- Northrend World Green Reference #9 +(31779,26028,0.5,1,1,-26028,1), -- Northrend World Blue Reference #8 +(31779,39152,50,1,0,1,1), -- Manual: Heavy Frostweave Bandage +(31779,43297,1,1,0,1,1), -- Damaged Necklace +-- Charscale Assaulter +(40419,26001,6,1,1,-26001,1), -- Northrend World Grey Reference #2 +(40419,26002,6,1,1,-26002,1), -- Northrend World Grey Reference #3 +(40419,26015,2,1,1,-26015,1), -- Northrend World Green Reference #9 +(40419,26016,2,1,1,-26016,1); -- Northrend World Green Reference #10 +-- conditions +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 1 AND `SourceGroup` IN (28494,29554,31779); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`Comment`) VALUES +(1,28494,39152,7,129,390,'Manual: Heavy Frostweave Bandage will drop only if the player has first aid at 390'), +(1,29554,39152,7,129,390,'Manual: Heavy Frostweave Bandage will drop only if the player has first aid at 390'), +(1,31779,39152,7,129,390,'Manual: Heavy Frostweave Bandage will drop only if the player has first aid at 390'); diff --git a/sql/updates/world/2012_03_25_00_world_game_event.sql b/sql/updates/world/2012_03_25_00_world_game_event.sql new file mode 100644 index 00000000000..82dfaa3f494 --- /dev/null +++ b/sql/updates/world/2012_03_25_00_world_game_event.sql @@ -0,0 +1,4 @@ +-- darkmoon faerie resync, again +UPDATE `game_event` SET `start_time`='2012-04-01 00:01:00' WHERE `eventEntry`=5; +UPDATE `game_event` SET `start_time`='2012-05-06 00:01:00' WHERE `eventEntry`=3; +UPDATE `game_event` SET `start_time`='2012-06-03 00:01:00' WHERE `eventEntry`=4; diff --git a/sql/updates/world/2012_03_26_00_world_creature_template.sql b/sql/updates/world/2012_03_26_00_world_creature_template.sql new file mode 100644 index 00000000000..f60849476bd --- /dev/null +++ b/sql/updates/world/2012_03_26_00_world_creature_template.sql @@ -0,0 +1,73 @@ +UPDATE `creature_template` SET `HoverHeight`=10.8, `VehicleId`=232 WHERE `entry`=30393; +UPDATE `creature_template` SET `HoverHeight`=10.8, `VehicleId`=237 WHERE `entry`=30461; +UPDATE `creature_template` SET `HoverHeight`=10 WHERE `entry`=27530; +UPDATE `creature_template` SET `HoverHeight`=10 WHERE `entry`=26277; +UPDATE `creature_template` SET `HoverHeight`=10 WHERE `entry`=26276; +UPDATE `creature_template` SET `HoverHeight`=1.2 WHERE `entry`=31070; +UPDATE `creature_template` SET `HoverHeight`=12 WHERE `entry`=37126; +UPDATE `creature_template` SET `HoverHeight`=15 WHERE `entry`=27608; +UPDATE `creature_template` SET `HoverHeight`=15 WHERE `entry`=27608; +UPDATE `creature_template` SET `HoverHeight`=1.6 WHERE `entry`=38392; +UPDATE `creature_template` SET `HoverHeight`=2.25 WHERE `entry`=30272; +UPDATE `creature_template` SET `HoverHeight`=2.58, `Scale`=1.72 WHERE `entry`=26607; +UPDATE `creature_template` SET `HoverHeight`=25 WHERE `entry`=37755; +UPDATE `creature_template` SET `HoverHeight`=26 WHERE `entry`=29790; +UPDATE `creature_template` SET `HoverHeight`=2.7 WHERE `entry`=25451; +UPDATE `creature_template` SET `HoverHeight`=2 WHERE `entry`=29048; +UPDATE `creature_template` SET `HoverHeight`=2, `VehicleId`=234 WHERE `entry`=30228; +UPDATE `creature_template` SET `HoverHeight`=2 WHERE `entry`=25445; +UPDATE `creature_template` SET `HoverHeight`=2 WHERE `entry`=26761; +UPDATE `creature_template` SET `HoverHeight`=2 WHERE `entry`=26761; +UPDATE `creature_template` SET `HoverHeight`=2 WHERE `entry`=25721; +UPDATE `creature_template` SET `HoverHeight`=35 WHERE `entry`=27789; +UPDATE `creature_template` SET `HoverHeight`=3 WHERE `entry`=34567; +UPDATE `creature_template` SET `HoverHeight`=3 WHERE `entry`=26668; +UPDATE `creature_template` SET `HoverHeight`=3, `VehicleId`=390 WHERE `entry`=34120; +UPDATE `creature_template` SET `HoverHeight`=3, `VehicleId`=108 WHERE `entry`=24083; +UPDATE `creature_template` SET `HoverHeight`=3, `VehicleId`=270 WHERE `entry`=31137; +UPDATE `creature_template` SET `HoverHeight`=4 WHERE `entry`=24272; +UPDATE `creature_template` SET `HoverHeight`=4 WHERE `entry`=37098; +UPDATE `creature_template` SET `HoverHeight`=4 WHERE `entry`=28534; +UPDATE `creature_template` SET `HoverHeight`=4 WHERE `entry`=28511; +UPDATE `creature_template` SET `HoverHeight`=5.85 WHERE `entry`=26736; +UPDATE `creature_template` SET `HoverHeight`=5.85 WHERE `entry`=26736; +UPDATE `creature_template` SET `HoverHeight`=5.85 WHERE `entry`=32534; +UPDATE `creature_template` SET `HoverHeight`=5, `VehicleId`=348 WHERE `entry`=33214; +UPDATE `creature_template` SET `HoverHeight`=5 WHERE `entry`=27693; +UPDATE `creature_template` SET `HoverHeight`=5 WHERE `entry`=34203; +UPDATE `creature_template` SET `HoverHeight`=6.25 WHERE `entry`=40083; +UPDATE `creature_template` SET `HoverHeight`=6.25 WHERE `entry`=40100; +UPDATE `creature_template` SET `HoverHeight`=6 WHERE `entry`=34496; +UPDATE `creature_template` SET `HoverHeight`=6 WHERE `entry`=34496; +UPDATE `creature_template` SET `HoverHeight`=6 WHERE `entry`=34497; +UPDATE `creature_template` SET `HoverHeight`=7.5 WHERE `entry`=26933; +UPDATE `creature_template` SET `HoverHeight`=8.4, `VehicleId`=232 WHERE `entry`=30420; +UPDATE `creature_template` SET `HoverHeight`=8 WHERE `entry`=33186; +UPDATE `creature_template` SET `HoverHeight`=9 WHERE `entry`=26933; +UPDATE `creature_template` SET `HoverHeight`=9 WHERE `entry`=37528; +UPDATE `creature_template` SET `HoverHeight`=9 WHERE `entry`=37230; +UPDATE `creature_template` SET `HoverHeight`=9, `VehicleId`=375 WHERE `entry`=33687; +UPDATE `creature_template` SET `HoverHeight`=9, `VehicleId`=535 WHERE `entry`=36661; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=10.8, `VehicleId`=232 WHERE `entry`=30393; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=10 WHERE `entry`=27608; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=10 WHERE `entry`=27608; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=15 WHERE `entry`=32630; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=1.6 WHERE `entry`=38391; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=2.25, `VehicleId`=247 WHERE `entry`=30564; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=2.25 WHERE `entry`=30272; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=2 WHERE `entry`=25721; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=2 WHERE `entry`=29570; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=2 WHERE `entry`=26761; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=3.12, `Scale`=2.08 WHERE `entry`=26607; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=3 WHERE `entry`=26668; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=3, `VehicleId`=108 WHERE `entry`=24083; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=4 WHERE `entry`=37098; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=4 WHERE `entry`=30945; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=5.85 WHERE `entry`=26736; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=5.85 WHERE `entry`=26736; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=5, `VehicleId`=276 WHERE `entry`=31432; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=6 WHERE `entry`=30501; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=7.5 WHERE `entry`=26933; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=8.4, `VehicleId`=232 WHERE `entry`=30420; +UPDATE `creature_template` SET `InhabitType`=0x4, `HoverHeight`=9 WHERE `entry`=26933; + diff --git a/sql/updates/world/2012_03_26_01_world_spell_script_names.sql b/sql/updates/world/2012_03_26_01_world_spell_script_names.sql new file mode 100644 index 00000000000..0a5c90f798f --- /dev/null +++ b/sql/updates/world/2012_03_26_01_world_spell_script_names.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` IN (34477, 35079); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(34477,'spell_hun_misdirection'), +(35079,'spell_hun_misdirection_proc'); diff --git a/sql/updates/world/2012_03_27_00_world_misc.sql b/sql/updates/world/2012_03_27_00_world_misc.sql new file mode 100644 index 00000000000..132c91b81d7 --- /dev/null +++ b/sql/updates/world/2012_03_27_00_world_misc.sql @@ -0,0 +1,49 @@ +ALTER TABLE `battleground_template` CHANGE `Weight` `Weight` tinyint(3) unsigned NOT NULL DEFAULT '1'; +ALTER TABLE `conditions` CHANGE `SourceId` `SourceId` int(11) NOT NULL DEFAULT '0'; +ALTER TABLE `creature` CHANGE `equipment_id` `equipment_id` mediumint(8) NOT NULL DEFAULT '0'; +ALTER TABLE `creature_addon` CHANGE `path_id` `path_id` int(10) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `creature_ai_scripts` CHANGE `id` `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Identifier'; +ALTER TABLE `creature_ai_scripts` CHANGE `creature_id` `creature_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Creature Template Identifier'; +ALTER TABLE `creature_ai_scripts` CHANGE `event_type` `event_type` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT 'Event Type'; +ALTER TABLE `creature_ai_scripts` CHANGE `event_chance` `event_chance` int(10) unsigned NOT NULL DEFAULT '100'; +ALTER TABLE `creature_ai_scripts` CHANGE `event_flags` `event_flags` int(10) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `creature_ai_scripts` CHANGE `action1_type` `action1_type` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT 'Action Type'; +ALTER TABLE `creature_ai_scripts` CHANGE `action2_type` `action2_type` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT 'Action Type'; +ALTER TABLE `creature_ai_scripts` CHANGE `action3_type` `action3_type` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT 'Action Type'; +ALTER TABLE `creature_ai_summons` CHANGE `id` `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Location Identifier'; +ALTER TABLE `creature_ai_summons` CHANGE `spawntimesecs` `spawntimesecs` int(10) unsigned NOT NULL DEFAULT '120'; +ALTER TABLE `creature_classlevelstats` CHANGE `level` `level` tinyint(4) NOT NULL; +ALTER TABLE `creature_classlevelstats` CHANGE `class` `class` tinyint(4) NOT NULL; +ALTER TABLE `creature_classlevelstats` CHANGE `basehp0` `basehp0` smallint(6) NOT NULL; +ALTER TABLE `creature_classlevelstats` CHANGE `basehp1` `basehp1` smallint(6) NOT NULL; +ALTER TABLE `creature_classlevelstats` CHANGE `basehp2` `basehp2` smallint(6) NOT NULL; +ALTER TABLE `creature_classlevelstats` CHANGE `basemana` `basemana` smallint(6) NOT NULL; +ALTER TABLE `creature_classlevelstats` CHANGE `basearmor` `basearmor` smallint(6) NOT NULL; +ALTER TABLE `creature_formations` CHANGE `leaderGUID` `leaderGUID` int(10) unsigned NOT NULL; +ALTER TABLE `creature_formations` CHANGE `memberGUID` `memberGUID` int(10) unsigned NOT NULL; +ALTER TABLE `creature_formations` CHANGE `groupAI` `groupAI` int(10) unsigned NOT NULL; +ALTER TABLE `creature_loot_template` CHANGE `mincountOrRef` `mincountOrRef` mediumint(8) NOT NULL DEFAULT '1'; +ALTER TABLE `creature_onkill_reputation` CHANGE `RewOnKillRepValue1` `RewOnKillRepValue1` mediumint(8) NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `KillCredit1` `KillCredit1` int(10) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `KillCredit2` `KillCredit2` int(10) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `exp` `exp` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `resistance1` `resistance1` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `resistance2` `resistance2` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `resistance3` `resistance3` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `resistance4` `resistance4` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `resistance5` `resistance5` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `resistance6` `resistance6` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `questItem1` `questItem1` int(10) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `questItem2` `questItem2` int(10) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `questItem3` `questItem3` int(10) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `questItem4` `questItem4` int(10) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `questItem5` `questItem5` int(10) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `questItem6` `questItem6` int(10) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `WDBVerified` `WDBVerified` smallint(6) NULL DEFAULT '1'; +ALTER TABLE `creature_template_addon` CHANGE `path_id` `path_id` int(10) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `creature_transport` CHANGE `guid` `guid` int(11) NOT NULL AUTO_INCREMENT COMMENT 'GUID of NPC on transport - not the same as creature.guid'; +ALTER TABLE `creature_transport` CHANGE `transport_entry` `transport_entry` int(11) NOT NULL COMMENT 'Transport entry'; +ALTER TABLE `creature_transport` CHANGE `npc_entry` `npc_entry` int(11) NOT NULL COMMENT 'NPC entry'; +ALTER TABLE `creature_transport` CHANGE `emote` `emote` int(11) NOT NULL; +ALTER TABLE `db_script_string` CHANGE `entry` `entry` int(10) unsigned NOT NULL DEFAULT '0'; +
\ No newline at end of file diff --git a/src/server/authserver/Realms/RealmList.cpp b/src/server/authserver/Realms/RealmList.cpp index 245b9c7cc8c..efcced51089 100755 --- a/src/server/authserver/Realms/RealmList.cpp +++ b/src/server/authserver/Realms/RealmList.cpp @@ -31,7 +31,7 @@ void RealmList::Initialize(uint32 updateInterval) UpdateRealms(true); } -void RealmList::UpdateRealm(uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build) +void RealmList::UpdateRealm(uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build) { // Create new if not exist or update existed Realm& realm = m_realms[name]; @@ -39,7 +39,7 @@ void RealmList::UpdateRealm(uint32 ID, const std::string& name, const std::strin realm.m_ID = ID; realm.name = name; realm.icon = icon; - realm.color = color; + realm.flag = flag; realm.timezone = timezone; realm.allowedSecurityLevel = allowedSecurityLevel; realm.populationLevel = popu; @@ -84,13 +84,13 @@ void RealmList::UpdateRealms(bool init) const std::string& address = fields[2].GetString(); uint32 port = fields[3].GetUInt32(); uint8 icon = fields[4].GetUInt8(); - uint8 color = fields[5].GetUInt8(); + RealmFlags flag = RealmFlags(fields[5].GetUInt8()); uint8 timezone = fields[6].GetUInt8(); uint8 allowedSecurityLevel = fields[7].GetUInt8(); float pop = fields[8].GetFloat(); uint32 build = fields[9].GetUInt32(); - UpdateRealm(realmId, name, address, port, icon, color, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build); + UpdateRealm(realmId, name, address, port, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build); if (init) sLog->outString("Added realm \"%s\".", fields[1].GetCString()); diff --git a/src/server/authserver/Realms/RealmList.h b/src/server/authserver/Realms/RealmList.h index 698026876fb..4d258953ae0 100755 --- a/src/server/authserver/Realms/RealmList.h +++ b/src/server/authserver/Realms/RealmList.h @@ -23,13 +23,26 @@ #include <ace/Null_Mutex.h> #include "Common.h" +enum RealmFlags +{ + REALM_FLAG_NONE = 0x00, + REALM_FLAG_INVALID = 0x01, + REALM_FLAG_OFFLINE = 0x02, + REALM_FLAG_SPECIFYBUILD = 0x04, + REALM_FLAG_UNK1 = 0x08, + REALM_FLAG_UNK2 = 0x10, + REALM_FLAG_RECOMMENDED = 0x20, + REALM_FLAG_NEW = 0x40, + REALM_FLAG_FULL = 0x80 +}; + // Storage object for a realm struct Realm { std::string address; std::string name; uint8 icon; - uint8 color; + RealmFlags flag; uint8 timezone; uint32 m_ID; AccountTypes allowedSecurityLevel; @@ -58,7 +71,7 @@ public: private: void UpdateRealms(bool init=false); - void UpdateRealm(uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build); + void UpdateRealm(uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build); RealmMap m_realms; uint32 m_UpdateInterval; diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSocket.cpp index e1d77c60286..15555e4d607 100755 --- a/src/server/authserver/Server/AuthSocket.cpp +++ b/src/server/authserver/Server/AuthSocket.cpp @@ -871,7 +871,7 @@ bool AuthSocket::_HandleRealmList() pkt << i->second.icon; // realm type if ( _expversion & POST_BC_EXP_FLAG ) // only 2.x and 3.x clients pkt << lock; // if 1, then realm locked - pkt << i->second.color; // if 2, then realm is offline + pkt << uint8(i->second.flag); // RealmFlags pkt << i->first; pkt << i->second.address; pkt << i->second.populationLevel; @@ -882,6 +882,15 @@ bool AuthSocket::_HandleRealmList() else pkt << (uint8)0x0; // 1.12.1 and 1.12.2 clients + if (i->second.flag & REALM_FLAG_SPECIFYBUILD) + { + // TODO: Make this customizable + pkt << uint8(3); + pkt << uint8(3); + pkt << uint8(5); + pkt << uint16(12340); + } + ++RealmListSize; } diff --git a/src/server/authserver/Server/AuthSocket.h b/src/server/authserver/Server/AuthSocket.h index 9d59a9f7602..9be2136b55c 100755 --- a/src/server/authserver/Server/AuthSocket.h +++ b/src/server/authserver/Server/AuthSocket.h @@ -23,19 +23,6 @@ #include "BigNumber.h" #include "RealmSocket.h" -enum RealmFlags -{ - REALM_FLAG_NONE = 0x00, - REALM_FLAG_INVALID = 0x01, - REALM_FLAG_OFFLINE = 0x02, - REALM_FLAG_SPECIFYBUILD = 0x04, - REALM_FLAG_UNK1 = 0x08, - REALM_FLAG_UNK2 = 0x10, - REALM_FLAG_RECOMMENDED = 0x20, - REALM_FLAG_NEW = 0x40, - REALM_FLAG_FULL = 0x80 -}; - // Handle login commands class AuthSocket: public RealmSocket::Session { diff --git a/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp b/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp index add7b4db174..facfbd7581c 100755 --- a/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp +++ b/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp @@ -56,10 +56,10 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Texts() StringTextData temp; int32 i = fields[0].GetInt32(); - temp.SoundId = fields[1].GetInt32(); - temp.Type = fields[2].GetInt32(); - temp.Language = fields[3].GetInt32(); - temp.Emote = fields[4].GetInt32(); + temp.SoundId = fields[1].GetUInt32(); + temp.Type = fields[2].GetUInt8(); + temp.Language = fields[3].GetUInt8(); + temp.Emote = fields[4].GetUInt16(); // range negative if (i > MIN_CREATURE_AI_TEXT_STRING_ID || i <= MAX_CREATURE_AI_TEXT_STRING_ID) @@ -187,7 +187,7 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() temp.creature_id = fields[1].GetUInt32(); uint32 creature_id = temp.creature_id; - uint32 e_type = fields[2].GetUInt32(); + uint32 e_type = fields[2].GetUInt8(); //Report any errors in event if (e_type >= EVENT_T_END) { @@ -196,13 +196,13 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() } temp.event_type = EventAI_Type(e_type); - temp.event_inverse_phase_mask = fields[3].GetUInt32(); - temp.event_chance = fields[4].GetUInt8(); - temp.event_flags = fields[5].GetUInt8(); - temp.raw.param1 = fields[6].GetUInt32(); - temp.raw.param2 = fields[7].GetUInt32(); - temp.raw.param3 = fields[8].GetUInt32(); - temp.raw.param4 = fields[9].GetUInt32(); + temp.event_inverse_phase_mask = fields[3].GetInt32(); + temp.event_chance = fields[4].GetUInt32(); + temp.event_flags = fields[5].GetUInt32(); + temp.raw.param1 = fields[6].GetInt32(); + temp.raw.param2 = fields[7].GetInt32(); + temp.raw.param3 = fields[8].GetInt32(); + temp.raw.param4 = fields[9].GetInt32(); //Creature does not exist in database if (!sObjectMgr->GetCreatureTemplate(temp.creature_id)) @@ -399,7 +399,7 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() for (uint32 j = 0; j < MAX_ACTIONS; j++) { - uint16 action_type = fields[10+(j*4)].GetUInt16(); + uint16 action_type = fields[10+(j*4)].GetUInt8(); if (action_type >= ACTION_T_END) { sLog->outErrorDb("CreatureEventAI: Event %u Action %u has incorrect action type (%u), replace by ACTION_T_NONE.", i, j+1, action_type); @@ -410,9 +410,9 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() CreatureEventAI_Action& action = temp.action[j]; action.type = EventAI_ActionType(action_type); - action.raw.param1 = fields[11+(j*4)].GetUInt32(); - action.raw.param2 = fields[12+(j*4)].GetUInt32(); - action.raw.param3 = fields[13+(j*4)].GetUInt32(); + action.raw.param1 = fields[11+(j*4)].GetInt32(); + action.raw.param2 = fields[12+(j*4)].GetInt32(); + action.raw.param3 = fields[13+(j*4)].GetInt32(); //Report any errors in actions switch (action.type) diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 0523f59da5d..05a2910e7a7 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -1364,13 +1364,14 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u e.GetTargetType() == SMART_TARGET_CREATURE_DISTANCE || e.GetTargetType() == SMART_TARGET_GAMEOBJECT_RANGE || e.GetTargetType() == SMART_TARGET_GAMEOBJECT_GUID || e.GetTargetType() == SMART_TARGET_GAMEOBJECT_DISTANCE || e.GetTargetType() == SMART_TARGET_CLOSEST_CREATURE || e.GetTargetType() == SMART_TARGET_CLOSEST_GAMEOBJECT || - e.GetTargetType() == SMART_TARGET_OWNER_OR_SUMMONER) + e.GetTargetType() == SMART_TARGET_OWNER_OR_SUMMONER || e.GetTargetType() == SMART_TARGET_ACTION_INVOKER) { ObjectList* targets = GetTargets(e, unit); if (!targets) break; target = targets->front(); + delete targets; } if (!target) diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index fe2a89de9aa..776ffd78a9a 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -35,6 +35,14 @@ void SmartWaypointMgr::LoadFromDB() { uint32 oldMSTime = getMSTime(); + for (UNORDERED_MAP<uint32, WPPath*>::iterator itr = waypoint_map.begin(); itr != waypoint_map.end(); ++itr) + { + for (WPPath::iterator pathItr = itr->second->begin(); pathItr != itr->second->end(); ++pathItr) + delete pathItr->second; + + delete itr->second; + } + waypoint_map.clear(); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_SMARTAI_WP); @@ -84,6 +92,19 @@ void SmartWaypointMgr::LoadFromDB() sLog->outString(); } +SmartWaypointMgr::~SmartWaypointMgr() +{ + for (UNORDERED_MAP<uint32, WPPath*>::iterator itr = waypoint_map.begin(); itr != waypoint_map.end(); ++itr) + { + for (WPPath::iterator pathItr = itr->second->begin(); pathItr != itr->second->end(); ++pathItr) + delete pathItr->second; + + delete itr->second; + } + + waypoint_map.clear(); +} + void SmartAIMgr::LoadSmartAIFromDB() { uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 007b57b52d7..e2cd75ee62c 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1230,9 +1230,9 @@ typedef UNORDERED_MAP<uint32, ObjectList*> ObjectListMap; class SmartWaypointMgr { friend class ACE_Singleton<SmartWaypointMgr, ACE_Null_Mutex>; - SmartWaypointMgr(){}; + SmartWaypointMgr() {} public: - ~SmartWaypointMgr(){}; + ~SmartWaypointMgr(); void LoadFromDB(); diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index a6ae300e25d..240609e3821 100755 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -53,12 +53,21 @@ AccountOpResult CreateAccount(std::string username, std::string password) AccountOpResult DeleteAccount(uint32 accountId) { - QueryResult result = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accountId); + // Check if accounts exists + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BY_ID); + stmt->setUInt32(0, accountId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (!result) - return AOR_NAME_NOT_EXIST; // account doesn't exist + return AOR_NAME_NOT_EXIST; + + // Obtain accounts characters + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARS_BY_ACCOUNT_ID); + + stmt->setUInt32(0, accountId); + + result = CharacterDatabase.Query(stmt); - // existed characters list - result = CharacterDatabase.PQuery("SELECT guid FROM characters WHERE account='%d'", accountId); if (result) { do @@ -66,7 +75,7 @@ AccountOpResult DeleteAccount(uint32 accountId) uint32 guidLow = (*result)[0].GetUInt32(); uint64 guid = MAKE_NEW_GUID(guidLow, 0, HIGHGUID_PLAYER); - // kick if player is online + // Kick if player is online if (Player* p = ObjectAccessor::FindPlayer(guid)) { WorldSession* s = p->GetSession(); @@ -79,7 +88,7 @@ AccountOpResult DeleteAccount(uint32 accountId) } // table realm specific but common for all characters of account for realm - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_TUTORIALS); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_TUTORIALS); stmt->setUInt32(0, accountId); CharacterDatabase.Execute(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ACCOUNT_DATA); @@ -88,9 +97,17 @@ AccountOpResult DeleteAccount(uint32 accountId) SQLTransaction trans = LoginDatabase.BeginTransaction(); - trans->PAppend("DELETE FROM account WHERE id='%d'", accountId); - trans->PAppend("DELETE FROM account_access WHERE id ='%d'", accountId); - trans->PAppend("DELETE FROM realmcharacters WHERE acctid='%d'", accountId); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT); + stmt->setUInt32(0, accountId); + trans->Append(stmt); + + stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS); + stmt->setUInt32(0, accountId); + trans->Append(stmt); + + stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS); + stmt->setUInt32(0, accountId); + trans->Append(stmt); LoginDatabase.CommitTransaction(trans); @@ -99,9 +116,13 @@ AccountOpResult DeleteAccount(uint32 accountId) AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword) { - QueryResult result = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accountId); + // Check if accounts exists + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BY_ID); + stmt->setUInt32(0, accountId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (!result) - return AOR_NAME_NOT_EXIST; // account doesn't exist + return AOR_NAME_NOT_EXIST; if (utf8length(newUsername) > MAX_ACCOUNT_STR) return AOR_NAME_TOO_LONG; @@ -112,7 +133,7 @@ AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::s normalizeString(newUsername); normalizeString(newPassword); - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_USERNAME); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_USERNAME); stmt->setString(0, newUsername); stmt->setString(1, CalculateShaPassHash(newUsername, newPassword)); @@ -148,28 +169,38 @@ AccountOpResult ChangePassword(uint32 accountId, std::string newPassword) uint32 GetId(std::string username) { - LoginDatabase.EscapeString(username); - QueryResult result = LoginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'", username.c_str()); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_ACCOUNT_ID_BY_USERNAME); + stmt->setString(0, username); + PreparedQueryResult result = LoginDatabase.Query(stmt); + return (result) ? (*result)[0].GetUInt32() : 0; } uint32 GetSecurity(uint32 accountId) { - QueryResult result = LoginDatabase.PQuery("SELECT gmlevel FROM account_access WHERE id = '%u'", accountId); - return (result) ? (*result)[0].GetUInt32() : 0; + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_ACCOUNT_ACCESS_GMLEVEL); + stmt->setUInt32(0, accountId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + return (result) ? (*result)[0].GetUInt8() : uint32(SEC_PLAYER); } -uint32 GetSecurity(uint64 accountId, int32 realmId) +uint32 GetSecurity(uint32 accountId, int32 realmId) { - QueryResult result = (realmId == -1) - ? LoginDatabase.PQuery("SELECT gmlevel FROM account_access WHERE id = '%u' AND RealmID = '%d'", accountId, realmId) - : LoginDatabase.PQuery("SELECT gmlevel FROM account_access WHERE id = '%u' AND (RealmID = '%d' OR RealmID = '-1')", accountId, realmId); - return (result) ? (*result)[0].GetUInt32() : 0; + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_GMLEVEL_BY_REALMID); + stmt->setUInt32(0, accountId); + stmt->setInt32(1, realmId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + return (result) ? (*result)[0].GetUInt8() : uint32(SEC_PLAYER); } bool GetName(uint32 accountId, std::string& name) { - QueryResult result = LoginDatabase.PQuery("SELECT username FROM account WHERE id = '%u'", accountId); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_USERNAME_BY_ID); + stmt->setUInt32(0, accountId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (result) { name = (*result)[0].GetString(); @@ -189,14 +220,21 @@ bool CheckPassword(uint32 accountId, std::string password) normalizeString(username); normalizeString(password); - QueryResult result = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d' AND sha_pass_hash='%s'", accountId, CalculateShaPassHash(username, password).c_str()); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_CHECK_PASSWORD); + stmt->setUInt32(0, accountId); + stmt->setString(1, CalculateShaPassHash(username, password)); + PreparedQueryResult result = LoginDatabase.Query(stmt); + return (result) ? true : false; } uint32 GetCharactersCount(uint32 accountId) { // check character count - QueryResult result = CharacterDatabase.PQuery("SELECT COUNT(guid) FROM characters WHERE account = '%d'", accountId); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_SUM_CHARS); + stmt->setUInt32(0, accountId); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + return (result) ? (*result)[0].GetUInt32() : 0; } diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index 467972cdf65..c69f3c0a6f3 100755 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -44,7 +44,7 @@ namespace AccountMgr uint32 GetId(std::string username); uint32 GetSecurity(uint32 accountId); - uint32 GetSecurity(uint64 accountId, int32 realmId); + uint32 GetSecurity(uint32 accountId, int32 realmId); bool GetName(uint32 accountId, std::string& name); uint32 GetCharactersCount(uint32 accountId); std::string CalculateShaPassHash(std::string& name, std::string& password); diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 271e78abf67..7b2e157eac8 100755 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -496,8 +496,15 @@ void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uin void AchievementMgr::DeleteFromDB(uint32 lowguid) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); - trans->PAppend("DELETE FROM character_achievement WHERE guid = %u", lowguid); - trans->PAppend("DELETE FROM character_achievement_progress WHERE guid = %u", lowguid); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENT); + stmt->setUInt32(0, lowguid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS); + stmt->setUInt32(0, lowguid); + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); } @@ -625,7 +632,7 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ // title achievement rewards are retroactive if (AchievementReward const* reward = sAchievementMgr->GetAchievementReward(achievement)) - if (uint32 titleId = reward->titleId[GetPlayer()->GetTeam() == ALLIANCE ? 0 : 1]) + if (uint32 titleId = reward->titleId[Player::TeamForRace(GetPlayer()->getRace()) == ALLIANCE ? 0 : 1]) if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId)) if (!GetPlayer()->HasTitle(titleEntry)) GetPlayer()->SetTitle(titleEntry); @@ -2275,7 +2282,7 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData() continue; } - uint32 dataType = fields[1].GetUInt32(); + uint32 dataType = fields[1].GetUInt8(); const char* scriptName = fields[4].GetCString(); uint32 scriptId = 0; if (strcmp(scriptName, "")) // not empty diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index a2e958d680f..38a5a49f7a5 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -482,7 +482,9 @@ void AuctionHouseObject::Update() if (AuctionsMap.empty()) return; - QueryResult result = CharacterDatabase.PQuery("SELECT id FROM auctionhouse WHERE time <= %u ORDER BY TIME ASC", (uint32)curTime+60); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTION_BY_TIME); + stmt->setUInt32(0, (uint32)curTime+60); + PreparedQueryResult result = CharacterDatabase.Query(stmt); if (!result) return; diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp index 37aebab5225..ab451a38fa8 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp @@ -153,6 +153,8 @@ void ArenaTeamMgr::DistributeArenaPoints() SQLTransaction trans = CharacterDatabase.BeginTransaction(); + PreparedStatement* stmt; + // Cycle that gives points to all players for (std::map<uint32, uint32>::iterator playerItr = PlayerPoints.begin(); playerItr != PlayerPoints.end(); ++playerItr) { @@ -160,7 +162,12 @@ void ArenaTeamMgr::DistributeArenaPoints() if (Player* player = HashMapHolder<Player>::Find(playerItr->first)) player->ModifyArenaPoints(playerItr->second, &trans); else // Update database - trans->PAppend("UPDATE characters SET arenaPoints=arenaPoints+%u WHERE guid=%u", playerItr->second, playerItr->first); + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ARENA_POINTS); + stmt->setUInt32(0, playerItr->second); + stmt->setUInt32(1, playerItr->first); + trans->Append(stmt); + } } CharacterDatabase.CommitTransaction(trans); diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index 77b985b205f..e1b99cbdcb9 100755 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -708,10 +708,10 @@ void BattlegroundMgr::CreateInitialBattlegrounds() CreateBattlegroundData data; data.bgTypeId = BattlegroundTypeId(bgTypeID_); data.IsArena = (bl->type == TYPE_ARENA); - data.MinPlayersPerTeam = fields[1].GetUInt32(); - data.MaxPlayersPerTeam = fields[2].GetUInt32(); - data.LevelMin = fields[3].GetUInt32(); - data.LevelMax = fields[4].GetUInt32(); + data.MinPlayersPerTeam = fields[1].GetUInt16(); + data.MaxPlayersPerTeam = fields[2].GetUInt16(); + data.LevelMin = fields[3].GetUInt8(); + data.LevelMax = fields[4].GetUInt8(); //check values from DB if (data.MaxPlayersPerTeam == 0 || data.MinPlayersPerTeam == 0 || data.MinPlayersPerTeam > data.MaxPlayersPerTeam) { diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index a6596de25d6..9992721a6dd 100755 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -444,7 +444,10 @@ ChatCommand* ChatHandler::getCommandTable() added += appendCommandTable(commandTableCache + added, *it); } - QueryResult result = WorldDatabase.Query("SELECT name, security, help FROM command"); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_COMMANDS); + + PreparedQueryResult result = WorldDatabase.Query(stmt); + if (result) { do @@ -452,7 +455,7 @@ ChatCommand* 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].GetUInt8(), fields[2].GetString(), name); } while (result->NextRow()); } diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 2311f4b8e5e..0a39eb43ddb 100755 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -350,8 +350,8 @@ class ChatHandler bool HandleSaveAllCommand(const char* args); // Utility methods for commands - bool LookupPlayerSearchCommand(QueryResult result, int32 limit); - bool HandleBanListHelper(QueryResult result); + bool LookupPlayerSearchCommand(PreparedQueryResult result, int32 limit); + bool HandleBanListHelper(PreparedQueryResult result); bool HandleBanHelper(BanMode mode, char const* args); bool HandleBanInfoHelper(uint32 accountid, char const* accountname); bool HandleUnBanHelper(BanMode mode, char const* args); diff --git a/src/server/game/Chat/Commands/Level2.cpp b/src/server/game/Chat/Commands/Level2.cpp index 062cdb331ea..cc7c9020d38 100755 --- a/src/server/game/Chat/Commands/Level2.cpp +++ b/src/server/game/Chat/Commands/Level2.cpp @@ -42,6 +42,7 @@ #include "Transport.h" #include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand #include "CreatureGroups.h" +#include "ace/INET_Addr.h" //mute player for some times bool ChatHandler::HandleMuteCommand(const char* args) @@ -265,18 +266,18 @@ bool ChatHandler::HandlePInfoCommand(const char* args) else if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; - uint32 accId = 0; - uint32 money = 0; + uint32 accId = 0; + uint32 money = 0; uint32 total_player_time = 0; - uint8 level = 0; - uint32 latency = 0; + uint8 level = 0; + uint32 latency = 0; uint8 race; uint8 Class; - int64 muteTime = 0; - int64 banTime = -1; + int64 muteTime = 0; + int64 banTime = -1; uint32 mapId; uint32 areaId; - uint32 phase = 0; + uint32 phase = 0; // get additional information from Player object if (target) @@ -285,17 +286,17 @@ bool ChatHandler::HandlePInfoCommand(const char* args) if (HasLowerSecurity(target, 0)) return false; - accId = target->GetSession()->GetAccountId(); - money = target->GetMoney(); + accId = target->GetSession()->GetAccountId(); + money = target->GetMoney(); total_player_time = target->GetTotalPlayedTime(); - level = target->getLevel(); - latency = target->GetSession()->GetLatency(); - race = target->getRace(); - Class = target->getClass(); - muteTime = target->GetSession()->m_muteTime; - mapId = target->GetMapId(); - areaId = target->GetAreaId(); - phase = target->GetPhaseMask(); + level = target->getLevel(); + latency = target->GetSession()->GetLatency(); + race = target->getRace(); + Class = target->getClass(); + muteTime = target->GetSession()->m_muteTime; + mapId = target->GetMapId(); + areaId = target->GetAreaId(); + phase = target->GetPhaseMask(); } // get additional information from DB else @@ -304,41 +305,42 @@ bool ChatHandler::HandlePInfoCommand(const char* args) if (HasLowerSecurity(NULL, target_guid)) return false; - // 0 1 2 3 4 5 6 7 - QueryResult result = CharacterDatabase.PQuery("SELECT totaltime, level, money, account, race, class, map, zone FROM characters " - "WHERE guid = '%u'", GUID_LOPART(target_guid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PINFO); + stmt->setUInt32(0, GUID_LOPART(target_guid)); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) return false; - Field* fields = result->Fetch(); + Field* fields = result->Fetch(); total_player_time = fields[0].GetUInt32(); - level = fields[1].GetUInt32(); - money = fields[2].GetUInt32(); - accId = fields[3].GetUInt32(); - race = fields[4].GetUInt8(); - Class = fields[5].GetUInt8(); - mapId = fields[6].GetUInt16(); - areaId = fields[7].GetUInt16(); + level = fields[1].GetUInt8(); + money = fields[2].GetUInt32(); + accId = fields[3].GetUInt32(); + race = fields[4].GetUInt8(); + Class = fields[5].GetUInt8(); + mapId = fields[6].GetUInt16(); + areaId = fields[7].GetUInt16(); } - std::string username = GetTrinityString(LANG_ERROR); - std::string email = GetTrinityString(LANG_ERROR); - std::string last_ip = GetTrinityString(LANG_ERROR); - uint32 security = 0; + std::string username = GetTrinityString(LANG_ERROR); + std::string email = GetTrinityString(LANG_ERROR); + std::string last_ip = GetTrinityString(LANG_ERROR); + uint32 security = 0; std::string last_login = GetTrinityString(LANG_ERROR); - QueryResult result = LoginDatabase.PQuery("SELECT a.username, aa.gmlevel, a.email, a.last_ip, a.last_login, a.mutetime " - "FROM account a " - "LEFT JOIN account_access aa " - "ON (a.id = aa.id AND (aa.RealmID = -1 OR aa.RealmID = %u)) " - "WHERE a.id = '%u'", realmID, accId); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO); + stmt->setInt32(0, int32(realmID)); + stmt->setUInt32(1, accId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (result) { Field* fields = result->Fetch(); - username = fields[0].GetString(); - security = fields[1].GetUInt32(); - email = fields[2].GetString(); - muteTime = fields[5].GetUInt64(); + username = fields[0].GetString(); + security = fields[1].GetUInt8(); + email = fields[2].GetString(); + muteTime = fields[5].GetUInt64(); if (email.empty()) email = "-"; @@ -347,6 +349,25 @@ bool ChatHandler::HandlePInfoCommand(const char* args) { last_ip = fields[3].GetString(); last_login = fields[4].GetString(); + + uint32 ip = inet_addr(last_ip.c_str()); +#if TRINITY_ENDIAN == BIGENDIAN + EndianConvertReverse(ip); +#endif + + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_IP2NATION_COUNTRY); + + stmt->setUInt32(0, ip); + + PreparedQueryResult result2 = WorldDatabase.Query(stmt); + + if (result2) + { + Field* fields2 = result2->Fetch(); + last_ip.append(" ("); + last_ip.append(fields2[0].GetString()); + last_ip.append(")"); + } } else { @@ -361,21 +382,23 @@ bool ChatHandler::HandlePInfoCommand(const char* args) std::string bannedby = "unknown"; std::string banreason = ""; - if (QueryResult result2 = LoginDatabase.PQuery("SELECT unbandate, bandate = unbandate, bannedby, banreason FROM account_banned " - "WHERE id = '%u' AND active ORDER BY bandate ASC LIMIT 1", accId)) + + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO_BANS); + stmt->setUInt32(0, accId); + PreparedQueryResult result2 = LoginDatabase.Query(stmt); + if (!result2) { - Field* fields = result2->Fetch(); - banTime = fields[1].GetBool() ? 0 : fields[0].GetUInt64(); - bannedby = fields[2].GetString(); - banreason = fields[3].GetString(); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PINFO_BANS); + stmt->setUInt32(0, GUID_LOPART(target_guid)); + result2 = CharacterDatabase.Query(stmt); } - else if (QueryResult result3 = CharacterDatabase.PQuery("SELECT unbandate, bandate = unbandate, bannedby, banreason FROM character_banned " - "WHERE guid = '%u' AND active ORDER BY bandate ASC LIMIT 1", GUID_LOPART(target_guid))) + + if (result2) { - Field* fields = result3->Fetch(); - banTime = fields[1].GetBool() ? 0 : fields[0].GetUInt64(); - bannedby = fields[2].GetString(); - banreason = fields[3].GetString(); + Field* fields = result2->Fetch(); + banTime = int64(fields[1].GetBool() ? 0 : fields[0].GetUInt32()); + bannedby = fields[2].GetString(); + banreason = fields[3].GetString(); } if (muteTime > 0) @@ -726,9 +749,9 @@ bool ChatHandler::HandleLookupPlayerIpCommand(const char* args) limit = limit_str ? atoi (limit_str) : -1; } - LoginDatabase.EscapeString(ip); - - QueryResult result = LoginDatabase.PQuery("SELECT id, username FROM account WHERE last_ip = '%s'", ip.c_str()); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BY_IP); + stmt->setString(0, ip); + PreparedQueryResult result = LoginDatabase.Query(stmt); return LookupPlayerSearchCommand(result, limit); } @@ -745,9 +768,9 @@ bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args) if (!AccountMgr::normalizeString (account)) return false; - LoginDatabase.EscapeString (account); - - QueryResult result = LoginDatabase.PQuery ("SELECT id, username FROM account WHERE username = '%s'", account.c_str ()); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_LIST_BY_NAME); + stmt->setString(0, account); + PreparedQueryResult result = LoginDatabase.Query(stmt); return LookupPlayerSearchCommand (result, limit); } @@ -761,14 +784,14 @@ bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args) char* limit_str = strtok (NULL, " "); int32 limit = limit_str ? atoi (limit_str) : -1; - LoginDatabase.EscapeString (email); - - QueryResult result = LoginDatabase.PQuery ("SELECT id, username FROM account WHERE email = '%s'", email.c_str ()); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_LIST_BY_EMAIL); + stmt->setString(0, email); + PreparedQueryResult result = LoginDatabase.Query(stmt); return LookupPlayerSearchCommand(result, limit); } -bool ChatHandler::LookupPlayerSearchCommand(QueryResult result, int32 limit) +bool ChatHandler::LookupPlayerSearchCommand(PreparedQueryResult result, int32 limit) { if (!result) { @@ -792,8 +815,11 @@ bool ChatHandler::LookupPlayerSearchCommand(QueryResult result, int32 limit) uint32 acc_id = fields[0].GetUInt32(); std::string acc_name = fields[1].GetString(); - QueryResult chars = CharacterDatabase.PQuery("SELECT guid, name FROM characters WHERE account = '%u'", acc_id); - if (chars) + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_GUID_NAME_BY_ACC); + stmt->setUInt32(0, acc_id); + PreparedQueryResult result2 = CharacterDatabase.Query(stmt); + + if (result2) { PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT, acc_name.c_str(), acc_id); @@ -802,14 +828,14 @@ bool ChatHandler::LookupPlayerSearchCommand(QueryResult result, int32 limit) do { - Field* charfields = chars->Fetch(); + Field* charfields = result2->Fetch(); guid = charfields[0].GetUInt64(); name = charfields[1].GetString(); PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER, name.c_str(), guid); ++i; - } while (chars->NextRow() && (limit == -1 || i < limit)); + } while (result2->NextRow() && (limit == -1 || i < limit)); } } while (result->NextRow()); diff --git a/src/server/game/Chat/Commands/Level3.cpp b/src/server/game/Chat/Commands/Level3.cpp index 0b7bbf9e7ba..d5dd233b43e 100755 --- a/src/server/game/Chat/Commands/Level3.cpp +++ b/src/server/game/Chat/Commands/Level3.cpp @@ -225,7 +225,11 @@ bool ChatHandler::HandleAddItemCommand(const char *args) { std::string itemName = citemName+1; WorldDatabase.EscapeString(itemName); - QueryResult result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str()); + + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME); + stmt->setString(0, itemName); + PreparedQueryResult result = WorldDatabase.Query(stmt); + if (!result) { PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1); @@ -413,22 +417,22 @@ bool ChatHandler::HandleListItemCommand(const char *args) return false; uint32 count = uint32(_count); - QueryResult result; + PreparedQueryResult result; // inventory case uint32 inv_count = 0; - result = CharacterDatabase.PQuery("SELECT COUNT(itemEntry) FROM character_inventory ci INNER JOIN item_instance ii ON ii.guid = ci.item WHERE itemEntry = '%u'", item_id); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM); + stmt->setUInt32(0, item_id); + result = CharacterDatabase.Query(stmt); + if (result) inv_count = (*result)[0].GetUInt32(); - result=CharacterDatabase.PQuery( - // 0 1 2 3 4 5 - "SELECT ci.item, cb.slot AS bag, ci.slot, ci.guid, c.account, c.name FROM characters c " - "INNER JOIN character_inventory ci ON ci.guid = c.guid " - "INNER JOIN item_instance ii ON ii.guid = ci.item " - "LEFT JOIN character_inventory cb ON cb.item = ci.bag " - "WHERE ii.itemEntry = '%u' LIMIT %u ", - item_id, count); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_ITEM_BY_ENTRY); + stmt->setUInt32(0, item_id); + stmt->setUInt32(1, count); + result = CharacterDatabase.Query(stmt); if (result) { @@ -466,24 +470,23 @@ bool ChatHandler::HandleListItemCommand(const char *args) // mail case uint32 mail_count = 0; - result = CharacterDatabase.PQuery("SELECT COUNT(itemEntry) FROM mail_items mi INNER JOIN item_instance ii ON ii.guid = mi.item_guid WHERE itemEntry = '%u'", item_id); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT_ITEM); + stmt->setUInt32(0, item_id); + result = CharacterDatabase.Query(stmt); + if (result) mail_count = (*result)[0].GetUInt32(); if (count > 0) { - result = CharacterDatabase.PQuery( - // 0 1 2 3 4 5 6 - "SELECT mi.item_guid, m.sender, m.receiver, cs.account, cs.name, cr.account, cr.name FROM mail m " - "INNER JOIN mail_items mi ON mi.mail_id = m.id " - "INNER JOIN item_instance ii ON ii.guid = mi.item_guid " - "INNER JOIN characters cs ON cs.guid = m.sender " - "INNER JOIN characters cr ON cr.guid = m.receiver " - "WHERE ii.itemEntry = '%u' LIMIT %u", - item_id, count); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_ITEMS_BY_ENTRY); + stmt->setUInt32(0, item_id); + stmt->setUInt32(1, count); + result = CharacterDatabase.Query(stmt); } else - result = QueryResult(NULL); + result = PreparedQueryResult(NULL); if (result) { @@ -514,21 +517,23 @@ bool ChatHandler::HandleListItemCommand(const char *args) // auction case uint32 auc_count = 0; - result=CharacterDatabase.PQuery("SELECT COUNT(itemEntry) FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid WHERE itemEntry = '%u'", item_id); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_COUNT_ITEM); + stmt->setUInt32(0, item_id); + result = CharacterDatabase.Query(stmt); + if (result) auc_count = (*result)[0].GetUInt32(); if (count > 0) { - result = CharacterDatabase.PQuery( - // 0 1 2 3 - "SELECT ah.itemguid, ah.itemowner, c.account, c.name FROM auctionhouse ah " - "INNER JOIN characters c ON c.guid = ah.itemowner " - "INNER JOIN item_instance ii ON ii.guid = ah.itemguid " - "WHERE ii.itemEntry = '%u' LIMIT %u", item_id, count); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY); + stmt->setUInt32(0, item_id); + stmt->setUInt32(1, count); + result = CharacterDatabase.Query(stmt); } else - result = QueryResult(NULL); + result = PreparedQueryResult(NULL); if (result) { @@ -549,17 +554,18 @@ bool ChatHandler::HandleListItemCommand(const char *args) // guild bank case uint32 guild_count = 0; - result = CharacterDatabase.PQuery("SELECT COUNT(itemEntry) FROM guild_bank_item gbi INNER JOIN item_instance ii ON ii.guid = gbi.item_guid WHERE itemEntry = '%u'", item_id); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_COUNT_ITEM); + stmt->setUInt32(0, item_id); + result = CharacterDatabase.Query(stmt); + if (result) guild_count = (*result)[0].GetUInt32(); - result = CharacterDatabase.PQuery( - // 0 1 2 - "SELECT gi.item_guid, gi.guildid, g.name FROM guild_bank_item gi " - "INNER JOIN guild g ON g.guildid = gi.guildid " - "INNER JOIN item_instance ii ON ii.guid = gi.item_guid " - "WHERE ii.itemEntry = '%u' LIMIT %u ", - item_id, count); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_ITEM_BY_ENTRY); + stmt->setUInt32(0, item_id); + stmt->setUInt32(1, count); + result = CharacterDatabase.Query(stmt); if (result) { @@ -1884,7 +1890,7 @@ bool ChatHandler::HandleDamageCommand(const char * args) { m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); if (target != m_session->GetPlayer()) - m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_HIT, 0); + m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_AFFECTS_VICTIM, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_HIT, 0); return true; } @@ -1914,7 +1920,7 @@ bool ChatHandler::HandleDamageCommand(const char * args) m_session->GetPlayer()->DealDamageMods(target, damage, &absorb); m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false); - m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_HIT, 0); + m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_AFFECTS_VICTIM, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_HIT, 0); return true; } @@ -3220,7 +3226,7 @@ bool ChatHandler::HandleBanListCharacterCommand(const char *args) std::string filter(cFilter); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_BY_NAME_FILTER); - stmt->setString(0, filter.c_str()); + stmt->setString(0, filter); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (!result) { @@ -3302,20 +3308,22 @@ bool ChatHandler::HandleBanListAccountCommand(const char *args) char* cFilter = strtok((char*)args, " "); std::string filter = cFilter ? cFilter : ""; - LoginDatabase.EscapeString(filter); - QueryResult result; + PreparedQueryResult result; if (filter.empty()) { - result = LoginDatabase.Query("SELECT account.id, username FROM account, account_banned" - " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id"); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BANNED_ALL); + + result = LoginDatabase.Query(stmt); } else { - result = LoginDatabase.PQuery("SELECT account.id, username FROM account, account_banned" - " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'", "'%s'", "'%%'")" GROUP BY account.id", - filter.c_str()); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BANNED_BY_USERNAME); + + stmt->setString(0, filter); + + result = LoginDatabase.Query(stmt); } if (!result) @@ -3327,7 +3335,7 @@ bool ChatHandler::HandleBanListAccountCommand(const char *args) return HandleBanListHelper(result); } -bool ChatHandler::HandleBanListHelper(QueryResult result) +bool ChatHandler::HandleBanListHelper(PreparedQueryResult result) { PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT); @@ -3410,19 +3418,21 @@ bool ChatHandler::HandleBanListIPCommand(const char *args) std::string filter = cFilter ? cFilter : ""; LoginDatabase.EscapeString(filter); - QueryResult result; + PreparedQueryResult result; if (filter.empty()) { - result = LoginDatabase.Query ("SELECT ip, bandate, unbandate, bannedby, banreason FROM ip_banned" - " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())" - " ORDER BY unbandate"); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED_ALL); + + result = LoginDatabase.Query(stmt); } else { - result = LoginDatabase.PQuery("SELECT ip, bandate, unbandate, bannedby, banreason FROM ip_banned" - " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'", "'%s'", "'%%'") - " ORDER BY unbandate", filter.c_str()); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED_BY_IP); + + stmt->setString(0, filter); + + result = LoginDatabase.Query(stmt); } if (!result) @@ -4619,8 +4629,11 @@ bool ChatHandler::HandleUnFreezeCommand(const char *args) { if (TargetName) { - //check for offline players - QueryResult result = CharacterDatabase.PQuery("SELECT characters.guid FROM characters WHERE characters.name = '%s'", name.c_str()); + // Check for offline players + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_GUID_BY_NAME); + stmt->setString(0, name); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) { SendSysMessage(LANG_COMMAND_FREEZE_WRONG); @@ -4630,7 +4643,10 @@ bool ChatHandler::HandleUnFreezeCommand(const char *args) Field* fields=result->Fetch(); uint64 pguid = fields[0].GetUInt64(); - CharacterDatabase.PQuery("DELETE FROM character_aura WHERE character_aura.spell = 9454 AND character_aura.guid = '%u'", pguid); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_AURA_FROZEN); + stmt->setUInt32(0, pguid); + CharacterDatabase.Execute(stmt); + PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str()); return true; } @@ -4646,8 +4662,11 @@ bool ChatHandler::HandleUnFreezeCommand(const char *args) bool ChatHandler::HandleListFreezeCommand(const char * /*args*/) { - //Get names from DB - QueryResult result = CharacterDatabase.Query("SELECT characters.name FROM characters LEFT JOIN character_aura ON (characters.guid = character_aura.guid) WHERE character_aura.spell = 9454"); + // Get names from DB + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_AURA_FROZEN); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) { SendSysMessage(LANG_COMMAND_NO_FROZEN_PLAYERS); diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 7fe6df14679..3fcabea4c74 100755 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -719,8 +719,8 @@ void ConditionMgr::LoadConditions(bool isReload) Condition* cond = new Condition(); int32 iSourceTypeOrReferenceId = fields[0].GetInt32(); cond->SourceGroup = fields[1].GetUInt32(); - cond->SourceEntry = fields[2].GetInt32(); - cond->SourceId = fields[3].GetUInt32(); + cond->SourceEntry = fields[2].GetUInt32(); + cond->SourceId = fields[3].GetInt32(); cond->ElseGroup = fields[4].GetUInt32(); int32 iConditionTypeOrReference = fields[5].GetInt32(); cond->ConditionTarget = fields[6].GetUInt8(); diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index e6039880b63..815861ff96a 100755 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -38,7 +38,8 @@ m_NumWaitTimeAvg(0), m_NumWaitTimeTank(0), m_NumWaitTimeHealer(0), m_NumWaitTime m_update = sWorld->getBoolConfig(CONFIG_DUNGEON_FINDER_ENABLE); if (m_update) { - new LFGScripts(); + new LFGPlayerScript(); + new LFGGroupScript(); // Initialize dungeon cache for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i) diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 2966e799c58..6175addfae2 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -27,9 +27,45 @@ #include "LFGScripts.h" #include "LFGMgr.h" -LFGScripts::LFGScripts(): GroupScript("LFGScripts"), PlayerScript("LFGScripts") {} +LFGPlayerScript::LFGPlayerScript() : PlayerScript("LFGPlayerScript") +{ +} + +void LFGPlayerScript::OnLevelChanged(Player* player, uint8 /*oldLevel*/) +{ + sLFGMgr->InitializeLockedDungeons(player); +} -void LFGScripts::OnAddMember(Group* group, uint64 guid) +void LFGPlayerScript::OnLogout(Player* player) +{ + sLFGMgr->Leave(player); + LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE); + player->GetSession()->SendLfgUpdateParty(updateData); + player->GetSession()->SendLfgUpdatePlayer(updateData); + player->GetSession()->SendLfgUpdateSearch(false); + uint64 guid = player->GetGUID(); + // TODO - Do not remove, add timer before deleting + sLFGMgr->RemovePlayerData(guid); +} + +void LFGPlayerScript::OnLogin(Player* player) +{ + sLFGMgr->InitializeLockedDungeons(player); + // TODO - Restore LfgPlayerData and send proper status to player if it was in a group +} + +void LFGPlayerScript::OnBindToInstance(Player* player, Difficulty difficulty, uint32 mapId, bool /*permanent*/) +{ + MapEntry const* mapEntry = sMapStore.LookupEntry(mapId); + if (mapEntry->IsDungeon() && difficulty > DUNGEON_DIFFICULTY_NORMAL) + sLFGMgr->InitializeLockedDungeons(player); +} + +LFGGroupScript::LFGGroupScript() : GroupScript("LFGGroupScript") +{ +} + +void LFGGroupScript::OnAddMember(Group* group, uint64 guid) { uint64 gguid = group->GetGUID(); if (!gguid) @@ -55,7 +91,7 @@ void LFGScripts::OnAddMember(Group* group, uint64 guid) sLFGMgr->Leave(player); } -void LFGScripts::OnRemoveMember(Group* group, uint64 guid, RemoveMethod method, uint64 kicker, const char* reason) +void LFGGroupScript::OnRemoveMember(Group* group, uint64 guid, RemoveMethod method, uint64 kicker, char const* reason) { uint64 gguid = group->GetGUID(); if (!gguid || method == GROUP_REMOVEMETHOD_DEFAULT) @@ -102,7 +138,7 @@ void LFGScripts::OnRemoveMember(Group* group, uint64 guid, RemoveMethod method, sLFGMgr->OfferContinue(group); } -void LFGScripts::OnDisband(Group* group) +void LFGGroupScript::OnDisband(Group* group) { uint64 gguid = group->GetGUID(); sLog->outDebug(LOG_FILTER_LFG, "LFGScripts::OnDisband [" UI64FMTD "]", gguid); @@ -110,7 +146,7 @@ void LFGScripts::OnDisband(Group* group) sLFGMgr->RemoveGroupData(gguid); } -void LFGScripts::OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid) +void LFGGroupScript::OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid) { uint64 gguid = group->GetGUID(); if (!gguid) @@ -131,7 +167,7 @@ void LFGScripts::OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLe } } -void LFGScripts::OnInviteMember(Group* group, uint64 guid) +void LFGGroupScript::OnInviteMember(Group* group, uint64 guid) { uint64 gguid = group->GetGUID(); if (!gguid) @@ -140,33 +176,3 @@ void LFGScripts::OnInviteMember(Group* group, uint64 guid) sLog->outDebug(LOG_FILTER_LFG, "LFGScripts::OnInviteMember [" UI64FMTD "]: invite [" UI64FMTD "] leader [" UI64FMTD "]", gguid, guid, group->GetLeaderGUID()); sLFGMgr->Leave(NULL, group); } - -void LFGScripts::OnLevelChanged(Player* player, uint8 /*oldLevel*/) -{ - sLFGMgr->InitializeLockedDungeons(player); -} - -void LFGScripts::OnLogout(Player* player) -{ - sLFGMgr->Leave(player); - LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE); - player->GetSession()->SendLfgUpdateParty(updateData); - player->GetSession()->SendLfgUpdatePlayer(updateData); - player->GetSession()->SendLfgUpdateSearch(false); - uint64 guid = player->GetGUID(); - // TODO - Do not remove, add timer before deleting - sLFGMgr->RemovePlayerData(guid); -} - -void LFGScripts::OnLogin(Player* player) -{ - sLFGMgr->InitializeLockedDungeons(player); - // TODO - Restore LfgPlayerData and send proper status to player if it was in a group -} - -void LFGScripts::OnBindToInstance(Player* player, Difficulty difficulty, uint32 mapId, bool /*permanent*/) -{ - MapEntry const* mapEntry = sMapStore.LookupEntry(mapId); - if (mapEntry->IsDungeon() && difficulty > DUNGEON_DIFFICULTY_NORMAL) - sLFGMgr->InitializeLockedDungeons(player); -} diff --git a/src/server/game/DungeonFinding/LFGScripts.h b/src/server/game/DungeonFinding/LFGScripts.h index f17f7b16af1..4b332c7d731 100644 --- a/src/server/game/DungeonFinding/LFGScripts.h +++ b/src/server/game/DungeonFinding/LFGScripts.h @@ -26,17 +26,10 @@ class Player; class Group; -class LFGScripts: public GroupScript, public PlayerScript +class LFGPlayerScript : public PlayerScript { public: - LFGScripts(); - - // Group Hooks - void OnAddMember(Group* group, uint64 guid); - void OnRemoveMember(Group* group, uint64 guid, RemoveMethod method, uint64 kicker, const char* reason); - void OnDisband(Group* group); - void OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid); - void OnInviteMember(Group* group, uint64 guid); + LFGPlayerScript(); // Player Hooks void OnLevelChanged(Player* player, uint8 oldLevel); @@ -44,3 +37,16 @@ class LFGScripts: public GroupScript, public PlayerScript void OnLogin(Player* player); void OnBindToInstance(Player* player, Difficulty difficulty, uint32 mapId, bool permanent); }; + +class LFGGroupScript : public GroupScript +{ + public: + LFGGroupScript(); + + // Group Hooks + void OnAddMember(Group* group, uint64 guid); + void OnRemoveMember(Group* group, uint64 guid, RemoveMethod method, uint64 kicker, char const* reason); + void OnDisband(Group* group); + void OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid); + void OnInviteMember(Group* group, uint64 guid); +}; diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 47225c65396..6a8ae07291a 100755 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -199,7 +199,7 @@ void Creature::RemoveFromWorld() if (m_zoneScript) m_zoneScript->OnCreatureRemove(this); if (m_formation) - FormationMgr::RemoveCreatureFromGroup(m_formation, this); + sFormationMgr->RemoveCreatureFromGroup(m_formation, this); Unit::RemoveFromWorld(); sObjectAccessor->RemoveObject(this); } @@ -224,9 +224,9 @@ void Creature::SearchFormation() if (!lowguid) return; - CreatureGroupInfoType::iterator frmdata = CreatureGroupMap.find(lowguid); - if (frmdata != CreatureGroupMap.end()) - FormationMgr::AddCreatureToGroup(frmdata->second->leaderGUID, this); + CreatureGroupInfoType::iterator frmdata = sFormationMgr->CreatureGroupMap.find(lowguid); + if (frmdata != sFormationMgr->CreatureGroupMap.end()) + sFormationMgr->AddCreatureToGroup(frmdata->second->leaderGUID, this); } void Creature::RemoveCorpse(bool setSpawnTime) @@ -433,8 +433,8 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData* data) in relation to DisableGravity also. else if (GetByteValue(UNIT_FIELD_BYTES_1, 3) & UNIT_BYTE_1_FLAG_HOVER) - SetHover(true); - + SetHover(true); + */ // TODO: Shouldn't we check whether or not the creature is in water first? @@ -758,16 +758,14 @@ bool Creature::Create(uint32 guidlow, Map* map, uint32 phaseMask, uint32 Entry, return false; } + //! Relocate before CreateFromProto, to initialize coords and allow + //! returning correct zone id for selecting OutdoorPvP/Battlefield script + Relocate(x, y, z, ang); + //oX = x; oY = y; dX = x; dY = y; m_moveTime = 0; m_startMove = 0; if (!CreateFromProto(guidlow, Entry, vehId, team, data)) return false; - //! Need to be called after CreateFromProto - if (HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) - z += GetFloatValue(UNIT_FIELD_HOVERHEIGHT); - - Relocate(x, y, z, ang); - if (!IsPositionValid()) { sLog->outError("Creature::Create(): given coordinates for creature (guidlow %d, entry %d) are not valid (X: %f, Y: %f, Z: %f, O: %f)", guidlow, Entry, x, y, z, ang); @@ -794,6 +792,14 @@ bool Creature::Create(uint32 guidlow, Map* map, uint32 phaseMask, uint32 Entry, } LoadCreaturesAddon(); + + //! Need to be called after LoadCreaturesAddon - MOVEMENTFLAG_HOVER is set there + if (HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) + z += GetFloatValue(UNIT_FIELD_HOVERHEIGHT); + + //! Relocate again with updated Z coord + Relocate(x, y, z, ang); + uint32 displayID = GetNativeDisplayId(); CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelRandomGender(&displayID); if (minfo && !isTotem()) // Cancel load if no model defined or if totem @@ -1093,32 +1099,34 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) // update in DB SQLTransaction trans = WorldDatabase.BeginTransaction(); - trans->PAppend("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid); - - std::ostringstream ss; - ss << "INSERT INTO creature VALUES (" - << m_DBTableGuid << ',' - << GetEntry() << ',' - << mapid << ',' - << uint32(spawnMask) << ',' // cast to prevent save as symbol - << uint16(GetPhaseMask()) << ',' // prevent out of range error - << displayId << ',' - << GetEquipmentId() << ',' - << GetPositionX() << ',' - << GetPositionY() << ',' - << GetPositionZ() << ',' - << GetOrientation() << ',' - << m_respawnDelay << ',' //respawn time - << (float) m_respawnradius << ',' //spawn distance (float) - << (uint32) (0) << ',' //currentwaypoint - << GetHealth() << ',' //curhealth - << GetPower(POWER_MANA) << ',' //curmana - << GetDefaultMovementType() << ',' //default movement generator type - << npcflag << ',' - << unit_flags << ',' - << dynamicflags << ')'; - - trans->Append(ss.str().c_str()); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); + stmt->setUInt32(0, m_DBTableGuid); + trans->Append(stmt); + + uint8 index = 0; + + stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_CREATURE); + stmt->setUInt32(index++, m_DBTableGuid); + stmt->setUInt32(index++, GetEntry()); + stmt->setUInt16(index++, uint16(mapid)); + stmt->setUInt8(index++, spawnMask); + stmt->setUInt16(index++, uint16(GetPhaseMask())); + stmt->setUInt32(index++, displayId); + stmt->setInt32(index++, int32(GetEquipmentId())); + stmt->setFloat(index++, GetPositionX()); + stmt->setFloat(index++, GetPositionY()); + stmt->setFloat(index++, GetPositionZ()); + stmt->setFloat(index++, GetOrientation()); + stmt->setUInt32(index++, m_respawnDelay); + stmt->setFloat(index++, m_respawnradius); + stmt->setUInt32(index++, 0); + stmt->setUInt32(index++, GetHealth()); + stmt->setUInt32(index++, GetPower(POWER_MANA)); + stmt->setUInt8(index++, uint8(GetDefaultMovementType())); + stmt->setUInt32(index++, npcflag); + stmt->setUInt32(index++, unit_flags); + stmt->setUInt32(index, dynamicflags); + trans->Append(stmt); WorldDatabase.CommitTransaction(trans); } @@ -1391,10 +1399,23 @@ void Creature::DeleteFromDB() sObjectMgr->DeleteCreatureData(m_DBTableGuid); SQLTransaction trans = WorldDatabase.BeginTransaction(); - trans->PAppend("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid); - trans->PAppend("DELETE FROM creature_addon WHERE guid = '%u'", m_DBTableGuid); - trans->PAppend("DELETE FROM game_event_creature WHERE guid = '%u'", m_DBTableGuid); - trans->PAppend("DELETE FROM game_event_model_equip WHERE guid = '%u'", m_DBTableGuid); + + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); + stmt->setUInt32(0, m_DBTableGuid); + trans->Append(stmt); + + stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE_ADDON); + stmt->setUInt32(0, m_DBTableGuid); + trans->Append(stmt); + + stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAME_EVENT_CREATURE); + stmt->setUInt32(0, m_DBTableGuid); + trans->Append(stmt); + + stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAME_EVENT_MODEL_EQUIP); + stmt->setUInt32(0, m_DBTableGuid); + trans->Append(stmt); + WorldDatabase.CommitTransaction(trans); } diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp index c95d77db358..2104f474072 100755 --- a/src/server/game/Entities/Creature/CreatureGroups.cpp +++ b/src/server/game/Entities/Creature/CreatureGroups.cpp @@ -24,12 +24,13 @@ #define MAX_DESYNC 5.0f -CreatureGroupInfoType CreatureGroupMap; - -namespace FormationMgr +FormationMgr::~FormationMgr() { + for (CreatureGroupInfoType::iterator itr = CreatureGroupMap.begin(); itr != CreatureGroupMap.end(); ++itr) + delete itr->second; +} -void AddCreatureToGroup(uint32 groupId, Creature* member) +void FormationMgr::AddCreatureToGroup(uint32 groupId, Creature* member) { Map* map = member->FindMap(); if (!map) @@ -53,7 +54,7 @@ void AddCreatureToGroup(uint32 groupId, Creature* member) } } -void RemoveCreatureFromGroup(CreatureGroup* group, Creature* member) +void FormationMgr::RemoveCreatureFromGroup(CreatureGroup* group, Creature* member) { sLog->outDebug(LOG_FILTER_UNITS, "Deleting member pointer to GUID: %u from group %u", group->GetId(), member->GetDBTableGUIDLow()); group->RemoveMember(member); @@ -70,7 +71,7 @@ void RemoveCreatureFromGroup(CreatureGroup* group, Creature* member) } } -void LoadCreatureFormations() +void FormationMgr::LoadCreatureFormations() { uint32 oldMSTime = getMSTime(); @@ -97,10 +98,10 @@ void LoadCreatureFormations() fields = result->Fetch(); //Load group member data - group_member = new FormationInfo; + group_member = new FormationInfo(); group_member->leaderGUID = fields[0].GetUInt32(); uint32 memberGUID = fields[1].GetUInt32(); - group_member->groupAI = fields[4].GetUInt8(); + group_member->groupAI = fields[4].GetUInt32(); //If creature is group leader we may skip loading of dist/angle if (group_member->leaderGUID != memberGUID) { @@ -139,8 +140,6 @@ void LoadCreatureFormations() sLog->outString(); } -} // Namespace - void CreatureGroup::AddMember(Creature* member) { sLog->outDebug(LOG_FILTER_UNITS, "CreatureGroup::AddMember: Adding unit GUID: %u.", member->GetGUIDLow()); @@ -152,7 +151,7 @@ void CreatureGroup::AddMember(Creature* member) m_leader = member; } - m_members[member] = CreatureGroupMap.find(member->GetDBTableGUIDLow())->second; + m_members[member] = sFormationMgr->CreatureGroupMap.find(member->GetDBTableGUIDLow())->second; member->SetFormation(this); } @@ -167,7 +166,7 @@ void CreatureGroup::RemoveMember(Creature* member) void CreatureGroup::MemberAttackStart(Creature* member, Unit* target) { - uint8 groupAI = CreatureGroupMap[member->GetDBTableGUIDLow()]->groupAI; + uint8 groupAI = sFormationMgr->CreatureGroupMap[member->GetDBTableGUIDLow()]->groupAI; if (!groupAI) return; diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h index 80e552f7e93..e5b8771ee40 100755 --- a/src/server/game/Entities/Creature/CreatureGroups.h +++ b/src/server/game/Entities/Creature/CreatureGroups.h @@ -34,16 +34,19 @@ struct FormationInfo uint8 groupAI; }; -namespace FormationMgr -{ - void AddCreatureToGroup(uint32 group_id, Creature* creature); - void RemoveCreatureFromGroup(CreatureGroup* group, Creature* creature); - void LoadCreatureFormations(); -}; - typedef UNORDERED_MAP<uint32/*memberDBGUID*/, FormationInfo*> CreatureGroupInfoType; -extern CreatureGroupInfoType CreatureGroupMap; +class FormationMgr +{ + friend class ACE_Singleton<FormationMgr, ACE_Null_Mutex>; + public: + FormationMgr() { } + ~FormationMgr(); + void AddCreatureToGroup(uint32 group_id, Creature* creature); + void RemoveCreatureFromGroup(CreatureGroup* group, Creature* creature); + void LoadCreatureFormations(); + CreatureGroupInfoType CreatureGroupMap; +}; class CreatureGroup { @@ -73,4 +76,6 @@ class CreatureGroup void MemberAttackStart(Creature* member, Unit* target); }; +#define sFormationMgr ACE_Singleton<FormationMgr, ACE_Null_Mutex>::instance() + #endif diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 1cd8fa17183..910e9c86b42 100755 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -686,29 +686,34 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) data.spawnMask = spawnMask; data.artKit = GetGoArtKit(); - // update in DB - std::ostringstream ss; - ss << "INSERT INTO gameobject VALUES (" - << m_DBTableGuid << ',' - << GetEntry() << ',' - << mapid << ',' - << uint32(spawnMask) << ',' // cast to prevent save as symbol - << uint16(GetPhaseMask()) << ',' // prevent out of range error - << GetPositionX() << ',' - << GetPositionY() << ',' - << GetPositionZ() << ',' - << GetOrientation() << ',' - << GetFloatValue(GAMEOBJECT_PARENTROTATION) << ',' - << GetFloatValue(GAMEOBJECT_PARENTROTATION+1) << ',' - << GetFloatValue(GAMEOBJECT_PARENTROTATION+2) << ',' - << GetFloatValue(GAMEOBJECT_PARENTROTATION+3) << ',' - << m_respawnDelayTime << ',' - << uint32(GetGoAnimProgress()) << ',' - << uint32(GetGoState()) << ')'; - + // Update in DB SQLTransaction trans = WorldDatabase.BeginTransaction(); - trans->PAppend("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid); - trans->Append(ss.str().c_str()); + + uint8 index = 0; + + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT); + stmt->setUInt32(0, m_DBTableGuid); + trans->Append(stmt); + + stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_GAMEOBJECT); + stmt->setUInt32(index++, m_DBTableGuid); + stmt->setUInt32(index++, GetEntry()); + stmt->setUInt16(index++, uint16(mapid)); + stmt->setUInt8(index++, spawnMask); + stmt->setUInt16(index++, uint16(GetPhaseMask())); + stmt->setFloat(index++, GetPositionX()); + stmt->setFloat(index++, GetPositionY()); + stmt->setFloat(index++, GetPositionZ()); + stmt->setFloat(index++, GetOrientation()); + stmt->setFloat(index++, GetFloatValue(GAMEOBJECT_PARENTROTATION)); + stmt->setFloat(index++, GetFloatValue(GAMEOBJECT_PARENTROTATION+1)); + stmt->setFloat(index++, GetFloatValue(GAMEOBJECT_PARENTROTATION+2)); + stmt->setFloat(index++, GetFloatValue(GAMEOBJECT_PARENTROTATION+3)); + stmt->setInt32(index++, int32(m_respawnDelayTime)); + stmt->setUInt8(index++, GetGoAnimProgress()); + stmt->setUInt8(index++, uint8(GetGoState())); + trans->Append(stmt); + WorldDatabase.CommitTransaction(trans); } diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 90f6f4a217c..4a1d5d5749a 100755 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -1082,16 +1082,30 @@ void Item::BuildUpdate(UpdateDataMapType& data_map) void Item::SaveRefundDataToDB() { SQLTransaction trans = CharacterDatabase.BeginTransaction(); - trans->PAppend("DELETE FROM item_refund_instance WHERE item_guid = '%u'", GetGUIDLow()); - trans->PAppend("INSERT INTO item_refund_instance (`item_guid`, `player_guid`, `paidMoney`, `paidExtendedCost`)" - " VALUES('%u', '%u', '%u', '%u')", GetGUIDLow(), GetRefundRecipient(), GetPaidMoney(), GetPaidExtendedCost()); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_REFUND_INSTANCE); + stmt->setUInt32(0, GetGUIDLow()); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ITEM_REFUND_INSTANCE); + stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetRefundRecipient()); + stmt->setUInt32(0, GetPaidMoney()); + stmt->setUInt16(0, uint16(GetPaidExtendedCost())); + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); } void Item::DeleteRefundDataFromDB(SQLTransaction* trans) { if (trans && !trans->null()) - (*trans)->PAppend("DELETE FROM item_refund_instance WHERE item_guid = '%u'", GetGUIDLow()); + { + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_REFUND_INSTANCE); + stmt->setUInt32(0, GetGUIDLow()); + (*trans)->Append(stmt); + + } } void Item::SetNotRefundable(Player* owner, bool changestate /*=true*/, SQLTransaction* trans /*=NULL*/) diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 1a3c1a3fbb3..d51af9e1ba9 100755 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -97,30 +97,42 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petentry, uint32 petnumber, bool c uint32 ownerid = owner->GetGUIDLow(); - QueryResult result; + PreparedStatement* stmt; + PreparedQueryResult result; if (petnumber) - // known petnumber entry 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType " - "FROM character_pet WHERE owner = '%u' AND id = '%u'", - ownerid, petnumber); + { + // Known petnumber entry + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PET_BY_ENTRY); + stmt->setUInt32(0, ownerid); + stmt->setUInt32(1, petnumber); + } else if (current) - // current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType " - "FROM character_pet WHERE owner = '%u' AND slot = '%u'", - ownerid, PET_SAVE_AS_CURRENT); + { + // Current pet (slot 0) + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT); + stmt->setUInt32(0, ownerid); + stmt->setUInt8(1, uint8(PET_SAVE_AS_CURRENT)); + } else if (petentry) + { // known petentry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets) - // 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType " - "FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '%u' OR slot > '%u') ", - ownerid, petentry, PET_SAVE_AS_CURRENT, PET_SAVE_LAST_STABLE_SLOT); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT_2); + stmt->setUInt32(0, ownerid); + stmt->setUInt32(1, petentry); + stmt->setUInt8(2, uint8(PET_SAVE_AS_CURRENT)); + stmt->setUInt8(3, uint8(PET_SAVE_LAST_STABLE_SLOT)); + } else - // any current or other non-stabled pet (for hunter "call pet") - // 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType " - "FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u') ", - ownerid, PET_SAVE_AS_CURRENT, PET_SAVE_LAST_STABLE_SLOT); + { + // Any current or other non-stabled pet (for hunter "call pet") + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PET_BY_SLOT); + stmt->setUInt32(0, ownerid); + stmt->setUInt8(1, uint8(PET_SAVE_AS_CURRENT)); + stmt->setUInt8(2, uint8(PET_SAVE_LAST_STABLE_SLOT)); + } + + result = CharacterDatabase.Query(stmt); if (!result) { @@ -254,10 +266,20 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petentry, uint32 petnumber, bool c if (fields[7].GetUInt8()) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); - trans->PAppend("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u' AND id <> '%u'", - PET_SAVE_NOT_IN_SLOT, ownerid, PET_SAVE_AS_CURRENT, m_charmInfo->GetPetNumber()); - trans->PAppend("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND id = '%u'", - PET_SAVE_AS_CURRENT, ownerid, m_charmInfo->GetPetNumber()); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID); + stmt->setUInt8(0, uint8(PET_SAVE_NOT_IN_SLOT)); + stmt->setUInt32(1, ownerid); + stmt->setUInt8(2, uint8(PET_SAVE_AS_CURRENT)); + stmt->setUInt32(3, m_charmInfo->GetPetNumber()); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_SLOT_BY_ID); + stmt->setUInt8(0, uint8(PET_SAVE_AS_CURRENT)); + stmt->setUInt32(1, ownerid); + stmt->setUInt32(2, m_charmInfo->GetPetNumber()); + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); } @@ -310,7 +332,10 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petentry, uint32 petnumber, bool c if (getPetType() == HUNTER_PET) { - result = CharacterDatabase.PQuery("SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE owner = '%u' AND id = '%u'", owner->GetGUIDLow(), GetCharmInfo()->GetPetNumber()); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_DECLINED_NAME); + stmt->setUInt32(0, owner->GetGUIDLow()); + stmt->setUInt32(1, GetCharmInfo()->GetPetNumber()); + PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { @@ -385,17 +410,31 @@ void Pet::SavePetToDB(PetSaveMode mode) CharacterDatabase.EscapeString(name); trans = CharacterDatabase.BeginTransaction(); // remove current data - trans->PAppend("DELETE FROM character_pet WHERE owner = '%u' AND id = '%u'", ownerLowGUID, m_charmInfo->GetPetNumber()); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_BY_ID); + stmt->setUInt32(0, m_charmInfo->GetPetNumber()); + trans->Append(stmt); // prevent duplicate using slot (except PET_SAVE_NOT_IN_SLOT) if (mode <= PET_SAVE_LAST_STABLE_SLOT) - trans->PAppend("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u'", - PET_SAVE_NOT_IN_SLOT, ownerLowGUID, uint32(mode)); + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_PET_SLOT_BY_SLOT); + stmt->setUInt8(0, uint8(PET_SAVE_NOT_IN_SLOT)); + stmt->setUInt32(1, ownerLowGUID); + stmt->setUInt8(2, uint8(mode)); + trans->Append(stmt); + } // prevent existence another hunter pet in PET_SAVE_AS_CURRENT and PET_SAVE_NOT_IN_SLOT if (getPetType() == HUNTER_PET && (mode == PET_SAVE_AS_CURRENT || mode > PET_SAVE_LAST_STABLE_SLOT)) - trans->PAppend("DELETE FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u')", - ownerLowGUID, PET_SAVE_AS_CURRENT, PET_SAVE_LAST_STABLE_SLOT); + { + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_BY_SLOT); + stmt->setUInt32(0, ownerLowGUID); + stmt->setUInt8(1, uint8(PET_SAVE_AS_CURRENT)); + stmt->setUInt8(2, uint8(PET_SAVE_LAST_STABLE_SLOT)); + trans->Append(stmt); + } + // save pet std::ostringstream ss; ss << "INSERT INTO character_pet (id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType) " @@ -417,7 +456,7 @@ void Pet::SavePetToDB(PetSaveMode mode) for (uint32 i = ACTION_BAR_INDEX_START; i < ACTION_BAR_INDEX_END; ++i) { ss << uint32(m_charmInfo->GetActionBarEntry(i)->GetType()) << ' ' - << uint32(m_charmInfo->GetActionBarEntry(i)->GetAction()) << ' '; + << uint32(m_charmInfo->GetActionBarEntry(i)->GetAction()) << ' '; }; ss << "', " @@ -439,11 +478,27 @@ void Pet::SavePetToDB(PetSaveMode mode) void Pet::DeleteFromDB(uint32 guidlow) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); - trans->PAppend("DELETE FROM character_pet WHERE id = '%u'", guidlow); - trans->PAppend("DELETE FROM character_pet_declinedname WHERE id = '%u'", guidlow); - trans->PAppend("DELETE FROM pet_aura WHERE guid = '%u'", guidlow); - trans->PAppend("DELETE FROM pet_spell WHERE guid = '%u'", guidlow); - trans->PAppend("DELETE FROM pet_spell_cooldown WHERE guid = '%u'", guidlow); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_BY_ID); + stmt->setUInt32(0, guidlow); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME); + stmt->setUInt32(0, guidlow); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_AURAS); + stmt->setUInt32(0, guidlow); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELLS); + stmt->setUInt32(0, guidlow); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELL_COOLDOWNS); + stmt->setUInt32(0, guidlow); + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); } @@ -912,7 +967,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) SetCreateHealth(40*petlevel); SetCreateMana(28 + 10*petlevel); } - SetBonusDamage(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FIRE) * 0.5f); + SetBonusDamage(int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FIRE) * 0.5f)); SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 4 - petlevel)); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 4 + petlevel)); break; @@ -1037,7 +1092,9 @@ void Pet::_LoadSpellCooldowns() m_CreatureSpellCooldowns.clear(); m_CreatureCategoryCooldowns.clear(); - QueryResult result = CharacterDatabase.PQuery("SELECT spell, time FROM pet_spell_cooldown WHERE guid = '%u'", m_charmInfo->GetPetNumber()); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SPELL_COOLDOWN); + stmt->setUInt32(0, m_charmInfo->GetPetNumber()); + PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { @@ -1080,7 +1137,9 @@ void Pet::_LoadSpellCooldowns() void Pet::_SaveSpellCooldowns(SQLTransaction& trans) { - trans->PAppend("DELETE FROM pet_spell_cooldown WHERE guid = '%u'", m_charmInfo->GetPetNumber()); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELL_COOLDOWNS); + stmt->setUInt32(0, m_charmInfo->GetPetNumber()); + trans->Append(stmt); time_t curTime = time(NULL); @@ -1091,7 +1150,12 @@ void Pet::_SaveSpellCooldowns(SQLTransaction& trans) m_CreatureSpellCooldowns.erase(itr++); else { - trans->PAppend("INSERT INTO pet_spell_cooldown (guid, spell, time) VALUES ('%u', '%u', '%u')", m_charmInfo->GetPetNumber(), itr->first, uint32(itr->second)); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PET_SPELL_COOLDOWN); + stmt->setUInt32(0, m_charmInfo->GetPetNumber()); + stmt->setUInt32(1, itr->first); + stmt->setUInt32(2, uint32(itr->second)); + trans->Append(stmt); + ++itr; } } @@ -1099,7 +1163,9 @@ void Pet::_SaveSpellCooldowns(SQLTransaction& trans) void Pet::_LoadSpells() { - QueryResult result = CharacterDatabase.PQuery("SELECT spell, active FROM pet_spell WHERE guid = '%u'", m_charmInfo->GetPetNumber()); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SPELL); + stmt->setUInt32(0, m_charmInfo->GetPetNumber()); + PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { @@ -1123,18 +1189,37 @@ void Pet::_SaveSpells(SQLTransaction& trans) if (itr->second.type == PETSPELL_FAMILY) continue; + PreparedStatement* stmt; + switch (itr->second.state) { case PETSPELL_REMOVED: - trans->PAppend("DELETE FROM pet_spell WHERE guid = '%u' and spell = '%u'", m_charmInfo->GetPetNumber(), itr->first); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELL_BY_SPELL); + stmt->setUInt32(0, m_charmInfo->GetPetNumber()); + stmt->setUInt32(1, itr->first); + trans->Append(stmt); + m_spells.erase(itr); continue; case PETSPELL_CHANGED: - trans->PAppend("DELETE FROM pet_spell WHERE guid = '%u' and spell = '%u'", m_charmInfo->GetPetNumber(), itr->first); - trans->PAppend("INSERT INTO pet_spell (guid, spell, active) VALUES ('%u', '%u', '%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second.active); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELL_BY_SPELL); + stmt->setUInt32(0, m_charmInfo->GetPetNumber()); + stmt->setUInt32(1, itr->first); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PET_SPELL); + stmt->setUInt32(0, m_charmInfo->GetPetNumber()); + stmt->setUInt32(1, itr->first); + stmt->setUInt8(2, itr->second.active); + trans->Append(stmt); + break; case PETSPELL_NEW: - trans->PAppend("INSERT INTO pet_spell (guid, spell, active) VALUES ('%u', '%u', '%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second.active); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PET_SPELL); + stmt->setUInt32(0, m_charmInfo->GetPetNumber()); + stmt->setUInt32(1, itr->first); + stmt->setUInt8(2, itr->second.active); + trans->Append(stmt); break; case PETSPELL_UNCHANGED: continue; @@ -1147,7 +1232,9 @@ void Pet::_LoadAuras(uint32 timediff) { sLog->outDebug(LOG_FILTER_PETS, "Loading auras for pet %u", GetGUIDLow()); - QueryResult result = CharacterDatabase.PQuery("SELECT caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges FROM pet_aura WHERE guid = '%u'", m_charmInfo->GetPetNumber()); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_AURA); + stmt->setUInt32(0, m_charmInfo->GetPetNumber()); + PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { @@ -1217,7 +1304,9 @@ void Pet::_LoadAuras(uint32 timediff) void Pet::_SaveAuras(SQLTransaction& trans) { - trans->PAppend("DELETE FROM pet_aura WHERE guid = '%u'", m_charmInfo->GetPetNumber()); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_AURAS); + stmt->setUInt32(0, m_charmInfo->GetPetNumber()); + trans->Append(stmt); for (AuraMap::const_iterator itr = m_ownedAuras.begin(); itr != m_ownedAuras.end() ; ++itr) { @@ -1251,11 +1340,26 @@ void Pet::_SaveAuras(SQLTransaction& trans) // don't save guid of caster in case we are caster of the spell - guid for pet is generated every pet load, so it won't match saved guid anyways uint64 casterGUID = (itr->second->GetCasterGUID() == GetGUID()) ? 0 : itr->second->GetCasterGUID(); - trans->PAppend("INSERT INTO pet_aura (guid, caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges) " - "VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u')", - m_charmInfo->GetPetNumber(), casterGUID, itr->second->GetId(), effMask, recalculateMask, - itr->second->GetStackAmount(), damage[0], damage[1], damage[2], baseDamage[0], baseDamage[1], baseDamage[2], - itr->second->GetMaxDuration(), itr->second->GetDuration(), itr->second->GetCharges()); + uint8 index = 0; + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PET_AURA); + stmt->setUInt32(index++, m_charmInfo->GetPetNumber()); + stmt->setUInt64(index++, casterGUID); + stmt->setUInt32(index++, itr->second->GetId()); + stmt->setUInt8(index++, effMask); + stmt->setUInt8(index++, recalculateMask); + stmt->setUInt8(index++, itr->second->GetStackAmount()); + stmt->setInt32(index++, damage[0]); + stmt->setInt32(index++, damage[1]); + stmt->setInt32(index++, damage[2]); + stmt->setInt32(index++, baseDamage[0]); + stmt->setInt32(index++, baseDamage[1]); + stmt->setInt32(index++, baseDamage[2]); + stmt->setInt32(index++, itr->second->GetMaxDuration()); + stmt->setInt32(index++, itr->second->GetDuration()); + stmt->setUInt8(index++, itr->second->GetCharges()); + + trans->Append(stmt); } } @@ -1630,18 +1734,19 @@ void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* online_pet /*= NULL*/) // now need only reset for offline pets (all pets except online case) uint32 except_petnumber = online_pet ? online_pet->GetCharmInfo()->GetPetNumber() : 0; - QueryResult resultPets = CharacterDatabase.PQuery( - "SELECT id FROM character_pet WHERE owner = '%u' AND id <> '%u'", - owner->GetGUIDLow(), except_petnumber); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PET); + stmt->setUInt32(0, owner->GetGUIDLow()); + stmt->setUInt32(1, except_petnumber); + PreparedQueryResult resultPets = CharacterDatabase.Query(stmt); // no offline pets if (!resultPets) return; - QueryResult result = CharacterDatabase.PQuery( - "SELECT DISTINCT pet_spell.spell FROM pet_spell, character_pet " - "WHERE character_pet.owner = '%u' AND character_pet.id = pet_spell.guid AND character_pet.id <> %u", - owner->GetGUIDLow(), except_petnumber); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SPELL_LIST); + stmt->setUInt32(0, owner->GetGUIDLow()); + stmt->setUInt32(0, except_petnumber); + PreparedQueryResult result = CharacterDatabase.Query(stmt); if (!result) return; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index bd5b1010f45..de66362aa27 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -1911,7 +1911,7 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data) uint32 charFlags = 0; uint32 playerFlags = fields[14].GetUInt32(); - uint32 atLoginFlags = fields[15].GetUInt32(); + uint16 atLoginFlags = fields[15].GetUInt16(); if (playerFlags & PLAYER_FLAGS_HIDE_HELM) charFlags |= CHARACTER_FLAG_HIDE_HELM; if (playerFlags & PLAYER_FLAGS_HIDE_CLOAK) @@ -4305,7 +4305,9 @@ void Player::_LoadSpellCooldowns(PreparedQueryResult result) void Player::_SaveSpellCooldowns(SQLTransaction& trans) { - trans->PAppend("DELETE FROM character_spell_cooldown WHERE guid = '%u'", GetGUIDLow()); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SPELL_COOLDOWN); + stmt->setUInt32(0, GetGUIDLow()); + trans->Append(stmt); time_t curTime = time(NULL); time_t infTime = curTime + infinityCooldownDelayCheck; @@ -4787,7 +4789,10 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC LeaveAllArenaTeams(playerguid); // the player was uninvited already on logout so just remove from group - QueryResult resultGroup = CharacterDatabase.PQuery("SELECT guid FROM group_member WHERE memberGuid=%u", guid); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GROUP_MEMBER); + stmt->setUInt32(0, guid); + PreparedQueryResult resultGroup = CharacterDatabase.Query(stmt); + if (resultGroup) if (Group* group = sGroupMgr->GetGroupByDbStoreId((*resultGroup)[0].GetUInt32())) RemoveFromGroup(group, playerguid); @@ -4801,8 +4806,11 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC case CHAR_DELETE_REMOVE: { SQLTransaction trans = CharacterDatabase.BeginTransaction(); - // Return back all mails with COD and Item 0 1 2 3 4 5 6 7 - QueryResult resultMail = CharacterDatabase.PQuery("SELECT id, messageType, mailTemplateId, sender, subject, body, money, has_items FROM mail WHERE receiver='%u' AND has_items<>0 AND cod<>0", guid); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_COD_ITEM_MAIL); + stmt->setUInt32(0, guid); + PreparedQueryResult resultMail = CharacterDatabase.Query(stmt); + if (resultMail) { do @@ -4820,13 +4828,19 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC // We can return mail now // So firstly delete the old one - trans->PAppend("DELETE FROM mail WHERE id = '%u'", mail_id); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_BY_ID); + stmt->setUInt32(0, mail_id); + trans->Append(stmt); // Mail is not from player if (mailType != MAIL_NORMAL) { if (has_items) - trans->PAppend("DELETE FROM mail_items WHERE mail_id = '%u'", mail_id); + { + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM_BY_ID); + stmt->setUInt32(0, mail_id); + trans->Append(stmt); + } continue; } @@ -4871,7 +4885,9 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC } } - trans->PAppend("DELETE FROM mail_items WHERE mail_id = '%u'", mail_id); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM_BY_ID); + stmt->setUInt32(0, mail_id); + trans->Append(stmt); uint32 pl_account = sObjectMgr->GetPlayerAccountIdByGUID(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)); @@ -4882,7 +4898,11 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC // Unsummon and delete for pets in world is not required: player deleted from CLI or character list with not loaded pet. // NOW we can finally clear other DB data related to character - if (QueryResult resultPets = CharacterDatabase.PQuery("SELECT id FROM character_pet WHERE owner = '%u'", guid)) + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PETS); + stmt->setUInt32(0, guid); + PreparedQueryResult resultPets = CharacterDatabase.Query(stmt); + + if (resultPets) { do { @@ -4892,7 +4912,11 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC } // Delete char from social list of online chars - if (QueryResult resultFriends = CharacterDatabase.PQuery("SELECT DISTINCT guid FROM character_social WHERE friend = '%u'", guid)) + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_SOCIAL); + stmt->setUInt32(0, guid); + PreparedQueryResult resultFriends = CharacterDatabase.Query(stmt); + + if (resultFriends) { do { @@ -4907,48 +4931,134 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC } while (resultFriends->NextRow()); } - trans->PAppend("DELETE FROM characters WHERE guid = '%u'", guid); - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_ACCOUNT_DATA); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_ACCOUNT_DATA); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_DECLINED_NAME); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACTION); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_AURA); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_GIFT); stmt->setUInt32(0, guid); trans->Append(stmt); - trans->PAppend("DELETE FROM character_declinedname WHERE guid = '%u'", guid); - trans->PAppend("DELETE FROM character_action WHERE guid = '%u'", guid); - trans->PAppend("DELETE FROM character_aura WHERE guid = '%u'", guid); - trans->PAppend("DELETE FROM character_gifts WHERE guid = '%u'", guid); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_HOMEBIND); stmt->setUInt32(0, guid); trans->Append(stmt); - trans->PAppend("DELETE FROM character_instance WHERE guid = '%u'", guid); - trans->PAppend("DELETE FROM character_inventory WHERE guid = '%u'", guid); - trans->PAppend("DELETE FROM character_queststatus WHERE guid = '%u'", guid); - trans->PAppend("DELETE FROM character_queststatus_rewarded WHERE guid = '%u'", guid); - trans->PAppend("DELETE FROM character_reputation WHERE guid = '%u'", guid); - trans->PAppend("DELETE FROM character_spell WHERE guid = '%u'", guid); - trans->PAppend("DELETE FROM character_spell_cooldown WHERE guid = '%u'", guid); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INSTANCE); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INVENTORY); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS_REWARDED); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_REPUTATION); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SPELL); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SPELL_COOLDOWN); + stmt->setUInt32(0, guid); + trans->Append(stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_GM_TICKETS); stmt->setUInt32(0, guid); trans->Append(stmt); - trans->PAppend("DELETE FROM item_instance WHERE owner_guid = '%u'", guid); - trans->PAppend("DELETE FROM character_social WHERE guid = '%u' OR friend='%u'", guid, guid); - trans->PAppend("DELETE FROM mail WHERE receiver = '%u'", guid); - trans->PAppend("DELETE FROM mail_items WHERE receiver = '%u'", guid); - trans->PAppend("DELETE FROM character_pet WHERE owner = '%u'", guid); - trans->PAppend("DELETE FROM character_pet_declinedname WHERE owner = '%u'", guid); - trans->PAppend("DELETE FROM character_achievement WHERE guid = '%u' " // NOTE: These achievements have flags & 256 in DBC. - "AND achievement NOT BETWEEN '456' AND '467' " // Realm First Level 80 - "AND achievement NOT BETWEEN '1400' AND '1427' " // Realm First Raid Achievements - "AND achievement NOT IN(1463, 3117, 3259) ", guid); // Realm First Northen Vanguard + Raid Achievements - trans->PAppend("DELETE FROM character_achievement_progress WHERE guid = '%u'", guid); - trans->PAppend("DELETE FROM character_equipmentsets WHERE guid = '%u'", guid); - trans->PAppend("DELETE FROM guild_eventlog WHERE PlayerGuid1 = '%u' OR PlayerGuid2 = '%u'", guid, guid); - trans->PAppend("DELETE FROM guild_bank_eventlog WHERE PlayerGuid = '%u'", guid); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SOCIAL_BY_FRIEND); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SOCIAL_BY_GUID); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEMS); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_BY_OWNER); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME_BY_OWNER); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENTS); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_EQUIPMENTSETS); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_EVENTLOG_BY_PLAYER); + stmt->setUInt32(0, guid); + stmt->setUInt32(1, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_EVENTLOG_BY_PLAYER); + stmt->setUInt32(0, guid); + trans->Append(stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_BGDATA); stmt->setUInt32(0, guid); trans->Append(stmt); - trans->PAppend("DELETE FROM character_glyphs WHERE guid = '%u'", guid); - trans->PAppend("DELETE FROM character_queststatus_daily WHERE guid = '%u'", guid); - trans->PAppend("DELETE FROM character_talent WHERE guid = '%u'", guid); - trans->PAppend("DELETE FROM character_skills WHERE guid = '%u'", guid); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_GLYPHS); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS_DAILY); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_TALENT); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SKILLS); + stmt->setUInt32(0, guid); + trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); break; @@ -4996,15 +5106,19 @@ void Player::DeleteOldCharacters(uint32 keepDays) { sLog->outString("Player::DeleteOldChars: Deleting all characters which have been deleted %u days before...", keepDays); - QueryResult resultChars = CharacterDatabase.PQuery("SELECT guid, deleteInfos_Account FROM characters WHERE deleteDate IS NOT NULL AND deleteDate < '%u'", uint32(time(NULL) - time_t(keepDays * DAY))); - if (resultChars) + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_OLD_CHARS); + stmt->setUInt32(0, uint32(time(NULL) - time_t(keepDays * DAY))); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + + if (result) { - sLog->outString("Player::DeleteOldChars: Found " UI64FMTD " character(s) to delete", resultChars->GetRowCount()); + sLog->outString("Player::DeleteOldChars: Found " UI64FMTD " character(s) to delete", result->GetRowCount()); do { - Field* charFields = resultChars->Fetch(); - Player::DeleteFromDB(charFields[0].GetUInt64(), charFields[1].GetUInt32(), true, true); - } while (resultChars->NextRow()); + Field* fields = result->Fetch(); + Player::DeleteFromDB(fields[0].GetUInt64(), fields[1].GetUInt32(), true, true); + } + while (result->NextRow()); } } @@ -7252,29 +7366,46 @@ void Player::SetArenaPoints(uint32 value) void Player::ModifyHonorPoints(int32 value, SQLTransaction* trans /*=NULL*/) { + PreparedStatement* stmt = NULL; + int32 newValue = int32(GetHonorPoints()) + value; if (newValue < 0) newValue = 0; SetHonorPoints(uint32(newValue)); if (trans && !trans->null()) - (*trans)->PAppend("UPDATE characters SET totalHonorPoints=%u WHERE guid=%u", newValue, GetGUIDLow()); + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_HONOR_POINTS); + stmt->setUInt32(0, newValue); + stmt->setUInt32(1, GetGUIDLow()); + (*trans)->Append(stmt); + } } void Player::ModifyArenaPoints(int32 value, SQLTransaction* trans /*=NULL*/) { + PreparedStatement* stmt = NULL; + int32 newValue = int32(GetArenaPoints()) + value; if (newValue < 0) newValue = 0; SetArenaPoints(uint32(newValue)); if (trans && !trans->null()) - (*trans)->PAppend("UPDATE characters SET arenaPoints=%u WHERE guid=%u", newValue, GetGUIDLow()); + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_ARENA_POINTS); + stmt->setUInt32(0, newValue); + stmt->setUInt32(1, GetGUIDLow()); + (*trans)->Append(stmt); + } } uint32 Player::GetGuildIdFromDB(uint64 guid) { - QueryResult result = CharacterDatabase.PQuery("SELECT guildid FROM guild_member WHERE guid='%u'", GUID_LOPART(guid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER); + stmt->setUInt32(0, GUID_LOPART(guid)); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) return 0; @@ -7284,10 +7415,13 @@ uint32 Player::GetGuildIdFromDB(uint64 guid) uint8 Player::GetRankFromDB(uint64 guid) { - QueryResult result = CharacterDatabase.PQuery("SELECT rank FROM guild_member WHERE guid='%u'", GUID_LOPART(guid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER); + stmt->setUInt32(0, GUID_LOPART(guid)); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (result) { - uint32 v = result->Fetch()[0].GetUInt8(); + uint32 v = result->Fetch()[1].GetUInt8(); return v; } else @@ -7296,7 +7430,11 @@ uint8 Player::GetRankFromDB(uint64 guid) uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type) { - QueryResult result = CharacterDatabase.PQuery("SELECT arena_team_member.arenateamid FROM arena_team_member JOIN arena_team ON arena_team_member.arenateamid = arena_team.arenateamid WHERE guid='%u' AND type='%u' LIMIT 1", GUID_LOPART(guid), type); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID); + stmt->setUInt32(0, GUID_LOPART(guid)); + stmt->setUInt8(1, type); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) return 0; @@ -7307,7 +7445,10 @@ uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type) uint32 Player::GetZoneIdFromDB(uint64 guid) { uint32 guidLow = GUID_LOPART(guid); - QueryResult result = CharacterDatabase.PQuery("SELECT zone FROM characters WHERE guid='%u'", guidLow); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_ZONE); + stmt->setUInt32(0, guidLow); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) return 0; Field* fields = result->Fetch(); @@ -7316,7 +7457,10 @@ uint32 Player::GetZoneIdFromDB(uint64 guid) if (!zone) { // stored zone is zero, use generic and slow zone detection - result = CharacterDatabase.PQuery("SELECT map, position_x, position_y, position_z FROM characters WHERE guid='%u'", guidLow); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_POSITION_XYZ); + stmt->setUInt32(0, guidLow); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) return 0; fields = result->Fetch(); @@ -7343,7 +7487,10 @@ uint32 Player::GetZoneIdFromDB(uint64 guid) uint32 Player::GetLevelFromDB(uint64 guid) { - QueryResult result = CharacterDatabase.PQuery("SELECT level FROM characters WHERE guid='%u'", GUID_LOPART(guid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_LEVEL); + stmt->setUInt32(0, GUID_LOPART(guid)); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) return 0; @@ -7387,17 +7534,15 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) } // group update - if (GetGroup()) + if (Group* group = GetGroup()) { SetGroupUpdateFlag(GROUP_UPDATE_FULL); - Group* grp = GetGroup(); - if (GetSession() && grp->isLFGGroup() && sLFGMgr->IsTeleported(GetGUID())) + if (GetSession() && group->isLFGGroup() && sLFGMgr->IsTeleported(GetGUID())) { - for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { - Player* tempplr = itr->getSource(); - if (tempplr) - GetSession()->SendNameQueryOpcode(tempplr->GetGUID()); + if (Player* member = itr->getSource()) + GetSession()->SendNameQueryOpcode(member->GetGUID()); } } } @@ -7414,9 +7559,8 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) if (sWorld->getBoolConfig(CONFIG_WEATHER)) { - Weather* wth = WeatherMgr::FindWeather(zone->ID); - if (wth) - wth->SendWeatherUpdateToPlayer(this); + if (Weather* weather = WeatherMgr::FindWeather(zone->ID)) + weather->SendWeatherUpdateToPlayer(this); else { if (!WeatherMgr::AddWeather(zone->ID)) @@ -7448,7 +7592,7 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) break; } - if (zone->flags & AREA_FLAG_CAPITAL) // in capital city + if (zone->flags & AREA_FLAG_CAPITAL) // Is in a capital city { if (!pvpInfo.inHostileArea || zone->IsSanctuary()) { @@ -7458,19 +7602,21 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) } pvpInfo.inNoPvPArea = true; } - else // anywhere else + else { - if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING)) // but resting (walk from city or maybe in tavern or leave tavern recently) + if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING)) { - if (GetRestType() == REST_TYPE_IN_TAVERN) // has been in tavern. Is still in? + if (GetRestType() == REST_TYPE_IN_TAVERN) // Still inside a tavern or has recently left { - if (GetMapId() != GetInnPosMapId() || sqrt((GetPositionX()-GetInnPosX())*(GetPositionX()-GetInnPosX())+(GetPositionY()-GetInnPosY())*(GetPositionY()-GetInnPosY())+(GetPositionZ()-GetInnPosZ())*(GetPositionZ()-GetInnPosZ()))>40) + // Remove rest state if we have recently left a tavern. + // Why is 40 yd hardcoded? + if (GetMapId() != GetInnPosMapId() || GetExactDist(GetInnPosX(), GetInnPosY(), GetInnPosZ()) > 40.0f) { RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); SetRestType(REST_TYPE_NO); } } - else // not in tavern (leave city then) + else // Recently left a capital city { RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); SetRestType(REST_TYPE_NO); @@ -14303,15 +14449,15 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men { case GOSSIP_OPTION_GOSSIP: { + if (menuItemData->GossipActionPoi) + PlayerTalkClass->SendPointOfInterest(menuItemData->GossipActionPoi); + if (menuItemData->GossipActionMenuId) { PrepareGossipMenu(source, menuItemData->GossipActionMenuId); SendPreparedGossip(source); } - if (menuItemData->GossipActionPoi) - PlayerTalkClass->SendPointOfInterest(menuItemData->GossipActionPoi); - break; } case GOSSIP_OPTION_OUTDOORPVP: @@ -16537,7 +16683,10 @@ void Player::_LoadBGData(PreparedQueryResult result) bool Player::LoadPositionFromDB(uint32& mapid, float& x, float& y, float& z, float& o, bool& in_flight, uint64 guid) { - QueryResult result = CharacterDatabase.PQuery("SELECT position_x, position_y, position_z, orientation, map, taxi_path FROM characters WHERE guid = '%u'", GUID_LOPART(guid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_POSITION); + stmt->setUInt32(0, GUID_LOPART(guid)); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) return false; @@ -16719,12 +16868,12 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) InitPrimaryProfessions(); // to max set before any spell loaded // init saved position, and fix it later if problematic - uint32 transGUID = uint32(fields[30].GetUInt64()); // field type is uint64 but lowguid is saved + uint32 transGUID = fields[30].GetUInt32(); Relocate(fields[12].GetFloat(), fields[13].GetFloat(), fields[14].GetFloat(), fields[16].GetFloat()); uint32 mapId = fields[15].GetUInt16(); uint32 instanceId = fields[58].GetUInt8(); - uint32 dungeonDiff = fields[38].GetUInt32() & 0x0F; + uint32 dungeonDiff = fields[38].GetUInt8() & 0x0F; if (dungeonDiff >= MAX_DUNGEON_DIFFICULTY) dungeonDiff = DUNGEON_DIFFICULTY_NORMAL; uint32 raidDiff = (fields[38].GetUInt8() >> 4) & 0x0F; @@ -17217,7 +17366,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) } // RaF stuff. - m_grantableLevels = fields[66].GetUInt32(); + m_grantableLevels = fields[66].GetUInt8(); if (GetSession()->IsARecruiter() || (GetSession()->GetRecruiterId() != 0)) SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_REFER_A_FRIEND); @@ -17537,6 +17686,7 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, Field* fields) { + PreparedStatement* stmt = NULL; Item* item = NULL; uint32 itemGuid = fields[13].GetUInt32(); uint32 itemEntry = fields[14].GetUInt32(); @@ -17566,7 +17716,11 @@ Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, F { sLog->outDebug(LOG_FILTER_PLAYER_LOADING, "Player::_LoadInventory: player (GUID: %u, name: '%s') has item (GUID: %u, entry: %u) with expired refund time (%u). Deleting refund data and removing refundable flag.", GetGUIDLow(), GetName(), item->GetGUIDLow(), item->GetEntry(), item->GetPlayedTime()); - trans->PAppend("DELETE FROM item_refund_instance WHERE item_guid = '%u'", item->GetGUIDLow()); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_REFUND_INSTANCE); + stmt->setUInt32(0, item->GetGUIDLow()); + trans->Append(stmt); + item->RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE); } else @@ -17723,27 +17877,31 @@ void Player::_LoadMailInit(PreparedQueryResult resultUnread, PreparedQueryResult void Player::_LoadMail() { m_mail.clear(); - //mails are in right order 0 1 2 3 4 5 6 7 8 9 10 11 12 13 - QueryResult result = CharacterDatabase.PQuery("SELECT id, messageType, sender, receiver, subject, body, has_items, expire_time, deliver_time, money, cod, checked, stationery, mailTemplateId FROM mail WHERE receiver = '%u' ORDER BY id DESC", GetGUIDLow()); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL); + stmt->setUInt32(0, GetGUIDLow()); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (result) { do { Field* fields = result->Fetch(); Mail* m = new Mail; - m->messageID = fields[0].GetUInt32(); - m->messageType = fields[1].GetUInt8(); - m->sender = fields[2].GetUInt32(); - m->receiver = fields[3].GetUInt32(); - m->subject = fields[4].GetString(); - m->body = fields[5].GetString(); - bool has_items = fields[6].GetBool(); - m->expire_time = time_t(fields[7].GetUInt32()); - m->deliver_time = time_t(fields[8].GetUInt32()); - m->money = fields[9].GetUInt32(); - m->COD = fields[10].GetUInt32(); - m->checked = fields[11].GetUInt32(); - m->stationery = fields[12].GetUInt8(); + + m->messageID = fields[0].GetUInt32(); + m->messageType = fields[1].GetUInt8(); + m->sender = fields[2].GetUInt32(); + m->receiver = fields[3].GetUInt32(); + m->subject = fields[4].GetString(); + m->body = fields[5].GetString(); + bool has_items = fields[6].GetBool(); + m->expire_time = time_t(fields[7].GetUInt32()); + m->deliver_time = time_t(fields[8].GetUInt32()); + m->money = fields[9].GetUInt32(); + m->COD = fields[10].GetUInt32(); + m->checked = fields[11].GetUInt32(); + m->stationery = fields[12].GetUInt8(); m->mailTemplateId = fields[13].GetInt16(); if (m->mailTemplateId && !sMailTemplateStore.LookupEntry(m->mailTemplateId)) @@ -18091,7 +18249,7 @@ void Player::_LoadBoundInstances(PreparedQueryResult result) if (deleteInstance) { - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INSTANCE); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID); stmt->setUInt32(0, GetGUIDLow()); stmt->setUInt32(1, instanceId); @@ -18147,7 +18305,7 @@ void Player::UnbindInstance(BoundInstancesMap::iterator &itr, Difficulty difficu { if (!unload) { - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INSTANCE); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE); stmt->setUInt32(0, GetGUIDLow()); stmt->setUInt32(1, itr->second.save->GetInstanceId()); @@ -18507,7 +18665,7 @@ void Player::SaveToDB(bool create /*=false*/) outDebugValues(); PreparedStatement* stmt = NULL; - uint16 index = 0; + uint8 index = 0; if (create) { @@ -18546,12 +18704,12 @@ void Player::SaveToDB(bool create /*=false*/) //save, far from tavern/city //save, but in tavern/city stmt->setUInt32(index++, m_resetTalentsCost); - stmt->setUInt32(index++, m_resetTalentsTime); + stmt->setUInt32(index++, uint32(m_resetTalentsTime)); stmt->setUInt16(index++, (uint16)m_ExtraFlags); stmt->setUInt8(index++, m_stableSlots); stmt->setUInt16(index++, (uint16)m_atLoginFlags); stmt->setUInt16(index++, GetZoneId()); - stmt->setUInt32(index++, m_deathExpireTime); + stmt->setUInt32(index++, uint32(m_deathExpireTime)); ss.str(""); ss << m_taxi.SaveTaxiDestinationsToString(); @@ -18657,12 +18815,12 @@ void Player::SaveToDB(bool create /*=false*/) //save, far from tavern/city //save, but in tavern/city stmt->setUInt32(index++, m_resetTalentsCost); - stmt->setUInt32(index++, m_resetTalentsTime); + stmt->setUInt32(index++, uint32(m_resetTalentsTime)); stmt->setUInt16(index++, (uint16)m_ExtraFlags); stmt->setUInt8(index++, m_stableSlots); stmt->setUInt16(index++, (uint16)m_atLoginFlags); stmt->setUInt16(index++, GetZoneId()); - stmt->setUInt32(index++, m_deathExpireTime); + stmt->setUInt32(index++, uint32(m_deathExpireTime)); ss.str(""); ss << m_taxi.SaveTaxiDestinationsToString(); @@ -18772,29 +18930,51 @@ void Player::SaveInventoryAndGoldToDB(SQLTransaction& trans) void Player::SaveGoldToDB(SQLTransaction& trans) { - trans->PAppend("UPDATE characters SET money = '%u' WHERE guid = '%u'", GetMoney(), GetGUIDLow()); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_MONEY); + stmt->setUInt32(0, GetMoney()); + stmt->setUInt32(1, GetGUIDLow()); + trans->Append(stmt); } void Player::_SaveActions(SQLTransaction& trans) { + PreparedStatement* stmt = NULL; + for (ActionButtonList::iterator itr = m_actionButtons.begin(); itr != m_actionButtons.end();) { switch (itr->second.uState) { case ACTIONBUTTON_NEW: - trans->PAppend("INSERT INTO character_action (guid, spec, button, action, type) VALUES ('%u', '%u', '%u', '%u', '%u')", - GetGUIDLow(), m_activeSpec, (uint32)itr->first, (uint32)itr->second.GetAction(), (uint32)itr->second.GetType()); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACTION); + stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt8(1, m_activeSpec); + stmt->setUInt8(2, itr->first); + stmt->setUInt32(3, itr->second.GetAction()); + stmt->setUInt8(4, uint8(itr->second.GetType())); + trans->Append(stmt); + itr->second.uState = ACTIONBUTTON_UNCHANGED; ++itr; break; case ACTIONBUTTON_CHANGED: - trans->PAppend("UPDATE character_action SET action = '%u', type = '%u' WHERE guid = '%u' AND button = '%u' AND spec = '%u'", - (uint32)itr->second.GetAction(), (uint32)itr->second.GetType(), GetGUIDLow(), (uint32)itr->first, m_activeSpec); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ACTION); + stmt->setUInt32(0, itr->second.GetAction()); + stmt->setUInt8(1, uint8(itr->second.GetType())); + stmt->setUInt32(2, GetGUIDLow()); + stmt->setUInt8(3, itr->first); + stmt->setUInt8(4, m_activeSpec); + trans->Append(stmt); + itr->second.uState = ACTIONBUTTON_UNCHANGED; ++itr; break; case ACTIONBUTTON_DELETED: - trans->PAppend("DELETE FROM character_action WHERE guid = '%u' and button = '%u' and spec = '%u'", GetGUIDLow(), (uint32)itr->first, m_activeSpec); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACTION_BY_BUTTON_SPEC); + stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt8(1, itr->first); + stmt->setUInt8(2, m_activeSpec); + trans->Append(stmt); + m_actionButtons.erase(itr++); break; default: @@ -18862,6 +19042,7 @@ void Player::_SaveAuras(SQLTransaction& trans) void Player::_SaveInventory(SQLTransaction& trans) { + PreparedStatement* stmt = NULL; // force items in buyback slots to new state // and remove those that aren't already for (uint8 i = BUYBACK_SLOT_START; i < BUYBACK_SLOT_END; ++i) @@ -18869,8 +19050,12 @@ void Player::_SaveInventory(SQLTransaction& trans) Item* item = m_items[i]; if (!item || item->GetState() == ITEM_NEW) continue; - trans->PAppend("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow()); - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INVENTORY_BY_ITEM); + stmt->setUInt32(0, item->GetGUIDLow()); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE); stmt->setUInt32(0, item->GetGUIDLow()); trans->Append(stmt); m_items[i]->FSetState(ITEM_NEW); @@ -18928,7 +19113,12 @@ void Player::_SaveInventory(SQLTransaction& trans) bagTestGUID = test2->GetGUIDLow(); sLog->outError("Player(GUID: %u Name: %s)::_SaveInventory - the bag(%u) and slot(%u) values for the item with guid %u (state %d) are incorrect, the player doesn't have an item at that position!", lowGuid, GetName(), item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), (int32)item->GetState()); // according to the test that was just performed nothing should be in this slot, delete - trans->PAppend("DELETE FROM character_inventory WHERE bag=%u AND slot=%u AND guid=%u", bagTestGUID, item->GetSlot(), lowGuid); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INVENTORY_BY_BAG_SLOT); + stmt->setUInt32(0, bagTestGUID); + stmt->setUInt8(1, item->GetSlot()); + stmt->setUInt32(2, lowGuid); + trans->Append(stmt); + // also THIS item should be somewhere else, cheat attempt item->FSetState(ITEM_REMOVED); // we are IN updateQueue right now, can't use SetState which modifies the queue DeleteRefundReference(item->GetGUIDLow()); @@ -18976,17 +19166,32 @@ void Player::_SaveMail(SQLTransaction& trans) if (!m_mailsLoaded) return; + PreparedStatement* stmt = NULL; + for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr) { Mail* m = (*itr); if (m->state == MAIL_STATE_CHANGED) { - trans->PAppend("UPDATE mail SET has_items = '%u', expire_time = '" UI64FMTD "', deliver_time = '" UI64FMTD "', money = '%u', cod = '%u', checked = '%u' WHERE id = '%u'", - m->HasItems() ? 1 : 0, (uint64)m->expire_time, (uint64)m->deliver_time, m->money, m->COD, m->checked, m->messageID); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_MAIL); + stmt->setUInt8(0, uint8(m->HasItems() ? 1 : 0)); + stmt->setUInt32(1, uint32(m->expire_time)); + stmt->setUInt32(2, uint32(m->deliver_time)); + stmt->setUInt32(3, m->money); + stmt->setUInt32(4, m->COD); + stmt->setUInt8(5, uint8(m->checked)); + stmt->setUInt32(6, m->messageID); + + trans->Append(stmt); + if (!m->removedItems.empty()) { for (std::vector<uint32>::iterator itr2 = m->removedItems.begin(); itr2 != m->removedItems.end(); ++itr2) - trans->PAppend("DELETE FROM mail_items WHERE item_guid = '%u'", *itr2); + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM); + stmt->setUInt32(0, *itr2); + trans->Append(stmt); + } m->removedItems.clear(); } m->state = MAIL_STATE_UNCHANGED; @@ -19003,8 +19208,13 @@ void Player::_SaveMail(SQLTransaction& trans) trans->Append(stmt); } } - trans->PAppend("DELETE FROM mail WHERE id = '%u'", m->messageID); - trans->PAppend("DELETE FROM mail_items WHERE mail_id = '%u'", m->messageID); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_BY_ID); + stmt->setUInt32(0, m->messageID); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM_BY_ID); + stmt->setUInt32(0, m->messageID); + trans->Append(stmt); } } @@ -19033,6 +19243,7 @@ void Player::_SaveQuestStatus(SQLTransaction& trans) QuestStatusSaveMap::iterator saveItr; QuestStatusMap::iterator statusItr; + PreparedStatement* stmt = NULL; bool keepAbandoned = !(sWorld->GetCleaningFlags() & CharacterDatabaseCleaner::CLEANING_FLAG_QUESTSTATUS); @@ -19042,12 +19253,33 @@ void Player::_SaveQuestStatus(SQLTransaction& trans) { statusItr = m_QuestStatus.find(saveItr->first); if (statusItr != m_QuestStatus.end() && (keepAbandoned || statusItr->second.Status != QUEST_STATUS_NONE)) - trans->PAppend("REPLACE INTO character_queststatus (guid, quest, status, explored, timer, mobcount1, mobcount2, mobcount3, mobcount4, itemcount1, itemcount2, itemcount3, itemcount4, playercount) " - "VALUES ('%u', '%u', '%u', '%u', '" UI64FMTD "', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')", - GetGUIDLow(), statusItr->first, statusItr->second.Status, statusItr->second.Explored, uint64(statusItr->second.Timer / IN_MILLISECONDS+ sWorld->GetGameTime()), statusItr->second.CreatureOrGOCount[0], statusItr->second.CreatureOrGOCount[1], statusItr->second.CreatureOrGOCount[2], statusItr->second.CreatureOrGOCount[3], statusItr->second.ItemCount[0], statusItr->second.ItemCount[1], statusItr->second.ItemCount[2], statusItr->second.ItemCount[3], statusItr->second.PlayerCount); + { + uint8 index = 0; + stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHAR_QUESTSTATUS); + + stmt->setUInt32(index++, GetGUIDLow()); + stmt->setUInt32(index++, statusItr->first); + stmt->setUInt8(index++, uint8(statusItr->second.Status)); + stmt->setBool(index++, statusItr->second.Explored); + stmt->setUInt32(index++, uint32(statusItr->second.Timer / IN_MILLISECONDS+ sWorld->GetGameTime())); + + for (uint8 i = 0; i < 4; i++) + stmt->setUInt16(index++, statusItr->second.CreatureOrGOCount[i]); + + for (uint8 i = 0; i < 4; i++) + stmt->setUInt16(index++, statusItr->second.ItemCount[i]); + + stmt->setUInt16(index, statusItr->second.PlayerCount); + trans->Append(stmt); + } } else - trans->PAppend("DELETE FROM character_queststatus WHERE guid = %u AND quest = %u", GetGUIDLow(), saveItr->first); + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS_BY_QUEST); + stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(1, saveItr->first); + trans->Append(stmt); + } } m_QuestStatusSave.clear(); @@ -19055,9 +19287,20 @@ void Player::_SaveQuestStatus(SQLTransaction& trans) for (saveItr = m_RewardedQuestsSave.begin(); saveItr != m_RewardedQuestsSave.end(); ++saveItr) { if (saveItr->second) - trans->PAppend("INSERT IGNORE INTO character_queststatus_rewarded (guid, quest) VALUES (%u, %u)", GetGUIDLow(), saveItr->first); + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_QUESTSTATUS); + stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(1, saveItr->first); + trans->Append(stmt); + + } else if (!keepAbandoned) - trans->PAppend("DELETE FROM character_queststatus_rewarded WHERE guid = %u AND quest = %u", GetGUIDLow(), saveItr->first); + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST); + stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(1, saveItr->first); + trans->Append(stmt); + } } m_RewardedQuestsSave.clear(); @@ -19157,6 +19400,7 @@ void Player::_SaveSeasonalQuestStatus(SQLTransaction& trans) void Player::_SaveSkills(SQLTransaction& trans) { + PreparedStatement* stmt = NULL; // we don't need transactions here. for (SkillStatusMap::iterator itr = mSkillStatus.begin(); itr != mSkillStatus.end();) { @@ -19168,7 +19412,11 @@ void Player::_SaveSkills(SQLTransaction& trans) if (itr->second.uState == SKILL_DELETED) { - trans->PAppend("DELETE FROM character_skills WHERE guid = '%u' AND skill = '%u' ", GetGUIDLow(), itr->first); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SKILL_BY_SKILL); + stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(1, itr->first); + trans->Append(stmt); + mSkillStatus.erase(itr++); continue; } @@ -19180,12 +19428,22 @@ void Player::_SaveSkills(SQLTransaction& trans) switch (itr->second.uState) { case SKILL_NEW: - trans->PAppend("INSERT INTO character_skills (guid, skill, value, max) VALUES ('%u', '%u', '%u', '%u')", - GetGUIDLow(), itr->first, value, max); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SKILLS); + stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt16(1, uint16(itr->first)); + stmt->setUInt16(2, value); + stmt->setUInt16(3, max); + trans->Append(stmt); + break; case SKILL_CHANGED: - trans->PAppend("UPDATE character_skills SET value = '%u', max = '%u'WHERE guid = '%u' AND skill = '%u' ", - value, max, GetGUIDLow(), itr->first); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_SKILLS); + stmt->setUInt16(0, value); + stmt->setUInt16(1, max); + stmt->setUInt32(2, GetGUIDLow()); + stmt->setUInt16(3, uint16(itr->first)); + trans->Append(stmt); + break; default: break; @@ -19198,14 +19456,28 @@ void Player::_SaveSkills(SQLTransaction& trans) void Player::_SaveSpells(SQLTransaction& trans) { + PreparedStatement* stmt = NULL; + for (PlayerSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end();) { if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED) - trans->PAppend("DELETE FROM character_spell WHERE guid = '%u' and spell = '%u'", GetGUIDLow(), itr->first); + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SPELL_BY_SPELL); + stmt->setUInt32(0, itr->first); + stmt->setUInt32(1, GetGUIDLow()); + trans->Append(stmt); + } // add only changed/new not dependent spells if (!itr->second->dependent && (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED)) - trans->PAppend("INSERT INTO character_spell (guid, spell, active, disabled) VALUES ('%u', '%u', '%u', '%u')", GetGUIDLow(), itr->first, itr->second->active ? 1 : 0, itr->second->disabled ? 1 : 0); + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SPELL); + stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(1, itr->first); + stmt->setBool(2, itr->second->active); + stmt->setBool(3, itr->second->disabled); + trans->Append(stmt); + } if (itr->second->state == PLAYERSPELL_REMOVED) { @@ -19228,31 +19500,40 @@ void Player::_SaveStats(SQLTransaction& trans) if (!sWorld->getIntConfig(CONFIG_MIN_LEVEL_STAT_SAVE) || getLevel() < sWorld->getIntConfig(CONFIG_MIN_LEVEL_STAT_SAVE)) return; - trans->PAppend("DELETE FROM character_stats WHERE guid = '%u'", GetGUIDLow()); - std::ostringstream ss; - ss << "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, maxpower6, maxpower7, " - "strength, agility, stamina, intellect, spirit, armor, resHoly, resFire, resNature, resFrost, resShadow, resArcane, " - "blockPct, dodgePct, parryPct, critPct, rangedCritPct, spellCritPct, attackPower, rangedAttackPower, spellPower, resilience) VALUES (" - << GetGUIDLow() << ',' - << GetMaxHealth() << ','; + PreparedStatement* stmt = NULL; + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_STATS); + stmt->setUInt32(0, GetGUIDLow()); + trans->Append(stmt); + + uint8 index = 0; + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_STATS); + stmt->setUInt32(index++, GetGUIDLow()); + stmt->setUInt32(index++, GetMaxHealth()); + for (uint8 i = 0; i < MAX_POWERS; ++i) - ss << GetMaxPower(Powers(i)) << ','; + stmt->setUInt32(index++, GetMaxPower(Powers(i))); + for (uint8 i = 0; i < MAX_STATS; ++i) - ss << GetStat(Stats(i)) << ','; - // armor + school resistances + stmt->setUInt32(index++, GetStat(Stats(i))); + for (int i = 0; i < MAX_SPELL_SCHOOL; ++i) - ss << GetResistance(SpellSchools(i)) << ','; - ss << GetFloatValue(PLAYER_BLOCK_PERCENTAGE) << ',' - << GetFloatValue(PLAYER_DODGE_PERCENTAGE) << ',' - << GetFloatValue(PLAYER_PARRY_PERCENTAGE) << ',' - << GetFloatValue(PLAYER_CRIT_PERCENTAGE) << ',' - << GetFloatValue(PLAYER_RANGED_CRIT_PERCENTAGE) << ',' - << GetFloatValue(PLAYER_SPELL_CRIT_PERCENTAGE1) << ',' - << GetUInt32Value(UNIT_FIELD_ATTACK_POWER) << ',' - << GetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER) << ',' - << GetBaseSpellPowerBonus() << ',' - << GetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + CR_CRIT_TAKEN_SPELL) << ')'; - trans->Append(ss.str().c_str()); + stmt->setUInt32(index++, GetResistance(SpellSchools(i))); + + stmt->setFloat(index++, GetFloatValue(PLAYER_BLOCK_PERCENTAGE)); + stmt->setFloat(index++, GetFloatValue(PLAYER_DODGE_PERCENTAGE)); + stmt->setFloat(index++, GetFloatValue(PLAYER_PARRY_PERCENTAGE)); + stmt->setFloat(index++, GetFloatValue(PLAYER_CRIT_PERCENTAGE)); + stmt->setFloat(index++, GetFloatValue(PLAYER_RANGED_CRIT_PERCENTAGE)); + stmt->setFloat(index++, GetFloatValue(PLAYER_SPELL_CRIT_PERCENTAGE1)); + stmt->setUInt32(index++, GetUInt32Value(UNIT_FIELD_ATTACK_POWER)); + stmt->setUInt32(index++, GetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER)); + stmt->setUInt32(index++, GetBaseSpellPowerBonus()); + stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + CR_CRIT_TAKEN_SPELL)); + stmt->setUInt32(index++, GetMaxHealth()); + + trans->Append(stmt); } void Player::outDebugValues() const @@ -19351,8 +19632,10 @@ void Player::SetUInt32ValueInArray(Tokens& tokens, uint16 index, uint32 value) void Player::Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair) { - // 0 - QueryResult result = CharacterDatabase.PQuery("SELECT playerBytes2 FROM characters WHERE guid = '%u'", GUID_LOPART(guid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PLAYERBYTES2); + stmt->setUInt32(0, GUID_LOPART(guid)); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) return; @@ -19362,7 +19645,7 @@ void Player::Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 playerBytes2 &= ~0xFF; playerBytes2 |= facialHair; - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GENDER_PLAYERBYTES); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GENDER_PLAYERBYTES); stmt->setUInt8(0, gender); stmt->setUInt32(1, skin | (face << 8) | (hairStyle << 16) | (hairColor << 24)); @@ -20200,11 +20483,19 @@ void Player::SendProficiency(ItemClass itemClass, uint32 itemSubclassMask) void Player::RemovePetitionsAndSigns(uint64 guid, uint32 type) { - QueryResult result = QueryResult(NULL); + PreparedStatement* stmt; + if (type == 10) - result = CharacterDatabase.PQuery("SELECT ownerguid, petitionguid FROM petition_sign WHERE playerguid = '%u'", GUID_LOPART(guid)); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIG_BY_GUID); else - result = CharacterDatabase.PQuery("SELECT ownerguid, petitionguid FROM petition_sign WHERE playerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type); + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIG_BY_GUID_TYPE); + stmt->setUInt8(0, uint8(type)); + } + + stmt->setUInt32(0, GUID_LOPART(guid)); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (result) { do // this part effectively does nothing, since the deletion / modification only takes place _after_ the PetitionQuery. Though I don't know if the result remains intact if I execute the delete query beforehand. @@ -20241,13 +20532,25 @@ void Player::RemovePetitionsAndSigns(uint64 guid, uint32 type) SQLTransaction trans = CharacterDatabase.BeginTransaction(); if (type == 10) { - trans->PAppend("DELETE FROM petition WHERE ownerguid = '%u'", GUID_LOPART(guid)); - trans->PAppend("DELETE FROM petition_sign WHERE ownerguid = '%u'", GUID_LOPART(guid)); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_BY_OWNER); + stmt->setUInt32(0, GUID_LOPART(guid)); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER); + stmt->setUInt32(0, GUID_LOPART(guid)); + trans->Append(stmt); } else { - trans->PAppend("DELETE FROM petition WHERE ownerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type); - trans->PAppend("DELETE FROM petition_sign WHERE ownerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_BY_OWNER_AND_TYPE); + stmt->setUInt32(0, GUID_LOPART(guid)); + stmt->setUInt8(1, uint8(type)); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER_AND_TYPE); + stmt->setUInt32(0, GUID_LOPART(guid)); + stmt->setUInt8(1, uint8(type)); + trans->Append(stmt); } CharacterDatabase.CommitTransaction(trans); } @@ -24644,12 +24947,26 @@ void Player::_LoadGlyphs(PreparedQueryResult result) void Player::_SaveGlyphs(SQLTransaction& trans) { - trans->PAppend("DELETE FROM character_glyphs WHERE guid='%u'", GetGUIDLow()); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_GLYPHS); + stmt->setUInt32(0, GetGUIDLow()); + trans->Append(stmt); + + uint8 index = 0; + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_GLYPHS); + stmt->setUInt32(index++, GetGUIDLow()); + + for (uint8 spec = 0; spec < m_specsCount; ++spec) { - trans->PAppend("INSERT INTO character_glyphs VALUES('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')", - GetGUIDLow(), spec, m_Glyphs[spec][0], m_Glyphs[spec][1], m_Glyphs[spec][2], m_Glyphs[spec][3], m_Glyphs[spec][4], m_Glyphs[spec][5]); + stmt->setUInt8(index++, spec); + + for (uint8 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i) + stmt->setUInt16(index++, uint16(m_Glyphs[spec][i])); + } + + trans->Append(stmt); } void Player::_LoadTalents(PreparedQueryResult result) @@ -24658,22 +24975,36 @@ void Player::_LoadTalents(PreparedQueryResult result) if (result) { do - AddTalent((*result)[0].GetUInt32(), (*result)[1].GetUInt32(), false); + AddTalent((*result)[0].GetUInt32(), (*result)[1].GetUInt8(), false); while (result->NextRow()); } } void Player::_SaveTalents(SQLTransaction& trans) { + PreparedStatement* stmt = NULL; + for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) { for (PlayerTalentMap::iterator itr = m_talents[i]->begin(); itr != m_talents[i]->end();) { if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED) - trans->PAppend("DELETE FROM character_talent WHERE guid = '%u' and spell = '%u' and spec = '%u'", GetGUIDLow(), itr->first, itr->second->spec); + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC); + stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(1, itr->first); + stmt->setUInt8(2, itr->second->spec); + trans->Append(stmt); + } if (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED) - trans->PAppend("INSERT INTO character_talent (guid, spell, spec) VALUES ('%u', '%u', '%u')", GetGUIDLow(), itr->first, itr->second->spec); + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_TALENT); + stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(1, itr->first); + stmt->setUInt8(2, itr->second->spec); + trans->Append(stmt); + } if (itr->second->state == PLAYERSPELL_REMOVED) { @@ -24699,20 +25030,33 @@ void Player::UpdateSpecCount(uint8 count) ActivateSpec(0); SQLTransaction trans = CharacterDatabase.BeginTransaction(); + PreparedStatement* stmt = NULL; // Copy spec data if (count > curCount) { _SaveActions(trans); // make sure the button list is cleaned up for (ActionButtonList::iterator itr = m_actionButtons.begin(); itr != m_actionButtons.end(); ++itr) - trans->PAppend("INSERT INTO character_action (guid, button, action, type, spec) VALUES ('%u', '%u', '%u', '%u', '%u')", - GetGUIDLow(), uint32(itr->first), uint32(itr->second.GetAction()), uint32(itr->second.GetType()), 1); + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACTION); + stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt8(1, 1); + stmt->setUInt8(2, itr->first); + stmt->setUInt32(3, itr->second.GetAction()); + stmt->setUInt8(4, uint8(itr->second.GetType())); + trans->Append(stmt); + } } // Delete spec data for removed spec. else if (count < curCount) { _SaveActions(trans); - trans->PAppend("DELETE FROM character_action WHERE spec<>'%u' AND guid='%u'", m_activeSpec, GetGUIDLow()); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC); + stmt->setUInt8(0, m_activeSpec); + stmt->setUInt32(1, GetGUIDLow()); + trans->Append(stmt); + m_activeSpec = 0; } @@ -25197,8 +25541,8 @@ void Player::SendMovementSetCanFly(bool apply) void Player::SendMovementSetCanTransitionBetweenSwimAndFly(bool apply) { - WorldPacket data(apply ? - SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY : + WorldPacket data(apply ? + SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY : SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, 12); data.append(GetPackGUID()); data << uint32(0); //! movement counter diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index a238247b3c1..ac50bbd9d35 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2481,9 +2481,6 @@ class Player : public Unit, public GridObject<Player> void AddWhisperWhiteList(uint64 guid) { WhisperList.push_back(guid); } bool IsInWhisperWhiteList(uint64 guid); - #pragma region Player Movement - - /*! These methods send different packets to the client in apply and unapply case. These methods are only sent to the current unit. */ @@ -2525,8 +2522,6 @@ class Player : public Unit, public GridObject<Player> return modelData->CollisionHeight; } } - #pragma endregion Player Movement - protected: // Gamemaster whisper whitelist diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp index cb327b83d17..1ded8cda81b 100755 --- a/src/server/game/Entities/Player/SocialMgr.cpp +++ b/src/server/game/Entities/Player/SocialMgr.cpp @@ -61,7 +61,7 @@ bool PlayerSocial::AddToSocialList(uint32 friendGuid, bool ignore) return false; } - uint32 flag = SOCIAL_FLAG_FRIEND; + uint8 flag = SOCIAL_FLAG_FRIEND; if (ignore) flag = SOCIAL_FLAG_IGNORED; @@ -70,7 +70,7 @@ bool PlayerSocial::AddToSocialList(uint32 friendGuid, bool ignore) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_CHARACTER_SOCIAL_FLAGS); - stmt->setUInt8(0, uint8(flag)); + stmt->setUInt8(0, flag); stmt->setUInt32(1, GetPlayerGUID()); stmt->setUInt32(2, friendGuid); @@ -84,7 +84,7 @@ bool PlayerSocial::AddToSocialList(uint32 friendGuid, bool ignore) stmt->setUInt32(0, GetPlayerGUID()); stmt->setUInt32(1, friendGuid); - stmt->setUInt8(2, uint8(flag)); + stmt->setUInt8(2, flag); CharacterDatabase.Execute(stmt); @@ -101,7 +101,7 @@ void PlayerSocial::RemoveFromSocialList(uint32 friendGuid, bool ignore) if (itr == m_playerSocialMap.end()) // not exist return; - uint32 flag = SOCIAL_FLAG_FRIEND; + uint8 flag = SOCIAL_FLAG_FRIEND; if (ignore) flag = SOCIAL_FLAG_IGNORED; @@ -121,7 +121,7 @@ void PlayerSocial::RemoveFromSocialList(uint32 friendGuid, bool ignore) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_REM_CHARACTER_SOCIAL_FLAGS); - stmt->setUInt8(0, uint8(flag)); + stmt->setUInt8(0, flag); stmt->setUInt32(1, GetPlayerGUID()); stmt->setUInt32(2, friendGuid); @@ -321,7 +321,7 @@ void SocialMgr::BroadcastToFriendListers(Player* player, WorldPacket* packet) } } -PlayerSocial *SocialMgr::LoadFromDB(PreparedQueryResult result, uint32 guid) +PlayerSocial* SocialMgr::LoadFromDB(PreparedQueryResult result, uint32 guid) { PlayerSocial *social = &m_socialMap[guid]; social->SetPlayerGUID(guid); @@ -330,7 +330,7 @@ PlayerSocial *SocialMgr::LoadFromDB(PreparedQueryResult result, uint32 guid) return social; uint32 friend_guid = 0; - uint32 flags = 0; + uint8 flags = 0; std::string note = ""; do @@ -338,7 +338,7 @@ PlayerSocial *SocialMgr::LoadFromDB(PreparedQueryResult result, uint32 guid) Field* fields = result->Fetch(); friend_guid = fields[0].GetUInt32(); - flags = fields[1].GetUInt32(); + flags = fields[1].GetUInt8(); note = fields[2].GetString(); social->m_playerSocialMap[friend_guid] = FriendInfo(flags, note); diff --git a/src/server/game/Entities/Player/SocialMgr.h b/src/server/game/Entities/Player/SocialMgr.h index 540b425588e..3c7d13070fa 100755 --- a/src/server/game/Entities/Player/SocialMgr.h +++ b/src/server/game/Entities/Player/SocialMgr.h @@ -48,7 +48,7 @@ enum SocialFlag struct FriendInfo { FriendStatus Status; - uint32 Flags; + uint8 Flags; uint32 Area; uint8 Level; uint8 Class; @@ -64,7 +64,7 @@ struct FriendInfo Note = ""; } - FriendInfo(uint32 flags, const std::string& note) + FriendInfo(uint8 flags, const std::string& note) { Status = FRIEND_STATUS_OFFLINE; Flags = flags; diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 24fe75605d2..81a505b7acc 100755 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -129,8 +129,8 @@ void MapManager::LoadTransportNPCs() { uint32 oldMSTime = getMSTime(); - // 0 1 2 3 4 5 6 7 - QueryResult result = WorldDatabase.PQuery("SELECT guid, npc_entry, transport_entry, TransOffsetX, TransOffsetY, TransOffsetZ, TransOffsetO, emote FROM creature_transport"); + // 0 1 2 3 4 5 6 7 + QueryResult result = WorldDatabase.Query("SELECT guid, npc_entry, transport_entry, TransOffsetX, TransOffsetY, TransOffsetZ, TransOffsetO, emote FROM creature_transport"); if (!result) { @@ -144,14 +144,14 @@ void MapManager::LoadTransportNPCs() do { Field* fields = result->Fetch(); - uint32 guid = fields[0].GetUInt32(); - uint32 entry = fields[1].GetUInt32(); - uint32 transportEntry = fields[2].GetUInt32(); + uint32 guid = fields[0].GetInt32(); + uint32 entry = fields[1].GetInt32(); + uint32 transportEntry = fields[2].GetInt32(); float tX = fields[3].GetFloat(); float tY = fields[4].GetFloat(); float tZ = fields[5].GetFloat(); float tO = fields[6].GetFloat(); - uint32 anim = fields[7].GetUInt32(); + uint32 anim = fields[7].GetInt32(); for (MapManager::TransportSet::iterator itr = m_Transports.begin(); itr != m_Transports.end(); ++itr) { diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index bef8dc726c5..aea5de36bb7 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -110,23 +110,27 @@ m_damageType(DIRECT_DAMAGE), m_attackType(dmgInfo.attackType) m_resist = 0; m_block = 0; } + void DamageInfo::ModifyDamage(int32 amount) { amount = std::min(amount, int32(GetDamage())); m_damage += amount; } + void DamageInfo::AbsorbDamage(uint32 amount) { amount = std::min(amount, GetDamage()); m_absorb += amount; m_damage -= amount; } + void DamageInfo::ResistDamage(uint32 amount) { amount = std::min(amount, GetDamage()); m_resist += amount; m_damage -= amount; } + void DamageInfo::BlockDamage(uint32 amount) { amount = std::min(amount, GetDamage()); @@ -1096,6 +1100,7 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam if (!victim) return; + if (!isAlive() || !victim->isAlive()) return; @@ -1105,12 +1110,11 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam case BASE_ATTACK: damageInfo->procAttacker = PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_DONE_MAINHAND_ATTACK; damageInfo->procVictim = PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK; - damageInfo->HitInfo = HITINFO_NORMALSWING2; break; case OFF_ATTACK: damageInfo->procAttacker = PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_DONE_OFFHAND_ATTACK; damageInfo->procVictim = PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK; - damageInfo->HitInfo = HITINFO_LEFTSWING; + damageInfo->HitInfo = HITINFO_OFFHAND; break; default: return; @@ -1146,29 +1150,29 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam switch (damageInfo->hitOutCome) { case MELEE_HIT_EVADE: - damageInfo->HitInfo |= HITINFO_MISS|HITINFO_SWINGNOHITSOUND; - damageInfo->TargetState = VICTIMSTATE_EVADES; - damageInfo->procEx|=PROC_EX_EVADE; + damageInfo->HitInfo |= HITINFO_MISS | HITINFO_SWINGNOHITSOUND; + damageInfo->TargetState = VICTIMSTATE_EVADES; + damageInfo->procEx |= PROC_EX_EVADE; damageInfo->damage = 0; damageInfo->cleanDamage = 0; return; case MELEE_HIT_MISS: - damageInfo->HitInfo |= HITINFO_MISS; - damageInfo->TargetState = VICTIMSTATE_INTACT; - damageInfo->procEx |= PROC_EX_MISS; - damageInfo->damage = 0; - damageInfo->cleanDamage = 0; + damageInfo->HitInfo |= HITINFO_MISS; + damageInfo->TargetState = VICTIMSTATE_INTACT; + damageInfo->procEx |= PROC_EX_MISS; + damageInfo->damage = 0; + damageInfo->cleanDamage = 0; break; case MELEE_HIT_NORMAL: - damageInfo->TargetState = VICTIMSTATE_HIT; - damageInfo->procEx|=PROC_EX_NORMAL_HIT; + damageInfo->TargetState = VICTIMSTATE_HIT; + damageInfo->procEx |= PROC_EX_NORMAL_HIT; break; case MELEE_HIT_CRIT: { - damageInfo->HitInfo |= HITINFO_CRITICALHIT; - damageInfo->TargetState = VICTIMSTATE_HIT; + damageInfo->HitInfo |= HITINFO_CRITICALHIT; + damageInfo->TargetState = VICTIMSTATE_HIT; - damageInfo->procEx |= PROC_EX_CRITICAL_HIT; + damageInfo->procEx |= PROC_EX_CRITICAL_HIT; // Crit bonus calc damageInfo->damage += damageInfo->damage; float mod = 0.0f; @@ -1229,8 +1233,8 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam if (leveldif > 3) leveldif = 3; float reducePercent = 1 - leveldif * 0.1f; - damageInfo->cleanDamage += damageInfo->damage-uint32(reducePercent * damageInfo->damage); - damageInfo->damage = uint32(reducePercent * damageInfo->damage); + damageInfo->cleanDamage += damageInfo->damage - uint32(reducePercent * damageInfo->damage); + damageInfo->damage = uint32(reducePercent * damageInfo->damage); break; } case MELEE_HIT_CRUSHING: @@ -1244,6 +1248,10 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam break; } + // Always apply HITINFO_AFFECTS_VICTIM in case its not a miss + if (!(damageInfo->HitInfo & HITINFO_MISS)) + damageInfo->HitInfo |= HITINFO_AFFECTS_VICTIM; + int32 resilienceReduction = damageInfo->damage; if (attackType != RANGED_ATTACK) ApplyResilience(victim, NULL, &resilienceReduction, (damageInfo->hitOutCome == MELEE_HIT_CRIT), CR_CRIT_TAKEN_MELEE); @@ -1259,14 +1267,17 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam damageInfo->procVictim |= PROC_FLAG_TAKEN_DAMAGE; // Calculate absorb & resists CalcAbsorbResist(damageInfo->target, SpellSchoolMask(damageInfo->damageSchoolMask), DIRECT_DAMAGE, damageInfo->damage, &damageInfo->absorb, &damageInfo->resist); - damageInfo->damage -= damageInfo->absorb + damageInfo->resist; + if (damageInfo->absorb) { - damageInfo->HitInfo |= HITINFO_ABSORB; + damageInfo->HitInfo |= (damageInfo->damage - damageInfo->absorb == 0 ? HITINFO_FULL_ABSORB : HITINFO_PARTIAL_ABSORB); damageInfo->procEx |= PROC_EX_ABSORB; } + if (damageInfo->resist) - damageInfo->HitInfo |= HITINFO_RESIST; + damageInfo->HitInfo |= (damageInfo->damage - damageInfo->resist == 0 ? HITINFO_FULL_RESIST : HITINFO_PARTIAL_RESIST); + + damageInfo->damage -= damageInfo->absorb + damageInfo->resist; } else // Impossible get negative result but.... damageInfo->damage = 0; @@ -2157,8 +2168,8 @@ void Unit::SendMeleeAttackStop(Unit* victim) { WorldPacket data(SMSG_ATTACKSTOP, (8+8+4)); data.append(GetPackGUID()); - data.append(victim ? victim->GetPackGUID() : 0); // can be 0x00... - data << uint32(0); // can be 0x1 + data.append(victim ? victim->GetPackGUID() : 0); + data << uint32(0); //! Can also take the value 0x01, which seems related to updating rotation SendMessageToSet(&data, true); sLog->outStaticDebug("WORLD: Sent SMSG_ATTACKSTOP"); @@ -2988,20 +2999,20 @@ bool Unit::IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled, bool skip (withDelayed || m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_DELAYED)) { if (!isAutoshoot || !(m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->AttributesEx2 & SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS)) - return(true); + return true; } // channeled spells may be delayed, but they are still considered casted else if (!skipChanneled && m_currentSpells[CURRENT_CHANNELED_SPELL] && (m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED)) { if (!isAutoshoot || !(m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->AttributesEx2 & SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS)) - return(true); + return true; } // autorepeat spells may be finished or delayed, but they are still considered casted else if (!skipAutorepeat && m_currentSpells[CURRENT_AUTOREPEAT_SPELL]) - return(true); + return true; - return(false); + return false; } void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id, bool withInstant) @@ -4624,7 +4635,8 @@ void Unit::AddGameObject(GameObject* gameObj) void Unit::RemoveGameObject(GameObject* gameObj, bool del) { - if (!gameObj || !gameObj->GetOwnerGUID() == GetGUID()) return; + if (!gameObj || gameObj->GetOwnerGUID() != GetGUID()) + return; gameObj->SetOwnerGUID(0); @@ -4845,28 +4857,29 @@ void Unit::SendAttackStateUpdate(CalcDamageInfo* damageInfo) data << uint32(damageInfo->damage); // Sub Damage } - if (damageInfo->HitInfo & (HITINFO_ABSORB | HITINFO_ABSORB2)) + if (damageInfo->HitInfo & (HITINFO_FULL_ABSORB | HITINFO_PARTIAL_ABSORB)) { for (uint32 i = 0; i < count; ++i) data << uint32(damageInfo->absorb); // Absorb } - if (damageInfo->HitInfo & (HITINFO_RESIST | HITINFO_RESIST2)) + if (damageInfo->HitInfo & (HITINFO_FULL_RESIST | HITINFO_PARTIAL_RESIST)) { for (uint32 i = 0; i < count; ++i) data << uint32(damageInfo->resist); // Resist } data << uint8(damageInfo->TargetState); - data << uint32(0); - data << uint32(0); + data << uint32(0); // Unknown attackerstate + data << uint32(0); // Melee spellid if (damageInfo->HitInfo & HITINFO_BLOCK) data << uint32(damageInfo->blocked_amount); - if (damageInfo->HitInfo & HITINFO_UNK3) + if (damageInfo->HitInfo & HITINFO_RAGE_GAIN) data << uint32(0); + //! Probably used for debugging purposes, as it is not known to appear on retail servers if (damageInfo->HitInfo & HITINFO_UNK1) { data << uint32(0); @@ -5511,6 +5524,13 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere } break; } + case 71875: // Item - Black Bruise: Necrotic Touch Proc + case 71877: + { + basepoints0 = CalculatePctN(int32(damage), triggerAmount); + triggered_spell_id = 71879; + break; + } // Item - Shadowmourne Legendary case 71903: { @@ -6595,9 +6615,11 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere { case 34477: // Misdirection { + if (!GetMisdirectionTarget()) + return false; triggered_spell_id = 35079; // 4 sec buff on self target = this; - return true; + break; } case 57870: // Glyph of Mend Pet { @@ -12199,7 +12221,7 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co } Creature const* creatureAttacker = ToCreature(); - if (creatureAttacker && creatureAttacker->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_UNK26) + if (creatureAttacker && creatureAttacker->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER) return false; Player const* playerAffectingAttacker = HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) ? GetAffectingPlayer() : NULL; @@ -12286,7 +12308,7 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co // can't assist non-friendly targets if (GetReactionTo(target) <= REP_NEUTRAL && target->GetReactionTo(this) <= REP_NEUTRAL - && (!ToCreature() || !(ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_UNK26))) + && (!ToCreature() || !(ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER))) return false; // PvP case @@ -12320,7 +12342,7 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co && !((target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_PVP))) { if (Creature const* creatureTarget = target->ToCreature()) - return creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_UNK26 || creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_AID_PLAYERS; + return creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER || creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_AID_PLAYERS; } return true; } @@ -16160,7 +16182,10 @@ bool Unit::IsInPartyWith(Unit const* unit) const return true; if (u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_PLAYER) - return u1->ToPlayer()->IsInSameGroupWith(u2->ToPlayer()); + return u1->ToPlayer()->IsInSameGroupWith(u2->ToPlayer()); + else if ((u2->GetTypeId() == TYPEID_PLAYER && u1->GetTypeId() == TYPEID_UNIT && u1->ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER) || + (u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_UNIT && u2->ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER)) + return true; else return false; } @@ -16176,82 +16201,14 @@ bool Unit::IsInRaidWith(Unit const* unit) const return true; if (u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_PLAYER) - return u1->ToPlayer()->IsInSameRaidWith(u2->ToPlayer()); + return u1->ToPlayer()->IsInSameRaidWith(u2->ToPlayer()); + else if ((u2->GetTypeId() == TYPEID_PLAYER && u1->GetTypeId() == TYPEID_UNIT && u1->ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER) || + (u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_UNIT && u2->ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER)) + return true; else return false; } -void Unit::GetRaidMember(std::list<Unit*> &nearMembers, float radius) -{ - Player* owner = GetCharmerOrOwnerPlayerOrPlayerItself(); - if (!owner) - return; - - Group* group = owner->GetGroup(); - if (group) - { - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) - { - Player* Target = itr->getSource(); - - if (Target && !IsHostileTo(Target)) - { - if (Target->isAlive() && IsWithinDistInMap(Target, radius)) - nearMembers.push_back(Target); - - if (Guardian* pet = Target->GetGuardianPet()) - if (pet->isAlive() && IsWithinDistInMap(pet, radius)) - nearMembers.push_back(pet); - } - } - } - else - { - if (owner->isAlive() && (owner == this || IsWithinDistInMap(owner, radius))) - nearMembers.push_back(owner); - if (Guardian* pet = owner->GetGuardianPet()) - if (pet->isAlive() && (pet == this || IsWithinDistInMap(pet, radius))) - nearMembers.push_back(pet); - } -} - -void Unit::GetPartyMemberInDist(std::list<Unit*> &TagUnitMap, float radius) -{ - Unit* owner = GetCharmerOrOwnerOrSelf(); - Group* group = NULL; - if (owner->GetTypeId() == TYPEID_PLAYER) - group = owner->ToPlayer()->GetGroup(); - - if (group) - { - uint8 subgroup = owner->ToPlayer()->GetSubGroup(); - - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) - { - Player* Target = itr->getSource(); - - // IsHostileTo check duel and controlled by enemy - if (Target && Target->GetSubGroup() == subgroup && !IsHostileTo(Target)) - { - if (Target->isAlive() && IsWithinDistInMap(Target, radius)) - TagUnitMap.push_back(Target); - - if (Guardian* pet = Target->GetGuardianPet()) - if (pet->isAlive() && IsWithinDistInMap(pet, radius)) - TagUnitMap.push_back(pet); - } - } - } - else - { - if (owner->isAlive() && (owner == this || IsWithinDistInMap(owner, radius))) - TagUnitMap.push_back(owner); - if (Guardian* pet = owner->GetGuardianPet()) - if (pet->isAlive() && (pet == this || IsWithinDistInMap(pet, radius))) - TagUnitMap.push_back(pet); - } -} - void Unit::GetPartyMembers(std::list<Unit*> &TagUnitMap) { Unit* owner = GetCharmerOrOwnerOrSelf(); @@ -17520,7 +17477,7 @@ bool Unit::SetDisableGravity(bool disable) { if (disable == IsLevitating()) return false; - + if (disable) AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); else @@ -17563,7 +17520,7 @@ void Unit::SendMovementHover() SendMessageToSet(&data, true); } -void Unit::SendMovementWaterWalking() +void Unit::SendMovementWaterWalking() { WorldPacket data(MSG_MOVE_WATER_WALK, 64); data.append(GetPackGUID()); @@ -17578,7 +17535,7 @@ void Unit::SendMovementFeatherFall() BuildMovementPacket(&data); SendMessageToSet(&data, true); } - + void Unit::SendMovementGravityChange() { WorldPacket data(MSG_MOVE_GRAVITY_CHNG, 64); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 4919f0e6fe3..d85b7dd15bf 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -286,29 +286,29 @@ enum HitInfo { HITINFO_NORMALSWING = 0x00000000, HITINFO_UNK1 = 0x00000001, // req correct packet structure - HITINFO_NORMALSWING2 = 0x00000002, - HITINFO_LEFTSWING = 0x00000004, + HITINFO_AFFECTS_VICTIM = 0x00000002, + HITINFO_OFFHAND = 0x00000004, HITINFO_UNK2 = 0x00000008, HITINFO_MISS = 0x00000010, - HITINFO_ABSORB = 0x00000020, // absorbed damage - HITINFO_ABSORB2 = 0x00000040, // absorbed damage - HITINFO_RESIST = 0x00000080, // resisted atleast some damage - HITINFO_RESIST2 = 0x00000100, // resisted atleast some damage + HITINFO_FULL_ABSORB = 0x00000020, + HITINFO_PARTIAL_ABSORB = 0x00000040, + HITINFO_FULL_RESIST = 0x00000080, + HITINFO_PARTIAL_RESIST = 0x00000100, HITINFO_CRITICALHIT = 0x00000200, // critical hit // 0x00000400 // 0x00000800 // 0x00001000 HITINFO_BLOCK = 0x00002000, // blocked damage - // 0x00004000 - // 0x00008000 + // 0x00004000 // Hides worldtext for 0 damage + // 0x00008000 // Related to blood visual HITINFO_GLANCING = 0x00010000, HITINFO_CRUSHING = 0x00020000, - HITINFO_NOACTION = 0x00040000, // guessed + HITINFO_NO_ANIMATION = 0x00040000, // 0x00080000 // 0x00100000 - HITINFO_SWINGNOHITSOUND = 0x00200000, // guessed + HITINFO_SWINGNOHITSOUND = 0x00200000, // unused? // 0x00400000 - HITINFO_UNK3 = 0x00800000 + HITINFO_RAGE_GAIN = 0x00800000 }; //i would like to remove this: (it is defined in item.h @@ -708,7 +708,7 @@ enum MovementFlags MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT, //! TODO if needed: add more flags to this masks that are exclusive to players - MOVEMENTFLAG_MASK_PLAYER_ONLY = + MOVEMENTFLAG_MASK_PLAYER_ONLY = MOVEMENTFLAG_FLYING, }; enum MovementFlags2 @@ -1398,9 +1398,7 @@ class Unit : public WorldObject bool IsNeutralToAll() const; bool IsInPartyWith(Unit const* unit) const; bool IsInRaidWith(Unit const* unit) const; - void GetPartyMemberInDist(std::list<Unit*> &units, float dist); void GetPartyMembers(std::list<Unit*> &units); - void GetRaidMember(std::list<Unit*> &units, float dist); bool IsContestedGuard() const { if (FactionTemplateEntry const* entry = getFactionTemplateEntry()) @@ -1635,7 +1633,7 @@ class Unit : public WorldObject /*! These methods send the same packet to the client in apply and unapply case. The client-side interpretation of this packet depends on the presence of relevant movementflags which are sent with movementinfo. Furthermore, these packets are broadcast to nearby players as well - as the current unit. + as the current unit. */ void SendMovementHover(); void SendMovementFeatherFall(); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index e5dd2f1ee25..f66ca460c0a 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -252,6 +252,10 @@ ObjectMgr::~ObjectMgr() itr->second.Clear(); _cacheTrainerSpellStore.clear(); + + for (DungeonEncounterContainer::iterator itr =_dungeonEncounterStore.begin(); itr != _dungeonEncounterStore.end(); ++itr) + for (DungeonEncounterList::iterator encounterItr = itr->second.begin(); encounterItr != itr->second.end(); ++encounterItr) + delete *encounterItr; } void ObjectMgr::AddLocaleString(std::string const& s, LocaleConstant locale, StringVector& data) @@ -418,7 +422,7 @@ void ObjectMgr::LoadCreatureTemplates() creatureTemplate.GossipMenuId = fields[13].GetUInt32(); creatureTemplate.minlevel = fields[14].GetUInt8(); creatureTemplate.maxlevel = fields[15].GetUInt8(); - creatureTemplate.expansion = uint32(fields[16].GetUInt16()); + creatureTemplate.expansion = uint32(fields[16].GetInt16()); creatureTemplate.faction_A = uint32(fields[17].GetUInt16()); creatureTemplate.faction_H = uint32(fields[18].GetUInt16()); creatureTemplate.npcflag = fields[19].GetUInt32(); @@ -451,7 +455,7 @@ void ObjectMgr::LoadCreatureTemplates() creatureTemplate.SkinLootId = fields[46].GetUInt32(); for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - creatureTemplate.resistance[i] = fields[47 + i -1].GetInt32(); + creatureTemplate.resistance[i] = fields[47 + i -1].GetInt16(); for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) creatureTemplate.spells[i] = fields[53 + i].GetUInt32(); @@ -1422,8 +1426,8 @@ void ObjectMgr::LoadCreatures() { Field* fields = result->Fetch(); - uint32 guid = fields[ 0].GetUInt32(); - uint32 entry = fields[ 1].GetUInt32(); + uint32 guid = fields[0].GetUInt32(); + uint32 entry = fields[1].GetUInt32(); CreatureTemplate const* cInfo = GetCreatureTemplate(entry); if (!cInfo) @@ -1434,14 +1438,14 @@ void ObjectMgr::LoadCreatures() CreatureData& data = _creatureDataStore[guid]; data.id = entry; - data.mapid = fields[ 2].GetUInt32(); - data.displayid = fields[ 3].GetUInt32(); - data.equipmentId = fields[ 4].GetUInt32(); - data.posX = fields[ 5].GetFloat(); - data.posY = fields[ 6].GetFloat(); - data.posZ = fields[ 7].GetFloat(); - data.orientation = fields[ 8].GetFloat(); - data.spawntimesecs = fields[ 9].GetUInt32(); + data.mapid = fields[2].GetUInt16(); + data.displayid = fields[3].GetUInt32(); + data.equipmentId = fields[4].GetInt32(); + data.posX = fields[5].GetFloat(); + data.posY = fields[6].GetFloat(); + data.posZ = fields[7].GetFloat(); + data.orientation = fields[8].GetFloat(); + data.spawntimesecs = fields[9].GetUInt32(); data.spawndist = fields[10].GetFloat(); data.currentwaypoint= fields[11].GetUInt32(); data.curhealth = fields[12].GetUInt32(); @@ -1449,7 +1453,7 @@ void ObjectMgr::LoadCreatures() data.movementType = fields[14].GetUInt8(); data.spawnMask = fields[15].GetUInt8(); data.phaseMask = fields[16].GetUInt16(); - int16 gameEvent = fields[17].GetInt16(); + int16 gameEvent = fields[17].GetInt8(); uint32 PoolId = fields[18].GetUInt32(); data.npcflag = fields[19].GetUInt32(); data.unit_flags = fields[20].GetUInt32(); @@ -1731,8 +1735,8 @@ void ObjectMgr::LoadGameobjects() { Field* fields = result->Fetch(); - uint32 guid = fields[ 0].GetUInt32(); - uint32 entry = fields[ 1].GetUInt32(); + uint32 guid = fields[0].GetUInt32(); + uint32 entry = fields[1].GetUInt32(); GameObjectTemplate const* gInfo = GetGameObjectTemplate(entry); if (!gInfo) @@ -1763,14 +1767,14 @@ void ObjectMgr::LoadGameobjects() GameObjectData& data = _gameObjectDataStore[guid]; data.id = entry; - data.mapid = fields[ 2].GetUInt32(); - data.posX = fields[ 3].GetFloat(); - data.posY = fields[ 4].GetFloat(); - data.posZ = fields[ 5].GetFloat(); - data.orientation = fields[ 6].GetFloat(); - data.rotation0 = fields[ 7].GetFloat(); - data.rotation1 = fields[ 8].GetFloat(); - data.rotation2 = fields[ 9].GetFloat(); + data.mapid = fields[2].GetUInt32(); + data.posX = fields[3].GetFloat(); + data.posY = fields[4].GetFloat(); + data.posZ = fields[5].GetFloat(); + data.orientation = fields[6].GetFloat(); + data.rotation0 = fields[7].GetFloat(); + data.rotation1 = fields[8].GetFloat(); + data.rotation2 = fields[9].GetFloat(); data.rotation3 = fields[10].GetFloat(); data.spawntimesecs = fields[11].GetInt32(); @@ -1903,7 +1907,7 @@ void ObjectMgr::LoadGameobjectRespawnTimes() uint32 oldMSTime = getMSTime(); // Remove outdated data - CharacterDatabase.DirectExecute(CharacterDatabase.GetPreparedStatement(CHAR_DEL_EXPIRED_GO_RESPAWNS)); + CharacterDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE respawnTime <= UNIX_TIMESTAMP(NOW())"); uint32 count = 0; @@ -1943,10 +1947,12 @@ uint64 ObjectMgr::GetPlayerGUIDByName(std::string name) const { uint64 guid = 0; - CharacterDatabase.EscapeString(name); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_BY_NAME); + + stmt->setString(0, name); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); - // Player name safe to sending to DB (checked at login) and this function using - QueryResult result = CharacterDatabase.PQuery("SELECT guid FROM characters WHERE name = '%s'", name.c_str()); if (result) guid = MAKE_NEW_GUID((*result)[0].GetUInt32(), 0, HIGHGUID_PLAYER); @@ -1962,7 +1968,11 @@ bool ObjectMgr::GetPlayerNameByGUID(uint64 guid, std::string &name) const return true; } - QueryResult result = CharacterDatabase.PQuery("SELECT name FROM characters WHERE guid = '%u'", GUID_LOPART(guid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_NAME); + + stmt->setUInt32(0, GUID_LOPART(guid)); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { @@ -1981,7 +1991,11 @@ uint32 ObjectMgr::GetPlayerTeamByGUID(uint64 guid) const return Player::TeamForRace(player->getRace()); } - QueryResult result = CharacterDatabase.PQuery("SELECT race FROM characters WHERE guid = '%u'", GUID_LOPART(guid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_RACE); + + stmt->setUInt32(0, GUID_LOPART(guid)); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { @@ -2000,7 +2014,12 @@ uint32 ObjectMgr::GetPlayerAccountIdByGUID(uint64 guid) const return player->GetSession()->GetAccountId(); } - QueryResult result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE guid = '%u'", GUID_LOPART(guid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ACCOUNT_BY_GUID); + + stmt->setUInt32(0, GUID_LOPART(guid)); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (result) { uint32 acc = (*result)[0].GetUInt32(); @@ -2012,7 +2031,12 @@ uint32 ObjectMgr::GetPlayerAccountIdByGUID(uint64 guid) const uint32 ObjectMgr::GetPlayerAccountIdByPlayerName(const std::string& name) const { - QueryResult result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name = '%s'", name.c_str()); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ACCOUNT_BY_NAME); + + stmt->setString(0, name); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (result) { uint32 acc = (*result)[0].GetUInt32(); @@ -4809,7 +4833,9 @@ void ObjectMgr::LoadWaypointScripts() for (ScriptMapMap::const_iterator itr = sWaypointScripts.begin(); itr != sWaypointScripts.end(); ++itr) actionSet.insert(itr->first); - QueryResult result = WorldDatabase.PQuery("SELECT DISTINCT(`action`) FROM waypoint_data"); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WOLRD_SEL_WAYPOINT_DATA_ACTION); + PreparedQueryResult result = WorldDatabase.Query(stmt); + if (result) { do @@ -5377,7 +5403,7 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) } } - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_BY_ID); stmt->setUInt32(0, m->messageID); CharacterDatabase.Execute(stmt); delete m; @@ -5949,7 +5975,7 @@ void ObjectMgr::LoadAreaTriggerTeleports() AreaTrigger at; - at.target_mapId = fields[1].GetUInt32(); + at.target_mapId = fields[1].GetUInt16(); at.target_X = fields[2].GetFloat(); at.target_Y = fields[3].GetFloat(); at.target_Z = fields[4].GetFloat(); @@ -6811,13 +6837,13 @@ void ObjectMgr::LoadReputationOnKill() uint32 creature_id = fields[0].GetUInt32(); ReputationOnKillEntry repOnKill; - repOnKill.RepFaction1 = fields[1].GetUInt32(); - repOnKill.RepFaction2 = fields[2].GetUInt32(); + repOnKill.RepFaction1 = fields[1].GetInt16(); + repOnKill.RepFaction2 = fields[2].GetInt16(); repOnKill.IsTeamAward1 = fields[3].GetBool(); - repOnKill.ReputationMaxCap1 = fields[4].GetUInt32(); + repOnKill.ReputationMaxCap1 = fields[4].GetUInt8(); repOnKill.RepValue1 = fields[5].GetInt32(); repOnKill.IsTeamAward2 = fields[6].GetBool(); - repOnKill.ReputationMaxCap2 = fields[7].GetUInt32(); + repOnKill.ReputationMaxCap2 = fields[7].GetUInt8(); repOnKill.RepValue2 = fields[8].GetInt32(); repOnKill.TeamDependent = fields[9].GetUInt8(); @@ -7033,8 +7059,8 @@ void ObjectMgr::LoadQuestPOI() return; } - // 0 1 2 3 - QueryResult points = WorldDatabase.PQuery("SELECT questId, id, x, y FROM quest_poi_points ORDER BY questId DESC, idx"); + // 0 1 2 3 + QueryResult points = WorldDatabase.Query("SELECT questId, id, x, y FROM quest_poi_points ORDER BY questId DESC, idx"); std::vector<std::vector<std::vector<QuestPOIPoint> > > POIs; @@ -8189,7 +8215,10 @@ void ObjectMgr::LoadTrainerSpell() int ObjectMgr::LoadReferenceVendor(int32 vendor, int32 item, std::set<uint32> *skip_vendors) { // find all items from the reference vendor - QueryResult result = WorldDatabase.PQuery("SELECT item, maxcount, incrtime, ExtendedCost FROM npc_vendor WHERE entry='%d' ORDER BY slot ASC", item); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_NPC_VENDOR_REF); + stmt->setUInt32(0, uint32(item)); + PreparedQueryResult result = WorldDatabase.Query(stmt); + if (!result) return 0; @@ -8205,7 +8234,7 @@ int ObjectMgr::LoadReferenceVendor(int32 vendor, int32 item, std::set<uint32> *s count += LoadReferenceVendor(vendor, -item_id, skip_vendors); else { - int32 maxcount = fields[1].GetInt32(); + int32 maxcount = fields[1].GetUInt8(); // tinyint(3) unsigned uint32 incrtime = fields[2].GetUInt32(); uint32 ExtendedCost = fields[3].GetUInt32(); @@ -8663,16 +8692,16 @@ void ObjectMgr::LoadCreatureClassLevelStats() { Field* fields = result->Fetch(); - uint8 Level = fields[0].GetUInt8(); - uint8 Class = fields[1].GetUInt8(); + uint8 Level = fields[0].GetInt8(); + uint8 Class = fields[1].GetInt8(); CreatureBaseStats stats; for (uint8 i = 0; i < MAX_CREATURE_BASE_HP; ++i) - stats.BaseHealth[i] = fields[i + 2].GetUInt32(); + stats.BaseHealth[i] = fields[i + 2].GetInt16(); - stats.BaseMana = fields[5].GetUInt32(); - stats.BaseArmor = fields[6].GetUInt32(); + stats.BaseMana = fields[5].GetInt16(); + stats.BaseArmor = fields[6].GetInt16(); if (!Class || ((1 << (Class - 1)) & CLASSMASK_ALL_CREATURES) == 0) sLog->outErrorDb("Creature base stats for level %u has invalid class %u", Level, Class); diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index c639da15113..e623b98a13a 100755 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -858,6 +858,30 @@ namespace Trinity float i_range; }; + class AnyGroupedUnitInObjectRangeCheck + { + public: + AnyGroupedUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool raid) : _source(obj), _refUnit(funit), _range(range), _raid(raid) {} + bool operator()(Unit* u) + { + if (_raid) + { + if (!_refUnit->IsInRaidWith(u)) + return false; + } + else if (!_refUnit->IsInPartyWith(u)) + return false; + + return !_refUnit->IsHostileTo(u) && u->isAlive() && _source->IsWithinDistInMap(u, _range); + } + + private: + WorldObject const* _source; + Unit const* _refUnit; + float _range; + bool _raid; + }; + class AnyUnitInObjectRangeCheck { public: diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 9879ef7ff3b..a27ea9eb281 100755 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -698,13 +698,21 @@ void Group::Disband(bool hideDestroy /* = false */) if (!isBGGroup()) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); - trans->PAppend("DELETE FROM groups WHERE guid = %u", m_dbStoreId); - trans->PAppend("DELETE FROM group_member WHERE guid = %u", m_dbStoreId); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP); + stmt->setUInt32(0, m_dbStoreId); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_MEMBER_ALL); + stmt->setUInt32(0, m_dbStoreId); + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); + ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, NULL); ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL); - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_LFG_DATA); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_LFG_DATA); stmt->setUInt32(0, m_dbStoreId); CharacterDatabase.Execute(stmt); diff --git a/src/server/game/Groups/GroupMgr.cpp b/src/server/game/Groups/GroupMgr.cpp index ae400852c73..3d901f42501 100644 --- a/src/server/game/Groups/GroupMgr.cpp +++ b/src/server/game/Groups/GroupMgr.cpp @@ -120,7 +120,7 @@ void GroupMgr::LoadGroups() CharacterDatabase.DirectExecute("DELETE FROM groups WHERE guid NOT IN (SELECT guid FROM group_member GROUP BY guid HAVING COUNT(guid) > 1)"); // 0 1 2 3 4 5 6 7 8 9 - QueryResult result = CharacterDatabase.PQuery("SELECT g.leaderGuid, g.lootMethod, g.looterGuid, g.lootThreshold, g.icon1, g.icon2, g.icon3, g.icon4, g.icon5, g.icon6" + QueryResult result = CharacterDatabase.Query("SELECT g.leaderGuid, g.lootMethod, g.looterGuid, g.lootThreshold, g.icon1, g.icon2, g.icon3, g.icon4, g.icon5, g.icon6" // 10 11 12 13 14 15 16 17 ", g.icon7, g.icon8, g.groupType, g.difficulty, g.raiddifficulty, g.guid, lfg.dungeon, lfg.state FROM groups g LEFT JOIN lfg_data lfg ON lfg.guid = g.guid ORDER BY g.guid ASC"); if (!result) diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index f82c52204fb..d26f275b864 100755 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -438,7 +438,11 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) auction->bid = price; GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price); - trans->PAppend("UPDATE auctionhouse SET buyguid = '%u', lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_AUCTION_BID); + stmt->setUInt32(0, auction->bidder); + stmt->setUInt32(1, auction->bid); + stmt->setUInt32(2, auction->Id); + trans->Append(stmt); SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK, 0); } diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 15e05ccfbf7..f6051cd4c6e 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -640,7 +640,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte SQLTransaction trans = LoginDatabase.BeginTransaction(); - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM); stmt->setUInt32(0, GetAccountId()); stmt->setUInt32(1, realmID); trans->Append(stmt); @@ -702,12 +702,17 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket & recv_data) return; } - QueryResult result = CharacterDatabase.PQuery("SELECT account, name FROM characters WHERE guid='%u'", GUID_LOPART(guid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ACCOUNT_NAME_BY_GUID); + + stmt->setUInt32(0, GUID_LOPART(guid)); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (result) { Field* fields = result->Fetch(); - accountId = fields[0].GetUInt32(); - name = fields[1].GetString(); + accountId = fields[0].GetUInt32(); + name = fields[1].GetString(); } // prevent deleting other players' characters using cheating tools @@ -1264,9 +1269,19 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data) CharacterDatabase.EscapeString(declinedname.name[i]); SQLTransaction trans = CharacterDatabase.BeginTransaction(); - trans->PAppend("DELETE FROM character_declinedname WHERE guid = '%u'", GUID_LOPART(guid)); - trans->PAppend("INSERT INTO character_declinedname (guid, genitive, dative, accusative, instrumental, prepositional) VALUES ('%u', '%s', '%s', '%s', '%s', '%s')", - GUID_LOPART(guid), declinedname.name[0].c_str(), declinedname.name[1].c_str(), declinedname.name[2].c_str(), declinedname.name[3].c_str(), declinedname.name[4].c_str()); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_DECLINED_NAME); + stmt->setUInt32(0, GUID_LOPART(guid)); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_DECLINED_NAME); + stmt->setUInt32(0, GUID_LOPART(guid)); + + for (uint8 i = 0; i < 5; i++) + stmt->setString(i+1, declinedname.name[i]); + + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); @@ -1363,7 +1378,12 @@ void WorldSession::HandleCharCustomize(WorldPacket& recv_data) uint8 gender, skin, face, hairStyle, hairColor, facialHair; recv_data >> gender >> skin >> hairColor >> hairStyle >> facialHair >> face; - QueryResult result = CharacterDatabase.PQuery("SELECT at_login FROM characters WHERE guid ='%u'", GUID_LOPART(guid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_AT_LOGIN); + + stmt->setUInt32(0, GUID_LOPART(guid)); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) { WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); @@ -1422,15 +1442,18 @@ void WorldSession::HandleCharCustomize(WorldPacket& recv_data) } } - if (QueryResult oldNameResult = CharacterDatabase.PQuery("SELECT name FROM characters WHERE guid ='%u'", GUID_LOPART(guid))) + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_NAME); + stmt->setUInt32(0, GUID_LOPART(guid)); + result = CharacterDatabase.Query(stmt); + + if (result) { - std::string oldname = oldNameResult->Fetch()[0].GetString(); - std::string IP_str = GetRemoteAddress(); - sLog->outChar("Account: %d (IP: %s), Character[%s] (guid:%u) Customized to: %s", GetAccountId(), IP_str.c_str(), oldname.c_str(), GUID_LOPART(guid), newName.c_str()); + std::string oldname = result->Fetch()[0].GetString(); + sLog->outChar("Account: %d (IP: %s), Character[%s] (guid:%u) Customized to: %s", GetAccountId(), GetRemoteAddress().c_str(), oldname.c_str(), GUID_LOPART(guid), newName.c_str()); } Player::Customize(guid, gender, skin, face, hairStyle, hairColor, facialHair); - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN); stmt->setString(0, newName); stmt->setUInt16(1, uint16(AT_LOGIN_CUSTOMIZE)); @@ -1575,7 +1598,13 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) recv_data >> gender >> skin >> hairColor >> hairStyle >> facialHair >> face >> race; uint32 lowGuid = GUID_LOPART(guid); - QueryResult result = CharacterDatabase.PQuery("SELECT class, level, at_login FROM characters WHERE guid ='%u'", lowGuid); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CLASS_LVL_AT_LOGIN); + + stmt->setUInt32(0, lowGuid); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) { WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1); @@ -1660,8 +1689,18 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) CharacterDatabase.EscapeString(newname); Player::Customize(guid, gender, skin, face, hairStyle, hairColor, facialHair); SQLTransaction trans = CharacterDatabase.BeginTransaction(); - trans->PAppend("UPDATE `characters` SET name='%s', race='%u', at_login=at_login & ~ %u WHERE guid='%u'", newname.c_str(), race, used_loginFlag, lowGuid); - trans->PAppend("DELETE FROM character_declinedname WHERE guid ='%u'", lowGuid); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_FACTION_OR_RACE); + stmt->setString(0, newname); + stmt->setUInt8(1, race); + stmt->setUInt16(2, used_loginFlag); + stmt->setUInt32(3, lowGuid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_DECLINED_NAME); + stmt->setUInt32(0, lowGuid); + trans->Append(stmt); + sWorld->UpdateCharacterNameData(GUID_LOPART(guid), newname, gender, race); BattlegroundTeamId team = BG_TEAM_ALLIANCE; @@ -1682,52 +1721,68 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) // Switch Languages // delete all languages first - trans->PAppend("DELETE FROM `character_skills` WHERE `skill` IN (98, 113, 759, 111, 313, 109, 115, 315, 673, 137) AND `guid`='%u'", lowGuid); - // now add them back + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SKILL_LANGUAGES); + stmt->setUInt32(0, lowGuid); + trans->Append(stmt); + + // Now add them back + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SKILL_LANGUAGE); + stmt->setUInt32(0, lowGuid); + + + // Faction specific languages if (team == BG_TEAM_ALLIANCE) { - trans->PAppend("INSERT INTO `character_skills` (guid, skill, value, max) VALUES (%u, 98, 300, 300)", lowGuid); - switch (race) - { - case RACE_DWARF: - trans->PAppend("INSERT INTO `character_skills` (guid, skill, value, max) VALUES (%u, 111, 300, 300)", lowGuid); - break; - case RACE_DRAENEI: - trans->PAppend("INSERT INTO `character_skills` (guid, skill, value, max) VALUES (%u, 759, 300, 300)", lowGuid); - break; - case RACE_GNOME: - trans->PAppend("INSERT INTO `character_skills` (guid, skill, value, max) VALUES (%u, 313, 300, 300)", lowGuid); - break; - case RACE_NIGHTELF: - trans->PAppend("INSERT INTO `character_skills` (guid, skill, value, max) VALUES (%u, 113, 300, 300)", lowGuid); - break; - } + stmt->setUInt16(1, 98); } else if (team == BG_TEAM_HORDE) { - trans->PAppend("INSERT INTO `character_skills` (guid, skill, value, max) VALUES (%u, 109, 300, 300)", lowGuid); - switch (race) - { - case RACE_UNDEAD_PLAYER: - trans->PAppend("INSERT INTO `character_skills` (guid, skill, value, max) VALUES (%u, 673, 300, 300)", lowGuid); - break; - case RACE_TAUREN: - trans->PAppend("INSERT INTO `character_skills` (guid, skill, value, max) VALUES (%u, 115, 300, 300)", lowGuid); - break; - case RACE_TROLL: - trans->PAppend("INSERT INTO `character_skills` (guid, skill, value, max) VALUES (%u, 315, 300, 300)", lowGuid); - break; - case RACE_BLOODELF: - trans->PAppend("INSERT INTO `character_skills` (guid, skill, value, max) VALUES (%u, 137, 300, 300)", lowGuid); - break; - } + stmt->setUInt16(1, 109); } + trans->Append(stmt); + + // Race specific languages + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SKILL_LANGUAGE); + stmt->setUInt32(0, lowGuid); + + switch (race) + { + case RACE_DWARF: + stmt->setUInt16(1, 111); + break; + case RACE_DRAENEI: + stmt->setUInt16(1, 759); + break; + case RACE_GNOME: + stmt->setUInt16(1, 313); + break; + case RACE_NIGHTELF: + stmt->setUInt16(1, 113); + break; + case RACE_UNDEAD_PLAYER: + stmt->setUInt16(1, 673); + break; + case RACE_TAUREN: + stmt->setUInt16(1, 115); + break; + case RACE_TROLL: + stmt->setUInt16(1, 315); + break; + case RACE_BLOODELF: + stmt->setUInt16(1, 137); + break; + } + + trans->Append(stmt); + if (recv_data.GetOpcode() == CMSG_CHAR_FACTION_CHANGE) { // Delete all Flypaths - trans->PAppend("UPDATE `characters` SET taxi_path = '' WHERE guid ='%u'", lowGuid); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXI_PATH); + stmt->setUInt32(0, lowGuid); + trans->Append(stmt); if (level > 7) { @@ -1769,11 +1824,17 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) taximaskstream << "0 "; taximaskstream << '0'; std::string taximask = taximaskstream.str(); - trans->PAppend("UPDATE `characters` SET `taximask`= '%s' WHERE `guid` = '%u'", taximask.c_str(), lowGuid); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXIMASK); + stmt->setString(0, taximask); + stmt->setUInt32(1, lowGuid); + trans->Append(stmt); } // Delete all current quests - trans->PAppend("DELETE FROM `character_queststatus` WHERE guid ='%u'", GUID_LOPART(guid)); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS); + stmt->setUInt32(0, GUID_LOPART(guid)); + trans->Append(stmt); // Delete record of the faction old completed quests { @@ -1811,23 +1872,34 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD)) { // Reset guild - if (QueryResult result2 = CharacterDatabase.PQuery("SELECT guildid FROM `guild_member` WHERE guid ='%u'", lowGuid)) - if (Guild* guild = sGuildMgr->GetGuildById((result2->Fetch()[0]).GetUInt32())) + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER); + + stmt->setUInt32(0, lowGuid); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (result) + if (Guild* guild = sGuildMgr->GetGuildById((result->Fetch()[0]).GetUInt32())) guild->DeleteMember(MAKE_NEW_GUID(lowGuid, 0, HIGHGUID_PLAYER)); } if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND)) { // Delete Friend List - trans->PAppend("DELETE FROM `character_social` WHERE `guid`= '%u'", lowGuid); - trans->PAppend("DELETE FROM `character_social` WHERE `friend`= '%u'", lowGuid); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SOCIAL_BY_GUID); + stmt->setUInt32(0, lowGuid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SOCIAL_BY_FRIEND); + stmt->setUInt32(0, lowGuid); + trans->Append(stmt); + } // Leave Arena Teams Player::LeaveAllArenaTeams(guid); // Reset homebind and position - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_HOMEBIND); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_HOMEBIND); stmt->setUInt32(0, lowGuid); trans->Append(stmt); @@ -1858,10 +1930,17 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) { uint32 achiev_alliance = it->first; uint32 achiev_horde = it->second; - trans->PAppend("DELETE FROM `character_achievement` WHERE `achievement`=%u AND `guid`=%u", - team == BG_TEAM_ALLIANCE ? achiev_alliance : achiev_horde, lowGuid); - trans->PAppend("UPDATE `character_achievement` SET achievement = '%u' where achievement = '%u' AND guid = '%u'", - team == BG_TEAM_ALLIANCE ? achiev_alliance : achiev_horde, team == BG_TEAM_ALLIANCE ? achiev_horde : achiev_alliance, lowGuid); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT); + stmt->setUInt16(0, uint16(team == BG_TEAM_ALLIANCE ? achiev_alliance : achiev_horde)); + stmt->setUInt32(1, lowGuid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ACHIEVEMENT); + stmt->setUInt16(0, uint16(team == BG_TEAM_ALLIANCE ? achiev_alliance : achiev_horde)); + stmt->setUInt16(1, uint16(team == BG_TEAM_ALLIANCE ? achiev_horde : achiev_alliance)); + stmt->setUInt32(2, lowGuid); + trans->Append(stmt); } // Item conversion @@ -1869,8 +1948,12 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) { uint32 item_alliance = it->first; uint32 item_horde = it->second; - trans->PAppend("UPDATE `item_instance` ii, `character_inventory` ci SET ii.itemEntry = '%u' WHERE ii.itemEntry = '%u' AND ci.guid = '%u' AND ci.item = ii.guid", - team == BG_TEAM_ALLIANCE ? item_alliance : item_horde, team == BG_TEAM_ALLIANCE ? item_horde : item_alliance, guid); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE); + stmt->setUInt32(0, (team == BG_TEAM_ALLIANCE ? item_alliance : item_horde)); + stmt->setUInt32(1, (team == BG_TEAM_ALLIANCE ? item_horde : item_alliance)); + stmt->setUInt32(2, guid); + trans->Append(stmt); } // Spell conversion @@ -1878,10 +1961,17 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) { uint32 spell_alliance = it->first; uint32 spell_horde = it->second; - trans->PAppend("DELETE FROM `character_spell` WHERE `spell`=%u AND `guid`=%u", - team == BG_TEAM_ALLIANCE ? spell_alliance : spell_horde, lowGuid); - trans->PAppend("UPDATE `character_spell` SET spell = '%u' where spell = '%u' AND guid = '%u'", - team == BG_TEAM_ALLIANCE ? spell_alliance : spell_horde, team == BG_TEAM_ALLIANCE ? spell_horde : spell_alliance, lowGuid); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SPELL_BY_SPELL); + stmt->setUInt32(0, (team == BG_TEAM_ALLIANCE ? spell_alliance : spell_horde)); + stmt->setUInt32(1, lowGuid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_SPELL_FACTION_CHANGE); + stmt->setUInt32(0, (team == BG_TEAM_ALLIANCE ? spell_alliance : spell_horde)); + stmt->setUInt32(1, (team == BG_TEAM_ALLIANCE ? spell_horde : spell_alliance)); + stmt->setUInt32(2, lowGuid); + trans->Append(stmt); } // Reputation conversion @@ -1889,10 +1979,17 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) { uint32 reputation_alliance = it->first; uint32 reputation_horde = it->second; - trans->PAppend("DELETE FROM character_reputation WHERE faction = '%u' AND guid = '%u'", - team == BG_TEAM_ALLIANCE ? reputation_alliance : reputation_horde, lowGuid); - trans->PAppend("UPDATE `character_reputation` SET faction = '%u' where faction = '%u' AND guid = '%u'", - team == BG_TEAM_ALLIANCE ? reputation_alliance : reputation_horde, team == BG_TEAM_ALLIANCE ? reputation_horde : reputation_alliance, lowGuid); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_REP_BY_FACTION); + stmt->setUInt32(0, uint16(team == BG_TEAM_ALLIANCE ? reputation_alliance : reputation_horde)); + stmt->setUInt32(1, lowGuid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_REP_FACTION_CHANGE); + stmt->setUInt16(0, uint16(team == BG_TEAM_ALLIANCE ? reputation_alliance : reputation_horde)); + stmt->setUInt16(1, uint16(team == BG_TEAM_ALLIANCE ? reputation_horde : reputation_alliance)); + stmt->setUInt32(2, lowGuid); + trans->Append(stmt); } } diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 9343a5356b6..637025c7d9e 100755 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -430,7 +430,8 @@ void WorldSession::HandleLootMethodOpcode(WorldPacket & recv_data) void WorldSession::HandleLootRoll(WorldPacket &recv_data) { - if (!GetPlayer()->GetGroup()) + Group* group = GetPlayer()->GetGroup(); + if (!group) { recv_data.rfinish(); return; @@ -443,12 +444,6 @@ void WorldSession::HandleLootRoll(WorldPacket &recv_data) recv_data >> NumberOfPlayers; recv_data >> rollType; //0: pass, 1: need, 2: greed - //sLog->outDebug("WORLD RECIEVE CMSG_LOOT_ROLL, From:%u, Numberofplayers:%u, Choise:%u", (uint32)Guid, NumberOfPlayers, Choise); - - Group* group = GetPlayer()->GetGroup(); - if (!group) - return; - // everything's fine, do it group->CountRollVote(GetPlayer()->GetGUID(), Guid, NumberOfPlayers, rollType); diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 2434ba6eaa7..8a60f21dac9 100755 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -1124,7 +1124,14 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data) } SQLTransaction trans = CharacterDatabase.BeginTransaction(); - trans->PAppend("INSERT INTO character_gifts VALUES ('%u', '%u', '%u', '%u')", GUID_LOPART(item->GetOwnerGUID()), item->GetGUIDLow(), item->GetEntry(), item->GetUInt32Value(ITEM_FIELD_FLAGS)); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_GIFT); + stmt->setUInt32(0, GUID_LOPART(item->GetOwnerGUID())); + stmt->setUInt32(0, item->GetGUIDLow()); + stmt->setUInt32(0, item->GetEntry()); + stmt->setUInt32(0, item->GetUInt32Value(ITEM_FIELD_FLAGS)); + trans->Append(stmt); + item->SetEntry(gift->GetEntry()); switch (item->GetEntry()) diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index a8522bb2582..72488966416 100755 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -128,12 +128,26 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data) else { rc_team = sObjectMgr->GetPlayerTeamByGUID(rc); - if (QueryResult result = CharacterDatabase.PQuery("SELECT COUNT(*) FROM mail WHERE receiver = '%u'", GUID_LOPART(rc))) + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT); + + stmt->setUInt32(0, GUID_LOPART(rc)); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); + + if (result) { Field* fields = result->Fetch(); mails_count = fields[0].GetUInt32(); } - if (QueryResult result = CharacterDatabase.PQuery("SELECT level FROM characters WHERE guid = '%u'", GUID_LOPART(rc))) + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_LEVEL); + + stmt->setUInt32(0, GUID_LOPART(rc)); + + result = CharacterDatabase.Query(stmt); + + if (result) { Field* fields = result->Fetch(); receiveLevel = fields[0].GetUInt8(); @@ -360,8 +374,15 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data) //we can return mail now //so firstly delete the old one SQLTransaction trans = CharacterDatabase.BeginTransaction(); - trans->PAppend("DELETE FROM mail WHERE id = '%u'", mailId); // needed? - trans->PAppend("DELETE FROM mail_items WHERE mail_id = '%u'", mailId); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_BY_ID); + stmt->setUInt32(0, mailId); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM_BY_ID); + stmt->setUInt32(0, mailId); + trans->Append(stmt); + player->RemoveMail(mailId); // only return mail if the player exists (and delete if not existing) diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 17f96a0fcda..35872f8c63f 100755 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1303,7 +1303,12 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recv_data) uint32 accid = player->GetSession()->GetAccountId(); - QueryResult result = LoginDatabase.PQuery("SELECT username, email, last_ip FROM account WHERE id=%u", accid); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_WHOIS); + + stmt->setUInt32(0, accid); + + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (!result) { SendNotification(LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND, charname.c_str()); diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 8da7683459e..1fa6d9fc0ed 100755 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -647,15 +647,25 @@ void WorldSession::HandlePetRename(WorldPacket & recv_data) SQLTransaction trans = CharacterDatabase.BeginTransaction(); if (isdeclined) { - for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) - CharacterDatabase.EscapeString(declinedname.name[i]); - trans->PAppend("DELETE FROM character_pet_declinedname WHERE owner = '%u' AND id = '%u'", _player->GetGUIDLow(), pet->GetCharmInfo()->GetPetNumber()); - trans->PAppend("INSERT INTO character_pet_declinedname (id, owner, genitive, dative, accusative, instrumental, prepositional) VALUES ('%u', '%u', '%s', '%s', '%s', '%s', '%s')", - pet->GetCharmInfo()->GetPetNumber(), _player->GetGUIDLow(), declinedname.name[0].c_str(), declinedname.name[1].c_str(), declinedname.name[2].c_str(), declinedname.name[3].c_str(), declinedname.name[4].c_str()); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME); + stmt->setUInt32(0, pet->GetCharmInfo()->GetPetNumber()); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_CHAR_PET_DECLINEDNAME); + stmt->setUInt32(0, _player->GetGUIDLow()); + + for (uint8 i = 0; i < 5; i++) + stmt->setString(i+1, declinedname.name[i]); + + trans->Append(stmt); } - CharacterDatabase.EscapeString(name); - trans->PAppend("UPDATE character_pet SET name = '%s', renamed = '1' WHERE owner = '%u' AND id = '%u'", name.c_str(), _player->GetGUIDLow(), pet->GetCharmInfo()->GetPetNumber()); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_NAME); + stmt->setString(0, name); + stmt->setUInt32(1, _player->GetGUIDLow()); + stmt->setUInt32(2, pet->GetCharmInfo()->GetPetNumber()); + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp index 38d17d8c3b6..a6a6637deaf 100755 --- a/src/server/game/Handlers/PetitionsHandler.cpp +++ b/src/server/game/Handlers/PetitionsHandler.cpp @@ -215,7 +215,10 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data) // a petition is invalid, if both the owner and the type matches // we checked above, if this player is in an arenateam, so this must be // datacorruption - QueryResult result = CharacterDatabase.PQuery("SELECT petitionguid FROM petition WHERE ownerguid = '%u' AND type = '%u'", _player->GetGUIDLow(), type); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_BY_OWNER); + stmt->setUInt32(0, _player->GetGUIDLow()); + stmt->setUInt8(1, type); + PreparedQueryResult result = CharacterDatabase.Query(stmt); std::ostringstream ssInvalidPetitionGUIDs; @@ -236,8 +239,14 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data) SQLTransaction trans = CharacterDatabase.BeginTransaction(); trans->PAppend("DELETE FROM petition WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str()); trans->PAppend("DELETE FROM petition_sign WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str()); - trans->PAppend("INSERT INTO petition (ownerguid, petitionguid, name, type) VALUES ('%u', '%u', '%s', '%u')", - _player->GetGUIDLow(), charter->GetGUIDLow(), name.c_str(), type); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PETITION); + stmt->setUInt32(0, _player->GetGUIDLow()); + stmt->setUInt32(1, charter->GetGUIDLow()); + stmt->setString(2, name); + stmt->setUInt8(3, uint8(type)); + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); } @@ -250,9 +259,14 @@ void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recv_data) recv_data >> petitionguid; // petition guid // solve (possible) some strange compile problems with explicit use GUID_LOPART(petitionguid) at some GCC versions (wrong code optimization in compiler?) - uint32 petitionguid_low = GUID_LOPART(petitionguid); + uint32 petitionGuidLow = GUID_LOPART(petitionguid); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_TYPE); + + stmt->setUInt32(0, petitionGuidLow); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); - QueryResult result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", petitionguid_low); if (!result) { sLog->outDebug(LOG_FILTER_PLAYER_ITEMS, "Petition %u is not found for player %u %s", GUID_LOPART(petitionguid), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName()); @@ -265,18 +279,22 @@ void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recv_data) if (type == GUILD_CHARTER_TYPE && _player->GetGuildId()) return; - result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", petitionguid_low); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURE); + + stmt->setUInt32(0, petitionGuidLow); + + result = CharacterDatabase.Query(stmt); // result == NULL also correct in case no sign yet if (result) signs = uint8(result->GetRowCount()); - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_PETITION_SHOW_SIGNATURES petition entry: '%u'", petitionguid_low); + sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_PETITION_SHOW_SIGNATURES petition entry: '%u'", petitionGuidLow); WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8+8+4+1+signs*12)); data << uint64(petitionguid); // petition guid data << uint64(_player->GetGUID()); // owner guid - data << uint32(petitionguid_low); // guild guid + data << uint32(petitionGuidLow); // guild guid data << uint8(signs); // sign's count for (uint8 i = 1; i <= signs; ++i) @@ -311,9 +329,11 @@ void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid) uint32 type; std::string name = "NO_NAME_FOR_GUID"; - // TODO: Use CHAR_LOAD_PETITION PS - QueryResult result = CharacterDatabase.PQuery("SELECT ownerguid, name, type " - "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION); + + stmt->setUInt32(0, GUID_LOPART(petitionguid)); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { @@ -382,7 +402,11 @@ void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recv_data) if (!item) return; - QueryResult result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionGuid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_TYPE); + + stmt->setUInt32(0, GUID_LOPART(petitionGuid)); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { @@ -422,7 +446,7 @@ void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recv_data) } } - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_PETITION_NAME); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_PETITION_NAME); stmt->setString(0, newName); stmt->setUInt32(1, GUID_LOPART(petitionGuid)); @@ -446,11 +470,12 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data) recv_data >> petitionGuid; // petition guid recv_data >> unk; - QueryResult result = CharacterDatabase.PQuery( - "SELECT ownerguid, " - " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs, " - " type " - "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionGuid), GUID_LOPART(petitionGuid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURES); + + stmt->setUInt32(0, GUID_LOPART(petitionGuid)); + stmt->setUInt32(1, GUID_LOPART(petitionGuid)); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); if (!result) { @@ -518,9 +543,14 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data) if (++signs > type) // client signs maximum return; - //client doesn't allow to sign petition two times by one character, but not check sign by another character from same account - //not allow sign another player from already sign player account - result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE player_account = '%u' AND petitionguid = '%u'", GetAccountId(), GUID_LOPART(petitionGuid)); + // Client doesn't allow to sign petition two times by one character, but not check sign by another character from same account + // not allow sign another player from already sign player account + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIG_BY_ACCOUNT); + + stmt->setUInt32(0, GetAccountId()); + stmt->setUInt32(1, GUID_LOPART(petitionGuid)); + + result = CharacterDatabase.Query(stmt); if (result) { @@ -538,7 +568,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data) return; } - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PETITION_SIGNATURE); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PETITION_SIGNATURE); stmt->setUInt32(0, GUID_LOPART(ownerGuid)); stmt->setUInt32(1, GUID_LOPART(petitionGuid)); @@ -576,7 +606,12 @@ void WorldSession::HandlePetitionDeclineOpcode(WorldPacket & recv_data) recv_data >> petitionguid; // petition guid sLog->outDebug(LOG_FILTER_NETWORKIO, "Petition %u declined by %u", GUID_LOPART(petitionguid), _player->GetGUIDLow()); - QueryResult result = CharacterDatabase.PQuery("SELECT ownerguid FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_OWNER_BY_GUID); + + stmt->setUInt32(0, GUID_LOPART(petitionguid)); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) return; @@ -608,7 +643,12 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recv_data) if (!player) return; - QueryResult result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_TYPE); + + stmt->setUInt32(0, GUID_LOPART(petitionguid)); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) return; @@ -667,7 +707,13 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recv_data) } } - result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURE); + + stmt->setUInt32(0, GUID_LOPART(petitionguid)); + + result = CharacterDatabase.Query(stmt); + // result == NULL also correct charter without signs if (result) signs = uint8(result->GetRowCount()); @@ -861,8 +907,15 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data) } SQLTransaction trans = CharacterDatabase.BeginTransaction(); - trans->PAppend("DELETE FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionGuid)); - trans->PAppend("DELETE FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionGuid)); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_BY_GUID); + stmt->setUInt32(0, GUID_LOPART(petitionGuid)); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_SIGNATURE); + stmt->setUInt32(0, GUID_LOPART(petitionGuid)); + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); // created diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index 9ea0e124112..36986075b4e 100755 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -241,7 +241,12 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))// wrapped? { - QueryResult result = CharacterDatabase.PQuery("SELECT entry, flags FROM character_gifts WHERE item_guid = '%u'", item->GetGUIDLow()); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_GIFT_BY_ITEM); + + stmt->setUInt32(0, item->GetGUIDLow()); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (result) { Field* fields = result->Fetch(); @@ -260,7 +265,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) return; } - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT); stmt->setUInt32(0, item->GetGUIDLow()); diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp index 557977f9468..ca39c137274 100755 --- a/src/server/game/Instances/InstanceSaveMgr.cpp +++ b/src/server/game/Instances/InstanceSaveMgr.cpp @@ -124,11 +124,21 @@ InstanceSave* InstanceSaveManager::GetInstanceSave(uint32 InstanceId) void InstanceSaveManager::DeleteInstanceFromDB(uint32 instanceid) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); - trans->PAppend("DELETE FROM instance WHERE id = '%u'", instanceid); - trans->PAppend("DELETE FROM character_instance WHERE instance = '%u'", instanceid); - trans->PAppend("DELETE FROM group_instance WHERE instance = '%u'", instanceid); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INSTANCE_BY_INSTANCE); + stmt->setUInt32(0, instanceid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE); + stmt->setUInt32(0, instanceid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_INSTANCE_BY_INSTANCE); + stmt->setUInt32(0, instanceid); + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); - // respawn times should be deleted only when the map gets unloaded + // Respawn times should be deleted only when the map gets unloaded } void InstanceSaveManager::RemoveInstanceSave(uint32 InstanceId) @@ -250,13 +260,13 @@ void InstanceSaveManager::LoadInstances() CharacterDatabase.DirectExecute("DELETE i.* FROM instance AS i LEFT JOIN character_instance AS ci ON i.id = ci.instance LEFT JOIN group_instance AS gi ON i.id = gi.instance WHERE ci.guid IS NULL AND gi.guid IS NULL"); // Delete invalid references to instance - CharacterDatabase.DirectExecute(CharacterDatabase.GetPreparedStatement(CHAR_DEL_NONEXISTENT_INSTANCE_CREATURE_RESPAWNS)); - CharacterDatabase.DirectExecute(CharacterDatabase.GetPreparedStatement(CHAR_DEL_NONEXISTENT_INSTANCE_GO_RESPAWNS)); + CharacterDatabase.DirectExecute("DELETE FROM creature_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)"); + CharacterDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)"); CharacterDatabase.DirectExecute("DELETE tmp.* FROM character_instance AS tmp LEFT JOIN instance ON tmp.instance = instance.id WHERE tmp.instance > 0 AND instance.id IS NULL"); CharacterDatabase.DirectExecute("DELETE tmp.* FROM group_instance AS tmp LEFT JOIN instance ON tmp.instance = instance.id WHERE tmp.instance > 0 AND instance.id IS NULL"); // Clean invalid references to instance - CharacterDatabase.DirectExecute(CharacterDatabase.GetPreparedStatement(CHAR_UPD_NONEXISTENT_INSTANCE_FOR_CORPSES)); + CharacterDatabase.DirectExecute("UPDATE corpse SET instanceId = 0 WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)"); CharacterDatabase.DirectExecute("UPDATE characters AS tmp LEFT JOIN instance ON tmp.instance_id = instance.id SET tmp.instance_id = 0 WHERE tmp.instance_id > 0 AND instance.id IS NULL"); // Initialize instance id storage (Needs to be done after the trash has been clean out) @@ -568,9 +578,22 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, b // delete them from the DB, even if not loaded SQLTransaction trans = CharacterDatabase.BeginTransaction(); - trans->PAppend("DELETE FROM character_instance USING character_instance LEFT JOIN instance ON character_instance.instance = id WHERE map = '%u' and difficulty='%u'", mapid, difficulty); - trans->PAppend("DELETE FROM group_instance USING group_instance LEFT JOIN instance ON group_instance.instance = id WHERE map = '%u' and difficulty='%u'", mapid, difficulty); - trans->PAppend("DELETE FROM instance WHERE map = '%u' and difficulty='%u'", mapid, difficulty); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INSTANCE_BY_MAP_DIFF); + stmt->setUInt16(0, uint16(mapid)); + stmt->setUInt8(0, uint8(difficulty)); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_INSTANCE_BY_MAP_DIFF); + stmt->setUInt16(0, uint16(mapid)); + stmt->setUInt8(0, uint8(difficulty)); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INSTANCE_BY_MAP_DIFF); + stmt->setUInt16(0, uint16(mapid)); + stmt->setUInt8(0, uint8(difficulty)); + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); // calculate the next reset time @@ -580,13 +603,13 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, b if (period < DAY) period = DAY; - uint32 next_reset = ((resetTime + MINUTE) / DAY * DAY) + period + diff; + uint32 next_reset = uint32(((resetTime + MINUTE) / DAY * DAY) + period + diff); SetResetTimeFor(mapid, difficulty, next_reset); ScheduleReset(true, time_t(next_reset-3600), InstResetEvent(1, mapid, difficulty, 0)); // Update it in the DB - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GLOBAL_INSTANCE_RESETTIME); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GLOBAL_INSTANCE_RESETTIME); stmt->setUInt32(0, next_reset); stmt->setUInt16(1, uint16(mapid)); diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 3522571775c..7c7cc06201c 100755 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -116,7 +116,7 @@ uint32 LootStore::LoadLootTable() uint16 lootmode = fields[3].GetUInt16(); uint8 group = fields[4].GetUInt8(); int32 mincountOrRef = fields[5].GetInt32(); - int32 maxcount = fields[6].GetInt32(); + int32 maxcount = fields[6].GetUInt8(); if (maxcount > std::numeric_limits<uint8>::max()) { diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 91ebea9f321..3be247947fe 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -1526,8 +1526,11 @@ inline ZLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 R { uint32 overrideLiquid = area->LiquidTypeOverride[liquidEntry->Type]; if (!overrideLiquid && area->zone) - if (area = GetAreaEntryByAreaID(area->zone)) + { + area = GetAreaEntryByAreaID(area->zone); + if (area) overrideLiquid = area->LiquidTypeOverride[liquidEntry->Type]; + } if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(overrideLiquid)) { @@ -1799,8 +1802,11 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp { uint32 overrideLiquid = area->LiquidTypeOverride[liquidFlagType]; if (!overrideLiquid && area->zone) - if (area = GetAreaEntryByAreaID(area->zone)) + { + area = GetAreaEntryByAreaID(area->zone); + if (area) overrideLiquid = area->LiquidTypeOverride[liquidFlagType]; + } if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(overrideLiquid)) { @@ -2527,7 +2533,11 @@ void InstanceMap::CreateInstanceData(bool load) if (load) { // TODO: make a global storage for this - QueryResult result = CharacterDatabase.PQuery("SELECT data, completedEncounters FROM instance WHERE map = '%u' AND id = '%u'", GetId(), i_InstanceId); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_INSTANCE); + stmt->setUInt16(0, uint16(GetId())); + stmt->setUInt32(1, i_InstanceId); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (result) { Field* fields = result->Fetch(); diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index c404277f61f..91a5f602327 100755 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -2589,7 +2589,7 @@ enum CreatureTypeFlags CREATURE_TYPEFLAGS_UNK23 = 0x00800000, // ? First seen in 3.2.2. Related to banner/backpack of creature/companion? CREATURE_TYPEFLAGS_UNK24 = 0x01000000, CREATURE_TYPEFLAGS_UNK25 = 0x02000000, - CREATURE_TYPEFLAGS_UNK26 = 0x04000000, + CREATURE_TYPEFLAGS_PARTY_MEMBER = 0x04000000, //! Creature can be targeted by spells that require target to be in caster's party/raid CREATURE_TYPEFLAGS_UNK27 = 0x08000000, CREATURE_TYPEFLAGS_UNK28 = 0x10000000, CREATURE_TYPEFLAGS_UNK29 = 0x20000000, diff --git a/src/server/game/Movement/Waypoints/WaypointManager.cpp b/src/server/game/Movement/Waypoints/WaypointManager.cpp index b957674151b..2c3a58f55a3 100755 --- a/src/server/game/Movement/Waypoints/WaypointManager.cpp +++ b/src/server/game/Movement/Waypoints/WaypointManager.cpp @@ -100,7 +100,12 @@ void WaypointMgr::ReloadPath(uint32 id) _waypointStore.erase(itr); } - QueryResult result = WorldDatabase.PQuery("SELECT point, position_x, position_y, position_z, orientation, move_flag, delay, action, action_chance FROM waypoint_data WHERE id = %u ORDER BY point", id); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_BY_ID); + + stmt->setUInt32(0, id); + + PreparedQueryResult result = WorldDatabase.Query(stmt); + if (!result) return; diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp index 88e6db971f0..608067935ea 100755 --- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp @@ -27,7 +27,7 @@ OutdoorPvPMgr::OutdoorPvPMgr() //sLog->outDebug(LOG_FILTER_OUTDOORPVP, "Instantiating OutdoorPvPMgr"); } -OutdoorPvPMgr::~OutdoorPvPMgr() +void OutdoorPvPMgr::Die() { //sLog->outDebug(LOG_FILTER_OUTDOORPVP, "Deleting OutdoorPvPMgr"); for (OutdoorPvPSet::iterator itr = m_OutdoorPvPSet.begin(); itr != m_OutdoorPvPSet.end(); ++itr) diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h index 3a66a87ecba..1313e29bfb4 100755 --- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h +++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h @@ -42,12 +42,15 @@ class OutdoorPvPMgr private: OutdoorPvPMgr(); - ~OutdoorPvPMgr(); + ~OutdoorPvPMgr() {}; public: // create outdoor pvp events void InitOutdoorPvP(); + // cleanup + void Die(); + // called when a player enters an outdoor pvp area void HandlePlayerEnterZone(Player* player, uint32 areaflag); diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp index 05ce7a0a50d..71204f92826 100755 --- a/src/server/game/Pools/PoolMgr.cpp +++ b/src/server/game/Pools/PoolMgr.cpp @@ -440,7 +440,12 @@ void PoolGroup<Quest>::SpawnObject(ActivePoolData& spawns, uint32 limit, uint32 // load state from db if (!triggerFrom) { - QueryResult result = CharacterDatabase.PQuery("SELECT quest_id FROM pool_quest_save WHERE pool_id = %u", poolId); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_POOL_QUEST_SAVE); + + stmt->setUInt32(0, poolId); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (result) { do diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp index 2a50f6e3c85..a9a02170e5f 100755 --- a/src/server/game/Reputation/ReputationMgr.cpp +++ b/src/server/game/Reputation/ReputationMgr.cpp @@ -568,8 +568,18 @@ void ReputationMgr::SaveToDB(SQLTransaction& trans) { if (itr->second.needSave) { - trans->PAppend("DELETE FROM character_reputation WHERE guid = '%u' AND faction='%u'", _player->GetGUIDLow(), itr->second.ID); - trans->PAppend("INSERT INTO character_reputation (guid, faction, standing, flags) VALUES ('%u', '%u', '%i', '%u')", _player->GetGUIDLow(), itr->second.ID, itr->second.Standing, itr->second.Flags); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_REPUTATION_BY_FACTION); + stmt->setUInt32(0, _player->GetGUIDLow()); + stmt->setUInt16(1, uint16(itr->second.ID)); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_REPUTATION_BY_FACTION); + stmt->setUInt32(0, _player->GetGUIDLow()); + stmt->setUInt16(1, uint16(itr->second.ID)); + stmt->setInt32(2, itr->second.Standing); + stmt->setUInt16(3, uint16(itr->second.Flags)); + trans->Append(stmt); + itr->second.needSave = false; } } diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index fba6b460ec9..012910210a5 100755 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -260,7 +260,7 @@ void ScriptMgr::Initialize() void ScriptMgr::Unload() { #define SCR_CLEAR(T) \ - FOR_SCRIPTS(T, itr, end) \ + for (SCR_REG_ITR(T) itr = SCR_REG_LST(T).begin(); itr != SCR_REG_LST(T).end(); ++itr) \ delete itr->second; \ SCR_REG_LST(T).clear(); diff --git a/src/server/game/Scripting/ScriptSystem.cpp b/src/server/game/Scripting/ScriptSystem.cpp index ecb82a80a8d..66f5a4089dc 100755 --- a/src/server/game/Scripting/ScriptSystem.cpp +++ b/src/server/game/Scripting/ScriptSystem.cpp @@ -109,11 +109,11 @@ void SystemMgr::LoadScriptTextsCustom() Field* pFields = result->Fetch(); StringTextData temp; - int32 iId = pFields[0].GetInt32(); + int32 iId = pFields[0].GetInt32(); temp.uiSoundId = pFields[1].GetUInt32(); - temp.uiType = pFields[2].GetUInt32(); - temp.uiLanguage = pFields[3].GetUInt32(); - temp.uiEmote = pFields[4].GetUInt32(); + temp.uiType = pFields[2].GetUInt8(); + temp.uiLanguage = pFields[3].GetUInt8(); + temp.uiEmote = pFields[4].GetUInt16(); if (iId >= 0) { diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 2c6098fb23f..cf9ec7dadc4 100755 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -812,13 +812,11 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) clientSeed); // Get the account information from the realmd database - std::string safe_account = account; // Duplicate, else will screw the SHA hash verification below - LoginDatabase.EscapeString (safe_account); - // No SQL injection, username escaped. + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME); - // 0 1 2 3 4 5 6 7 8 9 10 - QueryResult result = LoginDatabase.PQuery ("SELECT id, sessionkey, last_ip, locked, v, s, expansion, mutetime, locale, recruiter, os FROM account " - "WHERE username = '%s'", safe_account.c_str()); + stmt->setString(0, account); + + PreparedQueryResult result = LoginDatabase.Query(stmt); // Stop if the account is not found if (!result) @@ -899,29 +897,28 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) std::string os = fields[10].GetString(); // Checks gmlevel per Realm - result = - LoginDatabase.PQuery ("SELECT " - "RealmID, " //0 - "gmlevel " //1 - "FROM account_access " - "WHERE id = '%d'" - " AND (RealmID = '%d'" - " OR RealmID = '-1')", - id, realmID); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_GMLEVEL_BY_REALMID); + + stmt->setUInt32(0, id); + stmt->setInt32(1, int32(realmID)); + + result = LoginDatabase.Query(stmt); + if (!result) security = 0; else { fields = result->Fetch(); - security = fields[1].GetInt32(); + security = fields[0].GetUInt8(); } // Re-check account ban (same check as in realmd) - QueryResult banresult = - LoginDatabase.PQuery ("SELECT 1 FROM account_banned WHERE id = %u AND active = 1 " - "UNION " - "SELECT 1 FROM ip_banned WHERE ip = '%s'", - id, GetRemoteAddress().c_str()); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BANS); + + stmt->setUInt32(0, id); + stmt->setString(1, GetRemoteAddress()); + + PreparedQueryResult banresult = LoginDatabase.Query(stmt); if (banresult) // if account banned { @@ -976,7 +973,11 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) address.c_str()); // Check if this user is by any chance a recruiter - result = LoginDatabase.PQuery ("SELECT 1 FROM account WHERE recruiter = %u", id); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_RECRUITER); + + stmt->setUInt32(0, id); + + result = LoginDatabase.Query(stmt); bool isRecruiter = false; if (result) @@ -984,7 +985,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) // Update the last_ip in the database - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LAST_IP); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LAST_IP); stmt->setString(0, address); stmt->setString(1, account); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 5e44c777cbd..f7635f3fab5 100755 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -4948,18 +4948,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool } } break; - case SPELLFAMILY_HUNTER: - switch (GetId()) - { - case 34477: // Misdirection - if (aurApp->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) - target->SetReducedThreatPercent(0, 0); - break; - case 35079: // Misdirection proc - target->SetReducedThreatPercent(0, 0); - break; - } - break; case SPELLFAMILY_DEATHKNIGHT: // Summon Gargoyle (Dismiss Gargoyle at remove) if (GetId() == 61777) @@ -6460,7 +6448,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const caster->CalcHealAbsorb(target, GetSpellInfo(), heal, absorb); int32 gain = caster->DealHeal(target, heal); - SpellPeriodicAuraLogInfo pInfo(this, damage, damage - gain, absorb, 0, 0.0f, crit); + SpellPeriodicAuraLogInfo pInfo(this, heal, heal - gain, absorb, 0, 0.0f, crit); target->SendPeriodicAuraLog(&pInfo); target->getHostileRefManager().threatAssist(caster, float(gain) * 0.5f, GetSpellInfo()); diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 32473a93a26..a22b9e73fc6 100755 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -719,7 +719,8 @@ int32 Aura::CalcMaxDuration(Unit* caster) const if (IsPassive() && !m_spellInfo->DurationEntry) maxDuration = -1; - if (!IsPermanent() && modOwner) + // IsPermanent() checks max duration (which we are supposed to calculate here) + if (maxDuration != -1 && modOwner) modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, maxDuration); return maxDuration; } @@ -2357,13 +2358,14 @@ void UnitAura::FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster) switch (GetSpellInfo()->Effects[effIndex].Effect) { case SPELL_EFFECT_APPLY_AREA_AURA_PARTY: - targetList.push_back(GetUnitOwner()); - GetUnitOwner()->GetPartyMemberInDist(targetList, radius); - break; case SPELL_EFFECT_APPLY_AREA_AURA_RAID: + { targetList.push_back(GetUnitOwner()); - GetUnitOwner()->GetRaidMember(targetList, radius); + Trinity::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID); + Trinity::UnitListSearcher<Trinity::AnyGroupedUnitInObjectRangeCheck> searcher(GetUnitOwner(), targetList, u_check); + GetUnitOwner()->VisitNearbyObject(radius, searcher); break; + } case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: { targetList.push_back(GetUnitOwner()); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index ecd20a03665..a9e1b964b1c 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -3080,7 +3080,8 @@ void Spell::cancel() *m_selfContainer = NULL; m_caster->RemoveDynObject(m_spellInfo->Id); - m_caster->RemoveGameObject(m_spellInfo->Id, true); + if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet + m_caster->RemoveGameObject(m_spellInfo->Id, true); //set state back so finish will be processed m_spellState = oldState; @@ -4983,7 +4984,7 @@ SpellCastResult Spell::CheckCast(bool strict) break; } - if (!hasNonDispelEffect && !hasDispellableAura && m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL)) + if (!hasNonDispelEffect && !hasDispellableAura && m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL) && m_spellInfo->CalcPowerCost(m_caster, SPELL_SCHOOL_MASK_NONE)) return SPELL_FAILED_NOTHING_TO_DISPEL; for (int i = 0; i < MAX_SPELL_EFFECTS; i++) @@ -6665,7 +6666,7 @@ bool SpellEvent::Execute(uint64 e_time, uint32 p_time) // no, we aren't, do the typical update // check, if we have channeled spell on our hands /* - if (IsChanneledSpell(m_Spell->m_spellInfo)) + if (m_Spell->m_spellInfo->IsChanneled()) { // evented channeled spell is processed separately, casted once after delay, and not destroyed till finish // check, if we have casting anything else except this channeled spell and autorepeat diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index c1b267d9fac..7bfb71d83d4 100755 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1193,7 +1193,7 @@ void SpellMgr::LoadSpellRanks() if (lastSpell == -1) lastSpell = currentSpell; uint32 spell_id = fields[1].GetUInt32(); - uint32 rank = fields[2].GetUInt32(); + uint32 rank = fields[2].GetUInt8(); // don't drop the row if we're moving to the next rank if (currentSpell == lastSpell) diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp index 96f4438544f..e4b8ea2e034 100755 --- a/src/server/game/Tickets/TicketMgr.cpp +++ b/src/server/game/Tickets/TicketMgr.cpp @@ -198,6 +198,12 @@ void GmTicket::TeleportTo(Player* player) const // Ticket manager TicketMgr::TicketMgr() : _status(true), _lastTicketId(0), _lastSurveyId(0), _openTicketCount(0), _lastChange(time(NULL)) { } +TicketMgr::~TicketMgr() +{ + for (GmTicketList::const_iterator itr = _ticketList.begin(); itr != _ticketList.end(); ++itr) + delete itr->second; +} + void TicketMgr::Initialize() { SetStatus(sWorld->getBoolConfig(CONFIG_ALLOW_TICKETS)); } void TicketMgr::ResetTickets() @@ -217,10 +223,8 @@ void TicketMgr::LoadTickets() { uint32 oldMSTime = getMSTime(); - if (!_ticketList.empty()) - for (GmTicketList::const_iterator itr = _ticketList.begin(); itr != _ticketList.end(); ++itr) - if (itr->second) - delete itr->second; + for (GmTicketList::const_iterator itr = _ticketList.begin(); itr != _ticketList.end(); ++itr) + delete itr->second; _ticketList.clear(); _lastTicketId = 0; @@ -301,6 +305,7 @@ void TicketMgr::RemoveTicket(uint32 ticketId) { ticket->DeleteFromDB(); _ticketList.erase(ticketId); + delete ticket; } } diff --git a/src/server/game/Tickets/TicketMgr.h b/src/server/game/Tickets/TicketMgr.h index cb0a1bab22b..5695880542c 100755 --- a/src/server/game/Tickets/TicketMgr.h +++ b/src/server/game/Tickets/TicketMgr.h @@ -166,6 +166,7 @@ class TicketMgr private: TicketMgr(); + ~TicketMgr(); public: void LoadTickets(); diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp index 900fcf7392a..8d5d16d22b9 100644 --- a/src/server/game/Tools/PlayerDump.cpp +++ b/src/server/game/Tools/PlayerDump.cpp @@ -406,7 +406,10 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s bool incHighest = true; if (guid != 0 && guid < sObjectMgr->_hiCharGuid) { - result = CharacterDatabase.PQuery("SELECT 1 FROM characters WHERE guid = '%d'", guid); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_GUID); + stmt->setUInt32(0, guid); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (result) guid = sObjectMgr->_hiCharGuid; // use first free if exists else incHighest = false; @@ -420,8 +423,10 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s if (ObjectMgr::CheckPlayerName(name, true) == CHAR_NAME_SUCCESS) { - CharacterDatabase.EscapeString(name); // for safe, we use name only for sql quearies anyway - result = CharacterDatabase.PQuery("SELECT 1 FROM characters WHERE name = '%s'", name.c_str()); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_NAME); + stmt->setString(0, name); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (result) name = ""; // use the one from the dump } @@ -524,9 +529,11 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s { // check if the original name already exists name = getnth(line, 3); - CharacterDatabase.EscapeString(name); - result = CharacterDatabase.PQuery("SELECT 1 FROM characters WHERE name = '%s'", name.c_str()); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_NAME); + stmt->setString(0, name); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (result) if (!changenth(line, 37, "1")) // characters.at_login set to "rename on login" ROLLBACK(DUMP_FILE_BROKEN); diff --git a/src/server/game/Warden/Warden.cpp b/src/server/game/Warden/Warden.cpp index f2fe3c4ad67..fa30adde72a 100644 --- a/src/server/game/Warden/Warden.cpp +++ b/src/server/game/Warden/Warden.cpp @@ -193,9 +193,9 @@ std::string Warden::Penalty(WardenCheck* check /*= NULL*/) break; } default: - return "Undefined"; break; } + return "Undefined"; } void WorldSession::HandleWardenDataOpcode(WorldPacket& recvData) diff --git a/src/server/game/Weather/WeatherMgr.cpp b/src/server/game/Weather/WeatherMgr.cpp index 731aba8d197..41241583ea1 100755 --- a/src/server/game/Weather/WeatherMgr.cpp +++ b/src/server/game/Weather/WeatherMgr.cpp @@ -24,14 +24,14 @@ #include "Weather.h" #include "Log.h" #include "ObjectMgr.h" -#include <ace/Refcounted_Auto_Ptr.h> +#include "AutoPtr.h" namespace WeatherMgr { namespace { - typedef UNORDERED_MAP<uint32, ACE_Refcounted_Auto_Ptr<Weather, ACE_Null_Mutex> > WeatherMap; + typedef UNORDERED_MAP<uint32, Trinity::AutoPtr<Weather, ACE_Null_Mutex> > WeatherMap; typedef UNORDERED_MAP<uint32, WeatherData> WeatherZoneMap; WeatherMap m_weathers; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 4c02d1058b2..cb365eefbd6 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -78,7 +78,7 @@ #include "Warden.h" #include "CalendarMgr.h" -volatile bool World::m_stopEvent = false; +ACE_Atomic_Op<ACE_Thread_Mutex, bool> World::m_stopEvent = false; uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE; volatile uint32 World::m_worldLoopCounter = 0; @@ -1283,6 +1283,9 @@ void World::SetInitialWorldSettings() sLog->outString("Loading SpellInfo store..."); sSpellMgr->LoadSpellInfoStore(); + sLog->outString("Loading SkillLineAbilityMultiMap Data..."); + sSpellMgr->LoadSkillLineAbilityMap(); + sLog->outString("Loading spell custom attributes..."); sSpellMgr->LoadSpellCustomAttr(); @@ -1295,9 +1298,6 @@ void World::SetInitialWorldSettings() sLog->outString("Loading Instance Template..."); sObjectMgr->LoadInstanceTemplate(); - sLog->outString("Loading SkillLineAbilityMultiMap Data..."); - sSpellMgr->LoadSkillLineAbilityMap(); - // Must be called before `creature_respawn`/`gameobject_respawn` tables sLog->outString("Loading instances..."); sInstanceSaveMgr->LoadInstances(); @@ -1589,7 +1589,7 @@ void World::SetInitialWorldSettings() sSmartWaypointMgr->LoadFromDB(); sLog->outString("Loading Creature Formations..."); - FormationMgr::LoadCreatureFormations(); + sFormationMgr->LoadCreatureFormations(); sLog->outString("Loading World States..."); // must be loaded before battleground, outdoor PvP and conditions LoadWorldStates(); @@ -1625,6 +1625,9 @@ void World::SetInitialWorldSettings() sLog->outString("Loading Autobroadcasts..."); LoadAutobroadcasts(); + sLog->outString("Loading Ip2nation..."); + LoadIp2nation(); + ///- Load and initialize scripts sObjectMgr->LoadQuestStartScripts(); // must be after load Creature/Gameobject(Template/Data) and QuestTemplate sObjectMgr->LoadQuestEndScripts(); // must be after load Creature/Gameobject(Template/Data) and QuestTemplate @@ -1881,6 +1884,23 @@ void World::LoadAutobroadcasts() sLog->outString(); } +void World::LoadIp2nation() +{ + uint32 oldMSTime = getMSTime(); + + QueryResult result = WorldDatabase.Query("SELECT count(c.code) FROM ip2nationCountries c, ip2nation i WHERE c.code = i.country"); + uint32 count = 0; + + if (result) + { + Field* fields = result->Fetch(); + count = fields[0].GetUInt32(); + } + + sLog->outString(">> Loaded %u ip2nation definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); + sLog->outString(); +} + /// Update the World ! void World::Update(uint32 diff) { @@ -2314,7 +2334,7 @@ BanReturn World::BanAccount(BanMode mode, std::string nameOrIP, std::string dura do { Field* fieldsAccount = resultAccounts->Fetch(); - uint32 account = fieldsAccount->GetUInt32(); + uint32 account = fieldsAccount[0].GetUInt32(); if (mode != BAN_IP) { @@ -2450,7 +2470,7 @@ void World::_UpdateGameTime() m_gameTime = thisTime; ///- if there is a shutdown timer - if (!m_stopEvent && m_ShutdownTimer > 0 && elapsed > 0) + if (!IsStopped() && m_ShutdownTimer > 0 && elapsed > 0) { ///- ... and it is overdue, stop the world (set m_stopEvent) if (m_ShutdownTimer <= elapsed) @@ -2474,7 +2494,7 @@ void World::_UpdateGameTime() void World::ShutdownServ(uint32 time, uint32 options, uint8 exitcode) { // ignore if server shutdown at next tick - if (m_stopEvent) + if (IsStopped()) return; m_ShutdownMask = options; @@ -2526,7 +2546,7 @@ void World::ShutdownMsg(bool show, Player* player) void World::ShutdownCancel() { // nothing cancel or too later - if (!m_ShutdownTimer || m_stopEvent) + if (!m_ShutdownTimer || m_stopEvent.value()) return; ServerMessageType msgid = (m_ShutdownMask & SHUTDOWN_MASK_RESTART) ? SERVER_MSG_RESTART_CANCELLED : SERVER_MSG_SHUTDOWN_CANCELLED; @@ -2652,7 +2672,7 @@ void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount) uint32 accountId = fields[0].GetUInt32(); uint32 charCount = fields[1].GetUInt32(); - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM); stmt->setUInt32(0, accountId); stmt->setUInt32(1, realmID); LoginDatabase.Execute(stmt); @@ -2750,9 +2770,12 @@ void World::ResetDailyQuests() void World::LoadDBAllowedSecurityLevel() { - QueryResult result = LoginDatabase.PQuery("SELECT allowedSecurityLevel from realmlist WHERE id = '%d'", realmID); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST_SECURITY_LEVEL); + stmt->setInt32(0, int32(realmID)); + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (result) - SetPlayerSecurityLimit(AccountTypes(result->Fetch()->GetUInt16())); + SetPlayerSecurityLimit(AccountTypes(result->Fetch()->GetUInt8())); } void World::SetPlayerSecurityLimit(AccountTypes _sec) diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index be4c41214ec..1247504678a 100755 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -26,6 +26,7 @@ #include "Common.h" #include "Timer.h" #include <ace/Singleton.h> +#include <ace/Atomic_Op.h> #include "SharedDefines.h" #include "QueryResult.h" #include "Callback.h" @@ -650,7 +651,7 @@ class World void ShutdownMsg(bool show = false, Player* player = NULL); static uint8 GetExitCode() { return m_ExitCode; } static void StopNow(uint8 exitcode) { m_stopEvent = true; m_ExitCode = exitcode; } - static bool IsStopped() { return m_stopEvent; } + static bool IsStopped() { return m_stopEvent.value(); } void Update(uint32 diff); @@ -740,6 +741,8 @@ class World void LoadAutobroadcasts(); + void LoadIp2nation(); + void UpdateAreaDependentAuras(); void ProcessStartEvent(); @@ -768,7 +771,7 @@ class World void ResetWeeklyQuests(); void ResetRandomBG(); private: - static volatile bool m_stopEvent; + static ACE_Atomic_Op<ACE_Thread_Mutex, bool> m_stopEvent; static uint8 m_ExitCode; uint32 m_ShutdownTimer; uint32 m_ShutdownMask; diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp index 86818e2c931..b52102479b5 100644 --- a/src/server/scripts/Commands/cs_account.cpp +++ b/src/server/scripts/Commands/cs_account.cpp @@ -194,8 +194,11 @@ public: static bool HandleAccountOnlineListCommand(ChatHandler* handler, char const* /*args*/) { ///- Get the list of accounts ID logged to the realm - QueryResult resultDB = CharacterDatabase.Query("SELECT name, account, map, zone FROM characters WHERE online > 0"); - if (!resultDB) + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_ONLINE); + + PreparedQueryResult result = CharacterDatabase.Query(stmt); + + if (!result) { handler->SendSysMessage(LANG_ACCOUNT_LIST_EMPTY); return true; @@ -209,31 +212,28 @@ public: ///- Cycle through accounts do { - Field* fieldsDB = resultDB->Fetch(); + Field* fieldsDB = result->Fetch(); std::string name = fieldsDB[0].GetString(); uint32 account = fieldsDB[1].GetUInt32(); ///- Get the username, last IP and GM level of each account // No SQL injection. account is uint32. - QueryResult resultLogin = - LoginDatabase.PQuery("SELECT a.username, a.last_ip, aa.gmlevel, a.expansion " - "FROM account a " - "LEFT JOIN account_access aa " - "ON (a.id = aa.id) " - "WHERE a.id = '%u'", account); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO); + stmt->setUInt32(0, account); + PreparedQueryResult resultLogin = LoginDatabase.Query(stmt); if (resultLogin) { Field* fieldsLogin = resultLogin->Fetch(); handler->PSendSysMessage(LANG_ACCOUNT_LIST_LINE, fieldsLogin[0].GetCString(), name.c_str(), fieldsLogin[1].GetCString(), - fieldsDB[2].GetUInt16(), fieldsDB[3].GetUInt16(), fieldsLogin[3].GetUInt32(), - fieldsLogin[2].GetUInt32()); + fieldsDB[2].GetUInt16(), fieldsDB[3].GetUInt16(), fieldsLogin[3].GetUInt8(), + fieldsLogin[2].GetUInt8()); } else handler->PSendSysMessage(LANG_ACCOUNT_LIST_ERROR, name.c_str()); - } while (resultDB->NextRow()); + } while (result->NextRow()); handler->SendSysMessage(LANG_ACCOUNT_LIST_BAR); return true; @@ -469,7 +469,13 @@ public: // Check and abort if the target gm has a higher rank on one of the realms and the new realm is -1 if (gmRealmID == -1 && !AccountMgr::IsConsoleAccount(playerSecurity)) { - QueryResult result = LoginDatabase.PQuery("SELECT * FROM account_access WHERE id = '%u' AND gmlevel > '%d'", targetAccountId, gm); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_ACCESS_GMLEVEL_TEST); + + stmt->setUInt32(0, targetAccountId); + stmt->setUInt8(1, uint8(gm)); + + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (result) { handler->SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp index 9b9d1cfd146..d449b3617f7 100644 --- a/src/server/scripts/Commands/cs_gm.cpp +++ b/src/server/scripts/Commands/cs_gm.cpp @@ -156,7 +156,11 @@ public: static bool HandleGMListFullCommand(ChatHandler* handler, char const* /*args*/) { ///- Get the accounts with GM Level >0 - QueryResult result = LoginDatabase.PQuery("SELECT a.username, aa.gmlevel FROM account a, account_access aa WHERE a.id=aa.id AND aa.gmlevel >= %u AND (aa.realmid = -1 OR aa.realmid = %u)", SEC_MODERATOR, realmID); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_GM_ACCOUNTS); + stmt->setUInt8(0, uint8(SEC_MODERATOR)); + stmt->setInt32(1, int32(realmID)); + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (result) { handler->SendSysMessage(LANG_GMLIST); diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index 74b8272201b..232aad9f21c 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -535,11 +535,17 @@ public: uint32 count = 0; Player* player = handler->GetSession()->GetPlayer(); - QueryResult result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, " - "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ " - "FROM gameobject WHERE map='%u' AND (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) <= '%f' ORDER BY order_", - player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), - player->GetMapId(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), distance * distance); + + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_GAMEOBJECT_NEAREST); + stmt->setFloat(0, player->GetPositionX()); + stmt->setFloat(1, player->GetPositionY()); + stmt->setFloat(2, player->GetPositionZ()); + stmt->setUInt32(3, player->GetMapId()); + stmt->setFloat(4, player->GetPositionX()); + stmt->setFloat(5, player->GetPositionY()); + stmt->setFloat(6, player->GetPositionZ()); + stmt->setFloat(7, distance * distance); + PreparedQueryResult result = WorldDatabase.Query(stmt); if (result) { diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 90615a3bd88..a9959c60201 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -694,7 +694,7 @@ public: { PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_TRANSPORT_EMOTE); - stmt->setInt16(0, int16(emote)); + stmt->setInt32(0, int32(emote)); stmt->setInt32(1, target->GetTransport()->GetEntry()); stmt->setInt32(2, target->GetGUIDTransport()); @@ -1249,7 +1249,7 @@ public: group_member->leaderGUID = leaderGUID; group_member->groupAI = 0; - CreatureGroupMap[lowguid] = group_member; + sFormationMgr->CreatureGroupMap[lowguid] = group_member; creature->SearchFormation(); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_CREATURE_FORMATION); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 1520a944f6e..5f192ffceee 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -413,7 +413,11 @@ public: for (Tokens::const_iterator itr = entries.begin(); itr != entries.end(); ++itr) { uint32 entry = uint32(atoi(*itr)); - QueryResult result = WorldDatabase.PQuery("SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = %u", entry); + + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_TEMPLATE); + stmt->setUInt32(0, entry); + PreparedQueryResult result = WorldDatabase.Query(stmt); + if (!result) { handler->PSendSysMessage(LANG_COMMAND_CREATURETEMPLATE_NOTFOUND, entry); @@ -434,87 +438,87 @@ public: const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[0] = fields[0].GetUInt32(); const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[1] = fields[1].GetUInt32(); const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[2] = fields[2].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->KillCredit[0] = fields[3].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->KillCredit[1] = fields[4].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->Modelid1 = fields[5].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->Modelid2 = fields[6].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->Modelid3 = fields[7].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->Modelid4 = fields[8].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->Name = fields[9].GetString(); - const_cast<CreatureTemplate*>(cInfo)->SubName = fields[10].GetString(); - const_cast<CreatureTemplate*>(cInfo)->IconName = fields[11].GetString(); - const_cast<CreatureTemplate*>(cInfo)->GossipMenuId = fields[12].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->minlevel = fields[13].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->maxlevel = fields[14].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->expansion = fields[15].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->faction_A = fields[16].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->faction_H = fields[17].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->npcflag = fields[18].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->speed_walk = fields[19].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->speed_run = fields[20].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->scale = fields[21].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->rank = fields[22].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->mindmg = fields[23].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->maxdmg = fields[24].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->dmgschool = fields[25].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->attackpower = fields[26].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->dmg_multiplier = fields[27].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->baseattacktime = fields[28].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->rangeattacktime = fields[29].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->unit_class = fields[30].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->unit_flags = fields[31].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->dynamicflags = fields[32].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->family = fields[33].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->trainer_type = fields[34].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->trainer_spell = fields[35].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->trainer_class = fields[36].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->trainer_race = fields[37].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->minrangedmg = fields[38].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->maxrangedmg = fields[39].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->rangedattackpower = fields[40].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->type = fields[41].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->type_flags = fields[42].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->lootid = fields[43].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->pickpocketLootId = fields[44].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->SkinLootId = fields[45].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->KillCredit[0] = fields[3].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->KillCredit[1] = fields[4].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->Modelid1 = fields[5].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->Modelid2 = fields[6].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->Modelid3 = fields[7].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->Modelid4 = fields[8].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->Name = fields[9].GetString(); + const_cast<CreatureTemplate*>(cInfo)->SubName = fields[10].GetString(); + const_cast<CreatureTemplate*>(cInfo)->IconName = fields[11].GetString(); + const_cast<CreatureTemplate*>(cInfo)->GossipMenuId = fields[12].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->minlevel = fields[13].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->maxlevel = fields[14].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->expansion = fields[15].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->faction_A = fields[16].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->faction_H = fields[17].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->npcflag = fields[18].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->speed_walk = fields[19].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->speed_run = fields[20].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->scale = fields[21].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->rank = fields[22].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->mindmg = fields[23].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->maxdmg = fields[24].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->dmgschool = fields[25].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->attackpower = fields[26].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->dmg_multiplier = fields[27].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->baseattacktime = fields[28].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->rangeattacktime = fields[29].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->unit_class = fields[30].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->unit_flags = fields[31].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->dynamicflags = fields[32].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->family = fields[33].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->trainer_type = fields[34].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->trainer_spell = fields[35].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->trainer_class = fields[36].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->trainer_race = fields[37].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->minrangedmg = fields[38].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->maxrangedmg = fields[39].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->rangedattackpower = fields[40].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->type = fields[41].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->type_flags = fields[42].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->lootid = fields[43].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->pickpocketLootId = fields[44].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->SkinLootId = fields[45].GetUInt32(); for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) { const_cast<CreatureTemplate*>(cInfo)->resistance[i] = fields[46 + i -1].GetUInt32(); } - const_cast<CreatureTemplate*>(cInfo)->spells[0] = fields[52].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[1] = fields[53].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[2] = fields[54].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[3] = fields[55].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[4] = fields[56].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[5] = fields[57].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[6] = fields[58].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[7] = fields[59].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->PetSpellDataId = fields[60].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->VehicleId = fields[61].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->mingold = fields[62].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->maxgold = fields[63].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->AIName = fields[64].GetString(); - const_cast<CreatureTemplate*>(cInfo)->MovementType = fields[65].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->InhabitType = fields[66].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->HoverHeight = fields[67].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->ModHealth = fields[68].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->ModMana = fields[69].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->ModArmor = fields[70].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->RacialLeader = fields[71].GetBool(); - const_cast<CreatureTemplate*>(cInfo)->questItems[0] = fields[72].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->questItems[1] = fields[73].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->questItems[2] = fields[74].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->questItems[3] = fields[75].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->questItems[4] = fields[76].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->questItems[5] = fields[77].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->movementId = fields[78].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->RegenHealth = fields[79].GetBool(); - const_cast<CreatureTemplate*>(cInfo)->equipmentId = fields[80].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->spells[0] = fields[52].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->spells[1] = fields[53].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->spells[2] = fields[54].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->spells[3] = fields[55].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->spells[4] = fields[56].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->spells[5] = fields[57].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->spells[6] = fields[58].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->spells[7] = fields[59].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->PetSpellDataId = fields[60].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->VehicleId = fields[61].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->mingold = fields[62].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->maxgold = fields[63].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->AIName = fields[64].GetString(); + const_cast<CreatureTemplate*>(cInfo)->MovementType = fields[65].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->InhabitType = fields[66].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->HoverHeight = fields[67].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->ModHealth = fields[68].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->ModMana = fields[69].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->ModArmor = fields[70].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->RacialLeader = fields[71].GetBool(); + const_cast<CreatureTemplate*>(cInfo)->questItems[0] = fields[72].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->questItems[1] = fields[73].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->questItems[2] = fields[74].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->questItems[3] = fields[75].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->questItems[4] = fields[76].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->questItems[5] = fields[77].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->movementId = fields[78].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->RegenHealth = fields[79].GetBool(); + const_cast<CreatureTemplate*>(cInfo)->equipmentId = fields[80].GetUInt32(); const_cast<CreatureTemplate*>(cInfo)->MechanicImmuneMask = fields[81].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->flags_extra = fields[82].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->ScriptID = sObjectMgr->GetScriptId(fields[83].GetCString()); + const_cast<CreatureTemplate*>(cInfo)->flags_extra = fields[82].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->ScriptID = sObjectMgr->GetScriptId(fields[83].GetCString()); sObjectMgr->CheckCreatureTemplate(cInfo); } diff --git a/src/server/scripts/Commands/cs_tele.cpp b/src/server/scripts/Commands/cs_tele.cpp index 5054bd83f32..89646c23ea0 100644 --- a/src/server/scripts/Commands/cs_tele.cpp +++ b/src/server/scripts/Commands/cs_tele.cpp @@ -131,7 +131,10 @@ public: target->TeleportTo(target->m_homebindMapId, target->m_homebindX, target->m_homebindY, target->m_homebindZ, target->GetOrientation()); else { - QueryResult resultDB = CharacterDatabase.PQuery("SELECT mapId, zoneId, posX, posY, posZ FROM character_homebind WHERE guid = %u", target_guid); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_HOMEBIND); + stmt->setUInt32(0, target_guid); + PreparedQueryResult resultDB = CharacterDatabase.Query(stmt); + if (resultDB) { Field* fieldsDB = resultDB->Fetch(); diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index eb59007b40b..f29dd8a5069 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -91,7 +91,10 @@ public: pathid = target->GetWaypointPath(); else { - QueryResult result = WorldDatabase.Query("SELECT MAX(id) FROM waypoint_data"); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_MAX_ID); + + PreparedQueryResult result = WorldDatabase.Query(stmt); + uint32 maxpathid = result->Fetch()->GetInt32(); pathid = maxpathid+1; handler->PSendSysMessage("%s%s|r", "|cff00ff00", "New path started."); @@ -109,7 +112,9 @@ public: return true; } - QueryResult result = WorldDatabase.PQuery("SELECT MAX(point) FROM waypoint_data WHERE id = '%u'", pathid); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_MAX_POINT); + stmt->setUInt32(0, pathid); + PreparedQueryResult result = WorldDatabase.Query(stmt); if (result) point = (*result)[0].GetUInt32(); @@ -117,7 +122,7 @@ public: Player* player = handler->GetSession()->GetPlayer(); //Map* map = player->GetMap(); - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_WAYPOINT_DATA); + stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_WAYPOINT_DATA); stmt->setUInt32(0, pathid); stmt->setUInt32(1, point + 1); @@ -173,9 +178,12 @@ public: } guidLow = target->GetDBTableGUIDLow(); - QueryResult result = WorldDatabase.PQuery("SELECT guid FROM creature_addon WHERE guid = '%u'", guidLow); - PreparedStatement* stmt; + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_ADDON_BY_GUID); + + stmt->setUInt32(0, guidLow); + + PreparedQueryResult result = WorldDatabase.Query(stmt); if (result) { @@ -290,7 +298,9 @@ public: if (id) { - QueryResult result = WorldDatabase.PQuery("SELECT id FROM waypoint_scripts WHERE guid = %u", id); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID); + stmt->setUInt32(0, id); + PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { @@ -307,10 +317,13 @@ public: } else { - QueryResult result = WorldDatabase.Query("SELECT MAX(guid) FROM waypoint_scripts"); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPTS_MAX_ID); + + PreparedQueryResult result = WorldDatabase.Query(stmt); + id = result->Fetch()->GetUInt32(); - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_WAYPOINT_SCRIPT); + stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_WAYPOINT_SCRIPT); stmt->setUInt32(0, id + 1); @@ -336,7 +349,9 @@ public: float a8, a9, a10, a11; char const* a7; - QueryResult result = WorldDatabase.PQuery("SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = %u", id); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID); + stmt->setUInt32(0, id); + PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { @@ -369,7 +384,11 @@ public: { id = atoi(arg_id); - QueryResult result = WorldDatabase.PQuery("SELECT guid FROM waypoint_scripts WHERE guid = %u", id); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID); + + stmt->setUInt32(0, id); + + PreparedQueryResult result = WorldDatabase.Query(stmt); if (result) { @@ -447,7 +466,9 @@ public: } else { - QueryResult result = WorldDatabase.PQuery("SELECT id FROM waypoint_scripts WHERE guid='%u'", id); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID); + stmt->setUInt32(0, id); + PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { @@ -567,7 +588,9 @@ public: // User did select a visual waypoint? // Check the creature - QueryResult result = WorldDatabase.PQuery("SELECT id, point FROM waypoint_data WHERE wpguid = %u", wpGuid); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_BY_WPGUID); + stmt->setUInt32(0, wpGuid); + PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { @@ -578,9 +601,17 @@ public: // Here we search for all waypoints that only differ in one from 1 thousand // (0.001) - There is no other way to compare C++ floats with mySQL floats // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html - const char* maxDIFF = "0.01"; - result = WorldDatabase.PQuery("SELECT id, point FROM waypoint_data WHERE (abs(position_x - %f) <= %s) and (abs(position_y - %f) <= %s) and (abs(position_z - %f) <= %s)", - target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF); + std::string maxDiff = "0.01"; + + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_BY_POS); + stmt->setFloat(0, target->GetPositionX()); + stmt->setString(1, maxDiff); + stmt->setFloat(2, target->GetPositionY()); + stmt->setString(3, maxDiff); + stmt->setFloat(4, target->GetPositionZ()); + stmt->setString(5, maxDiff); + PreparedQueryResult result = WorldDatabase.Query(stmt); + if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid); @@ -765,7 +796,6 @@ public: } std::string show = show_str; - uint32 Maxpoint; //handler->PSendSysMessage("wpshow - show: %s", show); @@ -780,7 +810,11 @@ public: return false; } - QueryResult result = WorldDatabase.PQuery("SELECT id, point, delay, move_flag, action, action_chance FROM waypoint_data WHERE wpguid = %u", target->GetGUIDLow()); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_ALL_BY_WPGUID); + + stmt->setUInt32(0, target->GetGUIDLow()); + + PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { @@ -812,7 +846,11 @@ public: if (show == "on") { - QueryResult result = WorldDatabase.PQuery("SELECT point, position_x, position_y, position_z FROM waypoint_data WHERE id = '%u'", pathid); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_POS_BY_ID); + + stmt->setUInt32(0, pathid); + + PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { @@ -824,7 +862,11 @@ public: handler->PSendSysMessage("|cff00ff00DEBUG: wp on, PathID: |cff00ffff%u|r", pathid); // Delete all visuals for this NPC - QueryResult result2 = WorldDatabase.PQuery("SELECT wpguid FROM waypoint_data WHERE id = '%u' and wpguid <> 0", pathid); + stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_WPGUID_BY_ID); + + stmt->setUInt32(0, pathid); + + PreparedQueryResult result2 = WorldDatabase.Query(stmt); if (result2) { @@ -921,7 +963,10 @@ public: { handler->PSendSysMessage("|cff00ff00DEBUG: wp first, GUID: %u|r", pathid); - QueryResult result = WorldDatabase.PQuery("SELECT position_x, position_y, position_z FROM waypoint_data WHERE point='1' AND id = '%u'", pathid); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_POS_FIRST_BY_ID); + stmt->setUInt32(0, pathid); + PreparedQueryResult result = WorldDatabase.Query(stmt); + if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUND, pathid); @@ -968,13 +1013,10 @@ public: { handler->PSendSysMessage("|cff00ff00DEBUG: wp last, PathID: |r|cff00ffff%u|r", pathid); - QueryResult result = WorldDatabase.PQuery("SELECT MAX(point) FROM waypoint_data WHERE id = '%u'", pathid); - if (result) - Maxpoint = (*result)[0].GetUInt32(); - else - Maxpoint = 0; + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_POS_LAST_BY_ID); + stmt->setUInt32(0, pathid); + PreparedQueryResult result = WorldDatabase.Query(stmt); - result = WorldDatabase.PQuery("SELECT position_x, position_y, position_z, orientation FROM waypoint_data WHERE point ='%u' AND id = '%u'", Maxpoint, pathid); if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, pathid); @@ -1018,7 +1060,10 @@ public: if (show == "off") { - QueryResult result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%u'", 1); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_BY_ID); + stmt->setUInt32(0, 1); + PreparedQueryResult result = WorldDatabase.Query(stmt); + if (!result) { handler->SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND); @@ -1051,7 +1096,7 @@ public: } while (result->NextRow()); // set "wpguid" column to "empty" - no visual waypoint spawned - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_ALL_WAYPOINT_DATA_WPGUID); + stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_ALL_WPGUID); WorldDatabase.Execute(stmt); //WorldDatabase.PExecute("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'"); diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp index 30a2da32ef3..8a64d45abcb 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp @@ -434,8 +434,9 @@ public: { phase = PHASE_DECEIVERS; - if (Creature* pKalecKJ = Unit::GetCreature((*me), instance->GetData64(DATA_KALECGOS_KJ))) - CAST_AI(boss_kalecgos_kj::boss_kalecgos_kjAI, pKalecKJ->AI())->ResetOrbs(); + if (instance) + if (Creature* pKalecKJ = Unit::GetCreature((*me), instance->GetData64(DATA_KALECGOS_KJ))) + CAST_AI(boss_kalecgos_kj::boss_kalecgos_kjAI, pKalecKJ->AI())->ResetOrbs(); deceiverDeathCount = 0; bSummonedDeceivers = false; bKiljaedenDeath = false; diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp index 12ef2075857..6a0ccc54773 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp @@ -36,7 +36,8 @@ enum Spells SPELL_VANISH = 55964, CREATURE_FLAME_SPHERE = 30106, H_CREATURE_FLAME_SPHERE_1 = 31686, - H_CREATURE_FLAME_SPHERE_2 = 31687 + H_CREATURE_FLAME_SPHERE_2 = 31687, + SPELL_HOVER_FALL = 60425 }; enum Misc { @@ -45,18 +46,17 @@ enum Misc DATA_SPHERE_DISTANCE = 15 }; #define DATA_SPHERE_ANGLE_OFFSET 0.7f -#define DATA_GROUND_POSITION_Z 11.4f +#define DATA_GROUND_POSITION_Z 11.30809f enum Yells { - SAY_AGGRO = -1619021, - SAY_SLAY_1 = -1619022, - SAY_SLAY_2 = -1619023, - SAY_DEATH = -1619024, - SAY_FEED_1 = -1619025, - SAY_FEED_2 = -1619026, - SAY_VANISH_1 = -1619027, - SAY_VANISH_2 = -1619028 + SAY_1 = 0, + SAY_WARNING = 1, + SAY_AGGRO = 2, + SAY_SLAY = 3, + SAY_DEATH = 4, + SAY_FEED = 5, + SAY_VANISH = 6, }; enum CombatPhase { @@ -82,8 +82,7 @@ public: boss_taldaramAI(Creature* creature) : ScriptedAI(creature) { instance = creature->GetInstanceScript(); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->SetDisableGravity(true); } uint32 uiBloodthirstTimer; @@ -118,7 +117,7 @@ public: { if (instance) instance->SetData(DATA_PRINCE_TALDARAM_EVENT, IN_PROGRESS); - DoScriptText(SAY_AGGRO, me); + Talk(SAY_AGGRO); } void UpdateAI(const uint32 diff) @@ -180,7 +179,8 @@ public: break; case VANISHED: if (Unit* pEmbraceTarget = GetEmbraceTarget()) - DoCast(pEmbraceTarget, SPELL_EMBRACE_OF_THE_VAMPYR); + DoCast(pEmbraceTarget, DUNGEON_MODE(SPELL_EMBRACE_OF_THE_VAMPYR, H_SPELL_EMBRACE_OF_THE_VAMPYR)); + Talk(SAY_FEED); me->GetMotionMaster()->Clear(); me->SetSpeed(MOVE_WALK, 1.0f, true); me->GetMotionMaster()->MoveChase(me->getVictim()); @@ -201,7 +201,8 @@ public: if (uiFlamesphereTimer <= diff) { - DoCast(me, SPELL_CONJURE_FLAME_SPHERE); + // because TARGET_UNIT_TARGET_ENEMY we need a target selected to cast + DoCastVictim(SPELL_CONJURE_FLAME_SPHERE); Phase = CASTING_FLAME_SPHERES; uiPhaseTimer = 3*IN_MILLISECONDS + diff; uiFlamesphereTimer = 15*IN_MILLISECONDS; @@ -224,7 +225,7 @@ public: //He only vanishes if there are 3 or more alive players if (target_list.size() > 2) { - DoScriptText(RAND(SAY_VANISH_1, SAY_VANISH_2), me); + Talk(SAY_VANISH); DoCast(me, SPELL_VANISH); Phase = JUST_VANISHED; uiPhaseTimer = 500; @@ -260,7 +261,7 @@ public: void JustDied(Unit* /*killer*/) { - DoScriptText(SAY_DEATH, me); + Talk(SAY_DEATH); if (instance) instance->SetData(DATA_PRINCE_TALDARAM_EVENT, DONE); @@ -278,7 +279,7 @@ public: uiPhaseTimer = 0; uiEmbraceTarget = 0; } - DoScriptText(RAND(SAY_SLAY_1, SAY_SLAY_2), me); + Talk(SAY_SLAY); } bool CheckSpheres() @@ -314,12 +315,13 @@ public: { if (!instance) return; - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->RemoveAurasDueToSpell(SPELL_BEAM_VISUAL); - me->SetUnitMovementFlags(MOVEMENTFLAG_WALKING); me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), DATA_GROUND_POSITION_Z, me->GetOrientation()); + DoCast(SPELL_HOVER_FALL); + me->SetDisableGravity(false); + me->GetMotionMaster()->MovePoint(0, me->GetHomePosition()); + Talk(SAY_WARNING); uint64 prison_GUID = instance->GetData64(DATA_PRINCE_TALDARAM_PLATFORM); instance->HandleGameObject(prison_GUID, true); } @@ -404,10 +406,12 @@ public: { case GO_SPHERE1: instance->SetData(DATA_SPHERE1_EVENT, IN_PROGRESS); + pPrinceTaldaram->AI()->Talk(SAY_1); break; case GO_SPHERE2: instance->SetData(DATA_SPHERE2_EVENT, IN_PROGRESS); + pPrinceTaldaram->AI()->Talk(SAY_1); break; } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp index 940191f68cb..37516e5e0df 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp @@ -278,6 +278,9 @@ public: if (!UpdateVictim()) return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + switch (m_uiStage) { case 0: diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp index c2901d16fa1..74b9c038482 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp @@ -619,8 +619,7 @@ public: { if (m_uiRangeCheckTimer < uiDiff) { - if (Unit* target = me->SelectNearestTarget(2.0f)) - if (target->GetTypeId() == TYPEID_PLAYER && target->isAlive()) + if (me->SelectNearestPlayer(2.0f)) { DoCastAOE(SPELL_UNLEASHED_DARK); me->GetMotionMaster()->MoveIdle(); @@ -661,8 +660,7 @@ public: { if (m_uiRangeCheckTimer < uiDiff) { - if (Unit* target = me->SelectNearestTarget(2.0f)) - if (target->GetTypeId() == TYPEID_PLAYER && target->isAlive()) + if (me->SelectNearestPlayer(2.0f)) { DoCastAOE(SPELL_UNLEASHED_LIGHT); me->GetMotionMaster()->MoveIdle(); diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp index 65d59efb9d6..c498c41a068 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp @@ -491,7 +491,7 @@ public: Creature* coilfangElite = me->SummonCreature(COILFANG_ELITE, CoilfangElitePos[pos][0], CoilfangElitePos[pos][1], CoilfangElitePos[pos][2], CoilfangElitePos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); if (coilfangElite) { - if (Unit* target = target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) coilfangElite->AI()->AttackStart(target); else if (me->getVictim()) coilfangElite->AI()->AttackStart(me->getVictim()); diff --git a/src/server/scripts/Outland/blades_edge_mountains.cpp b/src/server/scripts/Outland/blades_edge_mountains.cpp index e9537546c92..7a371170d7d 100644 --- a/src/server/scripts/Outland/blades_edge_mountains.cpp +++ b/src/server/scripts/Outland/blades_edge_mountains.cpp @@ -774,7 +774,7 @@ class npc_simon_bunny : public CreatureScript colorSequence.clear(); playableSequence.clear(); playerSequence.clear(); - me->SetFloatValue(OBJECT_FIELD_SCALE_X, large ? 2 : 1); + me->SetFloatValue(OBJECT_FIELD_SCALE_X, large ? 2.0f : 1.0f); std::list<WorldObject*> ClusterList; Trinity::AllWorldObjectsInRange objects(me, searchDistance); diff --git a/src/server/scripts/Outland/nagrand.cpp b/src/server/scripts/Outland/nagrand.cpp index d53bb4c24a4..a89d06072a7 100644 --- a/src/server/scripts/Outland/nagrand.cpp +++ b/src/server/scripts/Outland/nagrand.cpp @@ -444,18 +444,22 @@ public: void Reset() { + Say_Timer = 5000; ReleasedFromCage = false; } void UpdateAI(uint32 const diff) { - if (Say_Timer <= diff && ReleasedFromCage) + if (ReleasedFromCage) { - me->ForcedDespawn(); - ReleasedFromCage = false; + if (Say_Timer <= diff) + { + me->ForcedDespawn(); + ReleasedFromCage = false; + } + else + Say_Timer -= diff; } - else - Say_Timer -= diff; } void MovementInform(uint32 type, uint32 id) diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index e6db50f3f5a..ddbdf6db36e 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -642,9 +642,7 @@ public: void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - Unit* target = GetTarget(); - if (target->HasAura(DK_SPELL_UNHOLY_PRESENCE)) - target->RemoveAura(DK_SPELL_IMPROVED_UNHOLY_PRESENCE_TRIGGERED); + GetTarget()->RemoveAura(DK_SPELL_IMPROVED_UNHOLY_PRESENCE_TRIGGERED); } void Register() @@ -713,6 +711,7 @@ enum DeathCoil { SPELL_DEATH_COIL_DAMAGE = 47632, SPELL_DEATH_COIL_HEAL = 47633, + SPELL_SIGIL_VENGEFUL_HEART = 64962, }; class spell_dk_death_coil : public SpellScriptLoader @@ -743,7 +742,11 @@ class spell_dk_death_coil : public SpellScriptLoader caster->CastCustomSpell(target, SPELL_DEATH_COIL_HEAL, &bp, NULL, NULL, true); } else + { + if (AuraEffect const* auraEffect = caster->GetAuraEffect(SPELL_SIGIL_VENGEFUL_HEART, EFFECT_1)) + damage += auraEffect->GetBaseAmount(); caster->CastCustomSpell(target, SPELL_DEATH_COIL_DAMAGE, &damage, NULL, NULL, true); + } } } diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 855af75cd83..5d8e8f84e6a 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -560,6 +560,64 @@ class spell_hun_pet_carrion_feeder : public SpellScriptLoader } }; +// 34477 Misdirection +class spell_hun_misdirection : public SpellScriptLoader +{ + public: + spell_hun_misdirection() : SpellScriptLoader("spell_hun_misdirection") { } + + class spell_hun_misdirection_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_misdirection_AuraScript); + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + if (!GetDuration()) + caster->SetReducedThreatPercent(0, 0); + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_hun_misdirection_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_hun_misdirection_AuraScript(); + } +}; + +// 35079 Misdirection proc +class spell_hun_misdirection_proc : public SpellScriptLoader +{ + public: + spell_hun_misdirection_proc() : SpellScriptLoader("spell_hun_misdirection_proc") { } + + class spell_hun_misdirection_proc_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_misdirection_proc_AuraScript); + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetCaster()) + GetCaster()->SetReducedThreatPercent(0, 0); + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_hun_misdirection_proc_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_hun_misdirection_proc_AuraScript(); + } +}; + + void AddSC_hunter_spell_scripts() { new spell_hun_aspect_of_the_beast(); @@ -572,4 +630,6 @@ void AddSC_hunter_spell_scripts() new spell_hun_sniper_training(); new spell_hun_pet_heart_of_the_phoenix(); new spell_hun_pet_carrion_feeder(); + new spell_hun_misdirection(); + new spell_hun_misdirection_proc(); } diff --git a/src/server/shared/AutoPtr.h b/src/server/shared/AutoPtr.h new file mode 100644 index 00000000000..988c46cc5a2 --- /dev/null +++ b/src/server/shared/AutoPtr.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008-2012 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 _TRINITY_AUTO_PTR_H +#define _TRINITY_AUTO_PTR_H + +#include <ace/Bound_Ptr.h> + +namespace Trinity +{ + template <class Pointer, class Lock> + class AutoPtr : public ACE_Strong_Bound_Ptr<Pointer, Lock> + { + public: + AutoPtr() : ACE_Strong_Bound_Ptr<Pointer, Lock>() {} + + AutoPtr(Pointer* x) + { + ACE_Strong_Bound_Ptr<Pointer, Lock>::reset(x); + } + + operator bool() const + { + return ACE_Strong_Bound_Ptr<Pointer, Lock>::get() != NULL; + } + + bool operator !() const + { + return ACE_Strong_Bound_Ptr<Pointer, Lock>::get() == NULL; + } + + bool operator !=(Pointer* x) const + { + return ACE_Strong_Bound_Ptr<Pointer, Lock>::get() != x; + } + }; +}; + +#endif
\ No newline at end of file diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index b91972e5b0c..5fe31006bb2 100755 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -33,17 +33,11 @@ class PingOperation : public SQLOperation { - /// Operation for idle delaythreads + //! Operation for idle delaythreads bool Execute() { - if (m_conn->LockIfReady()) - { - m_conn->Ping(); - m_conn->Unlock(); - return true; - } - - return false; + m_conn->Ping(); + return true; } }; @@ -53,10 +47,10 @@ class DatabaseWorkerPool public: /* Activity state */ DatabaseWorkerPool() : - m_queue(new ACE_Activation_Queue(new ACE_Message_Queue<ACE_MT_SYNCH>)) + _queue(new ACE_Activation_Queue()) { - memset(m_connectionCount, 0, sizeof(m_connectionCount)); - m_connections.resize(IDX_SIZE); + memset(_connectionCount, 0, sizeof(_connectionCount)); + _connections.resize(IDX_SIZE); WPFatal (mysql_thread_safe(), "Used MySQL library isn't thread-safe."); } @@ -68,64 +62,72 @@ class DatabaseWorkerPool bool Open(const std::string& infoString, uint8 async_threads, uint8 synch_threads) { bool res = true; - m_connectionInfo = MySQLConnectionInfo(infoString); + _connectionInfo = MySQLConnectionInfo(infoString); - sLog->outSQLDriver("Opening databasepool '%s'. Async threads: %u, synch threads: %u", m_connectionInfo.database.c_str(), async_threads, synch_threads); + sLog->outSQLDriver("Opening DatabasePool '%s'. Asynchronous connections: %u, synchronous connections: %u.", + GetDatabaseName(), async_threads, synch_threads); - /// Open asynchronous connections (delayed operations) - m_connections[IDX_ASYNC].resize(async_threads); + //! Open asynchronous connections (delayed operations) + _connections[IDX_ASYNC].resize(async_threads); for (uint8 i = 0; i < async_threads; ++i) { - T* t = new T(m_queue, m_connectionInfo); + T* t = new T(_queue, _connectionInfo); res &= t->Open(); - m_connections[IDX_ASYNC][i] = t; - ++m_connectionCount[IDX_ASYNC]; + _connections[IDX_ASYNC][i] = t; + ++_connectionCount[IDX_ASYNC]; } - /// Open synchronous connections (direct, blocking operations) - m_connections[IDX_SYNCH].resize(synch_threads); + //! Open synchronous connections (direct, blocking operations) + _connections[IDX_SYNCH].resize(synch_threads); for (uint8 i = 0; i < synch_threads; ++i) { - T* t = new T(m_connectionInfo); + T* t = new T(_connectionInfo); res &= t->Open(); - m_connections[IDX_SYNCH][i] = t; - ++m_connectionCount[IDX_SYNCH]; + _connections[IDX_SYNCH][i] = t; + ++_connectionCount[IDX_SYNCH]; } - sLog->outSQLDriver("Databasepool opened successfully. %u total connections running.", (m_connectionCount[IDX_SYNCH] + m_connectionCount[IDX_ASYNC])); + if (res) + sLog->outSQLDriver("DatabasePool '%s' opened successfully. %u total connections running.", GetDatabaseName(), + (_connectionCount[IDX_SYNCH] + _connectionCount[IDX_ASYNC])); + else + sLog->outError("DatabasePool %s NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile " + "for specific errors.", GetDatabaseName()); return res; } void Close() { - sLog->outSQLDriver("Closing down databasepool '%s'.", m_connectionInfo.database.c_str()); + sLog->outSQLDriver("Closing down DatabasePool '%s'.", GetDatabaseName()); - /// Shuts down delaythreads for this connection pool by underlying deactivate() - m_queue->queue()->close(); + //! Shuts down delaythreads for this connection pool by underlying deactivate(). + //! The next dequeue attempt in the worker thread tasks will result in an error, + //! ultimately ending the worker thread task. + _queue->queue()->close(); - for (uint8 i = 0; i < m_connectionCount[IDX_ASYNC]; ++i) + for (uint8 i = 0; i < _connectionCount[IDX_ASYNC]; ++i) { - /// TODO: Better way. probably should flip a boolean and check it on low level code before doing anything on the mysql ctx - /// Now we just wait until m_queue gives the signal to the worker threads to stop - T* t = m_connections[IDX_ASYNC][i]; + T* t = _connections[IDX_ASYNC][i]; DatabaseWorker* worker = t->m_worker; - worker->wait(); + worker->wait(); //! Block until no more threads are running this task. delete worker; - t->Close(); + t->Close(); //! Closes the actualy MySQL connection. } - sLog->outSQLDriver("Asynchronous connections on databasepool '%s' terminated. Proceeding with synchronous connections.", m_connectionInfo.database.c_str()); + sLog->outSQLDriver("Asynchronous connections on DatabasePool '%s' terminated. Proceeding with synchronous connections.", + GetDatabaseName()); - /// Shut down the synchronous connections - for (uint8 i = 0; i < m_connectionCount[IDX_SYNCH]; ++i) - { - T* t = m_connections[IDX_SYNCH][i]; - //while (1) - // if (t->LockIfReady()) -- For some reason deadlocks us - t->Close(); - } + //! Shut down the synchronous connections + //! There's no need for locking the connection, because DatabaseWorkerPool<>::Close + //! should only be called after any other thread tasks in the core have exited, + //! meaning there can be no concurrent access at this point. + for (uint8 i = 0; i < _connectionCount[IDX_SYNCH]; ++i) + _connections[IDX_SYNCH][i]->Close(); - sLog->outSQLDriver("All connections on databasepool %s closed.", m_connectionInfo.database.c_str()); + //! Deletes the ACE_Activation_Queue object and its underlying ACE_Message_Queue + delete _queue; + + sLog->outSQLDriver("All connections on DatabasePool '%s' closed.", GetDatabaseName()); } /** @@ -133,6 +135,7 @@ class DatabaseWorkerPool */ //! Enqueues a one-way SQL operation in string format that will be executed asynchronously. + //! This method should only be used for queries that are only executed once, e.g during startup. void Execute(const char* sql) { if (!sql) @@ -143,6 +146,7 @@ class DatabaseWorkerPool } //! Enqueues a one-way SQL operation in string format -with variable args- that will be executed asynchronously. + //! This method should only be used for queries that are only executed once, e.g during startup. void PExecute(const char* sql, ...) { if (!sql) @@ -166,10 +170,11 @@ class DatabaseWorkerPool } /** - Direct syncrhonous one-way statement methods. + Direct synchronous one-way statement methods. */ //! Directly executes a one-way SQL operation in string format, that will block the calling thread until finished. + //! This method should only be used for queries that are only executed once, e.g during startup. void DirectExecute(const char* sql) { if (!sql) @@ -181,6 +186,7 @@ class DatabaseWorkerPool } //! Directly executes a one-way SQL operation in string format -with variable args-, that will block the calling thread until finished. + //! This method should only be used for queries that are only executed once, e.g during startup. void DirectPExecute(const char* sql, ...) { if (!sql) @@ -265,6 +271,9 @@ class DatabaseWorkerPool PreparedResultSet* ret = t->Query(stmt); t->Unlock(); + //! Delete proxy-class. Not needed anymore + delete stmt; + if (!ret || !ret->GetRowCount()) return PreparedQueryResult(NULL); @@ -335,20 +344,22 @@ class DatabaseWorkerPool //! were appended to the transaction will be respected during execution. void CommitTransaction(SQLTransaction transaction) { - if (sLog->GetSQLDriverQueryLogging()) + #ifdef TRINITY_DEBUG + //! Only analyze transaction weaknesses in Debug mode. + //! Ideally we catch the faults in Debug mode and then correct them, + //! so there's no need to waste these CPU cycles in Release mode. + switch (transaction->GetSize()) { - switch (transaction->GetSize()) - { - case 0: - sLog->outSQLDriver("Transaction contains 0 queries. Not executing."); - return; - case 1: - sLog->outSQLDriver("Warning: Transaction only holds 1 query, consider removing Transaction context in code."); - break; - default: - break; - } + case 0: + sLog->outSQLDriver("Transaction contains 0 queries. Not executing."); + return; + case 1: + sLog->outSQLDriver("Warning: Transaction only holds 1 query, consider removing Transaction context in code."); + break; + default: + break; } + #endif // TRINITY_DEBUG Enqueue(new TransactionTask(transaction)); } @@ -364,9 +375,11 @@ class DatabaseWorkerPool return; } + //! Handle MySQL Errno 1213 without extending deadlock to the core itself + //! TODO: More elegant way if (con->GetLastError() == 1213) { - uint8 loopBreaker = 5; // Handle MySQL Errno 1213 without extending deadlock to the core itself + uint8 loopBreaker = 5; for (uint8 i = 0; i < loopBreaker; ++i) { if (con->ExecuteTransaction(transaction)) @@ -374,7 +387,7 @@ class DatabaseWorkerPool } } - // Clean up now. + //! Clean up now. transaction->Cleanup(); con->Unlock(); @@ -405,6 +418,7 @@ class DatabaseWorkerPool */ //! Automanaged (internally) pointer to a prepared statement object for usage in upper level code. + //! Pointer is deleted in this->Query(PreparedStatement*) or PreparedStatementTask::~PreparedStatementTask. //! This object is not tied to the prepared statement on the MySQL context yet until execution. PreparedStatement* GetPreparedStatement(uint32 index) { @@ -426,10 +440,10 @@ class DatabaseWorkerPool //! Keeps all our MySQL connections alive, prevent the server from disconnecting us. void KeepAlive() { - /// Ping synchronous connections - for (uint8 i = 0; i < m_connectionCount[IDX_SYNCH]; ++i) + //! Ping synchronous connections + for (uint8 i = 0; i < _connectionCount[IDX_SYNCH]; ++i) { - T* t = m_connections[IDX_SYNCH][i]; + T* t = _connections[IDX_SYNCH][i]; if (t->LockIfReady()) { t->Ping(); @@ -437,10 +451,10 @@ class DatabaseWorkerPool } } - /// Assuming all worker threads are free, every worker thread will receive 1 ping operation request - /// If one or more worker threads are busy, the ping operations will not be split evenly, but this doesn't matter - /// as the sole purpose is to prevent connections from idling. - for (size_t i = 0; i < m_connections[IDX_ASYNC].size(); ++i) + //! Assuming all worker threads are free, every worker thread will receive 1 ping operation request + //! If one or more worker threads are busy, the ping operations will not be split evenly, but this doesn't matter + //! as the sole purpose is to prevent connections from idling. + for (size_t i = 0; i < _connections[IDX_ASYNC].size(); ++i) Enqueue(new PingOperation); } @@ -450,41 +464,50 @@ class DatabaseWorkerPool if (!to || !from || !length) return 0; - return mysql_real_escape_string(m_connections[IDX_SYNCH][0]->GetHandle(), to, from, length); + return mysql_real_escape_string(_connections[IDX_SYNCH][0]->GetHandle(), to, from, length); } void Enqueue(SQLOperation* op) { - m_queue->enqueue(op); + _queue->enqueue(op); } + //! Gets a free connection in the synchronous connection pool. + //! Caller MUST call t->Unlock() after touching the MySQL context to prevent deadlocks. T* GetFreeConnection() { uint8 i = 0; - size_t num_cons = m_connectionCount[IDX_SYNCH]; - for (;;) /// Block forever until a connection is free + size_t num_cons = _connectionCount[IDX_SYNCH]; + //! Block forever until a connection is free + for (;;) { - T* t = m_connections[IDX_SYNCH][++i % num_cons ]; - if (t->LockIfReady()) /// Must be matched with t->Unlock() or you will get deadlocks + T* t = _connections[IDX_SYNCH][++i % num_cons]; + //! Must be matched with t->Unlock() or you will get deadlocks + if (t->LockIfReady()) return t; } - // This will be called when Celine Dion learns to sing + //! This will be called when Celine Dion learns to sing return NULL; } + char const* GetDatabaseName() const + { + return _connectionInfo.database.c_str(); + } + private: - enum + enum _internalIndex { IDX_ASYNC, IDX_SYNCH, IDX_SIZE, }; - ACE_Activation_Queue* m_queue; //! Queue shared by async worker threads. - std::vector< std::vector<T*> > m_connections; - uint32 m_connectionCount[2]; //! Counter of MySQL connections; - MySQLConnectionInfo m_connectionInfo; + ACE_Activation_Queue* _queue; //! Queue shared by async worker threads. + std::vector< std::vector<T*> > _connections; + uint32 _connectionCount[2]; //! Counter of MySQL connections; + MySQLConnectionInfo _connectionInfo; }; #endif diff --git a/src/server/shared/Database/Field.h b/src/server/shared/Database/Field.h index 355f6b47ff2..2c5e7d47ca4 100755 --- a/src/server/shared/Database/Field.h +++ b/src/server/shared/Database/Field.h @@ -41,11 +41,12 @@ class Field return 0; #ifdef TRINITY_DEBUG - if (!IsNumeric()) + if (!IsType(MYSQL_TYPE_TINY)) { - sLog->outSQLDriver("Error: GetUInt8() on non-numeric field."); + sLog->outSQLDriver("Warning: GetUInt8() on non-tinyint field."); return 0; } + #endif if (data.raw) return *reinterpret_cast<uint8*>(data.value); @@ -58,12 +59,13 @@ class Field return 0; #ifdef TRINITY_DEBUG - if (!IsNumeric()) + if (!IsType(MYSQL_TYPE_TINY)) { - sLog->outSQLDriver("Error: GeInt8() on non-numeric field."); + sLog->outSQLDriver("Warning: GetInt8() on non-tinyint field."); return 0; } #endif + if (data.raw) return *reinterpret_cast<int8*>(data.value); return static_cast<int8>(atol((char*)data.value)); @@ -75,12 +77,13 @@ class Field return 0; #ifdef TRINITY_DEBUG - if (!IsNumeric()) + if (!IsType(MYSQL_TYPE_SHORT) && !IsType(MYSQL_TYPE_YEAR)) { - sLog->outSQLDriver("Error: GetUInt16() on non-numeric field."); + sLog->outSQLDriver("Warning: GetUInt16() on non-smallint field."); return 0; } #endif + if (data.raw) return *reinterpret_cast<uint16*>(data.value); return static_cast<uint16>(atol((char*)data.value)); @@ -92,12 +95,13 @@ class Field return 0; #ifdef TRINITY_DEBUG - if (!IsNumeric()) + if (!IsType(MYSQL_TYPE_SHORT) && !IsType(MYSQL_TYPE_YEAR)) { - sLog->outSQLDriver("Error: GetInt16() on non-numeric field."); + sLog->outSQLDriver("Warning: GetInt16() on non-smallint field."); return 0; } #endif + if (data.raw) return *reinterpret_cast<int16*>(data.value); return static_cast<int16>(atol((char*)data.value)); @@ -109,12 +113,13 @@ class Field return 0; #ifdef TRINITY_DEBUG - if (!IsNumeric()) + if (!IsType(MYSQL_TYPE_INT24) && !IsType(MYSQL_TYPE_LONG)) { - sLog->outSQLDriver("Error: GetUInt32() on non-numeric field."); + sLog->outSQLDriver("Warning: GetUInt32() on non-(medium)int field."); return 0; } #endif + if (data.raw) return *reinterpret_cast<uint32*>(data.value); return static_cast<uint32>(atol((char*)data.value)); @@ -126,12 +131,13 @@ class Field return 0; #ifdef TRINITY_DEBUG - if (!IsNumeric()) + if (!IsType(MYSQL_TYPE_INT24) && !IsType(MYSQL_TYPE_LONG)) { - sLog->outSQLDriver("Error: GetInt32() on non-numeric field."); + sLog->outSQLDriver("Warning: GetInt32() on non-(medium)int field."); return 0; } #endif + if (data.raw) return *reinterpret_cast<int32*>(data.value); return static_cast<int32>(atol((char*)data.value)); @@ -143,12 +149,13 @@ class Field return 0; #ifdef TRINITY_DEBUG - if (!IsNumeric()) + if (!IsType(MYSQL_TYPE_LONGLONG) && !IsType(MYSQL_TYPE_BIT)) { - sLog->outSQLDriver("Error: GetUInt64() on non-numeric field."); + sLog->outSQLDriver("Warning: GetUInt64() on non-bigint field."); return 0; } #endif + if (data.raw) return *reinterpret_cast<uint64*>(data.value); return static_cast<uint64>(atol((char*)data.value)); @@ -160,12 +167,13 @@ class Field return 0; #ifdef TRINITY_DEBUG - if (!IsNumeric()) + if (!IsType(MYSQL_TYPE_LONGLONG) && !IsType(MYSQL_TYPE_BIT)) { - sLog->outSQLDriver("Error: GetInt64() on non-numeric field."); + sLog->outSQLDriver("Warning: GetInt64() on non-bigint field."); return 0; } #endif + if (data.raw) return *reinterpret_cast<int64*>(data.value); return static_cast<int64>(strtol((char*)data.value, NULL, 10)); @@ -177,12 +185,13 @@ class Field return 0.0f; #ifdef TRINITY_DEBUG - if (!IsNumeric()) + if (!IsType(MYSQL_TYPE_FLOAT)) { - sLog->outSQLDriver("Error: GetFloat() on non-numeric field."); + sLog->outSQLDriver("Warning: GetFloat() on non-float field."); return 0.0f; } #endif + if (data.raw) return *reinterpret_cast<float*>(data.value); return static_cast<float>(atof((char*)data.value)); @@ -194,12 +203,13 @@ class Field return 0.0f; #ifdef TRINITY_DEBUG - if (!IsNumeric()) + if (!IsType(MYSQL_TYPE_DOUBLE)) { - sLog->outSQLDriver("Error: GetDouble() on non-numeric field."); + sLog->outSQLDriver("Warning: GetDouble() on non-double field."); return 0.0f; } #endif + if (data.raw) return *reinterpret_cast<double*>(data.value); return static_cast<double>(atof((char*)data.value)); @@ -316,6 +326,11 @@ class Field } } + bool IsType(enum_field_types type) const + { + return data.type == type; + } + bool IsNumeric() const { return (data.type == MYSQL_TYPE_TINY || diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index 125c4509b18..3d30e97544a 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -28,12 +28,13 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_DEL_EXPIRED_BANS, "UPDATE character_banned SET active = 0 WHERE unbandate <= UNIX_TIMESTAMP() AND unbandate <> bandate", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_GUID_BY_NAME, "SELECT guid FROM characters WHERE name = ?", CONNECTION_BOTH); PREPARE_STATEMENT(CHAR_SEL_CHECK_NAME, "SELECT 1 FROM characters WHERE name = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_SEL_CHECK_GUID, "SELECT 1 FROM characters WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_SUM_CHARS, "SELECT COUNT(guid) FROM characters WHERE account = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_SEL_CHAR_CREATE_INFO, "SELECT level, race, class FROM characters WHERE account = ? LIMIT 0, ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_INS_CHARACTER_BAN, "INSERT INTO character_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, ?, ?, 1)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_UPD_CHARACTER_BAN, "UPDATE character_banned SET active = 0 WHERE guid = ? AND active != 0", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_BANINFO, "SELECT FROM_UNIXTIME(bandate), unbandate-bandate, active, unbandate, banreason, bannedby FROM character_banned WHERE guid = ? ORDER BY bandate ASC", CONNECTION_SYNCH) - PREPARE_STATEMENT(CHAR_SEL_GUID_BY_NAME_FILTER, "SELECT guid, name FROM characters WHERE name LIKE CONCAT('%', ?, '%')", CONNECTION_SYNCH) + PREPARE_STATEMENT(CHAR_SEL_GUID_BY_NAME_FILTER, "SELECT guid, name FROM characters WHERE name LIKE CONCAT('%%', ?, '%%')", CONNECTION_SYNCH) PREPARE_STATEMENT(CHAR_SEL_BANINFO_LIST, "SELECT bandate, unbandate, bannedby, banreason FROM character_banned WHERE guid = ? ORDER BY unbandate", CONNECTION_SYNCH) PREPARE_STATEMENT(CHAR_SEL_BANNED_NAME, "SELECT characters.name FROM characters, character_banned WHERE character_banned.guid = ? AND character_banned.guid = characters.guid", CONNECTION_SYNCH) PREPARE_STATEMENT(CHAR_SEL_ENUM, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.playerBytes, c.playerBytes2, c.level, c.zone, c.map, c.position_x, c.position_y, c.position_z, gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, cb.guid FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? LEFT JOIN guild_member AS gm ON c.guid = gm.guid LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? ORDER BY c.guid", CONNECTION_ASYNC); @@ -44,6 +45,11 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_SEL_PET_SLOT_BY_ID, "SELECT slot, entry FROM character_pet WHERE owner = ? AND id = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_SEL_FREE_NAME, "SELECT guid, name FROM characters WHERE guid = ? AND account = ? AND (at_login & ?) = ? AND NOT EXISTS (SELECT NULL FROM characters WHERE name = ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_SEL_GUID_RACE_ACC_BY_NAME, "SELECT guid, race, account FROM characters WHERE name = ?", CONNECTION_BOTH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_RACE, "SELECT race FROM characters WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_LEVEL, "SELECT level FROM characters WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_ZONE, "SELECT zone FROM characters WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_POSITION_XYZ, "SELECT map, position_x, position_y, position_z FROM characters WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_POSITION, "SELECT position_x, position_y, position_z, orientation, map, taxi_path FROM characters WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_DEL_QUEST_STATUS_DAILY, "DELETE FROM character_queststatus_daily", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_QUEST_STATUS_WEEKLY, "DELETE FROM character_queststatus_weekly", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_QUEST_STATUS_SEASONAL, "DELETE FROM character_queststatus_seasonal WHERE event = ?", CONNECTION_ASYNC); @@ -59,7 +65,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() "resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, " "arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, " "health, power1, power2, power3, power4, power5, power6, power7, instance_id, speccount, activespec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels FROM characters WHERE guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?", CONNECTION_BOTH) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_INSTANCE, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_AURAS, "SELECT caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, " "base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges FROM character_aura WHERE guid = ?", CONNECTION_ASYNC) @@ -78,11 +84,12 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_SEL_CHARACTER_ACTIONS, "SELECT a.button, a.action, a.type FROM character_action as a, characters as c WHERE a.guid = c.guid AND a.spec = c.activespec AND a.guid = ? ORDER BY button", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_MAILCOUNT, "SELECT COUNT(id) FROM mail WHERE receiver = ? AND (checked & 1) = 0 AND deliver_time <= ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_MAILDATE, "SELECT MIN(deliver_time) FROM mail WHERE receiver = ? AND (checked & 1) = 0", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_SEL_MAIL_COUNT, "SELECT COUNT(*) FROM mail WHERE receiver = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_CHARACTER_SOCIALLIST, "SELECT friend, flags, note FROM character_social JOIN characters ON characters.guid = character_social.friend WHERE character_social.guid = ? AND deleteinfos_name IS NULL LIMIT 255", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_HOMEBIND, "SELECT mapId, zoneId, posX, posY, posZ FROM character_homebind WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_SPELLCOOLDOWNS, "SELECT spell, item, time FROM character_spell_cooldown WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_DECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_SEL_GUILD_MEMBER, "SELECT guildid, rank FROM guild_member WHERE guid = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_SEL_GUILD_MEMBER, "SELECT guildid, rank FROM guild_member WHERE guid = ?", CONNECTION_BOTH) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_ACHIEVEMENTS, "SELECT achievement, date FROM character_achievement WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_CRITERIAPROGRESS, "SELECT criteria, counter, date FROM character_achievement_progress WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_EQUIPMENTSETS, "SELECT setguid, setindex, name, iconname, item0, item1, item2, item3, item4, item5, item6, item7, item8, " @@ -103,8 +110,10 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_SEL_AUCTIONS, "SELECT id, auctioneerguid, itemguid, itemEntry, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid", CONNECTION_SYNCH) PREPARE_STATEMENT(CHAR_INS_AUCTION, "INSERT INTO auctionhouse (id, auctioneerguid, itemguid, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_AUCTION, "DELETE FROM auctionhouse WHERE id = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_SEL_AUCTION_BY_TIME, "SELECT id FROM auctionhouse WHERE time <= ? ORDER BY TIME ASC", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_UPD_AUCTION_BID, "UPDATE auctionhouse SET buyguid = ?, lastbid = ? WHERE id = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_INS_MAIL, "INSERT INTO mail(id, messageType, stationery, mailTemplateId, sender, receiver, subject, body, has_items, expire_time, deliver_time, money, cod, checked) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_DEL_MAIL, "DELETE FROM mail WHERE id = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_DEL_MAIL_BY_ID, "DELETE FROM mail WHERE id = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_INS_MAIL_ITEM, "INSERT INTO mail_items(mail_id, item_guid, receiver) VALUES (?, ?, ?)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_MAIL_ITEM, "DELETE FROM mail_items WHERE item_guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_INVALID_MAIL_ITEM, "DELETE FROM mail_items WHERE item_guid = ?", CONNECTION_ASYNC); @@ -127,10 +136,14 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_DEL_ITEM_INSTANCE, "DELETE FROM item_instance WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_UPD_GIFT_OWNER, "UPDATE character_gifts SET guid = ? WHERE item_guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_GIFT, "DELETE FROM character_gifts WHERE item_guid = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_SEL_CHARACTER_GIFT_BY_ITEM, "SELECT entry, flags FROM character_gifts WHERE item_guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_ACCOUNT_BY_NAME, "SELECT account FROM characters WHERE name = ?", CONNECTION_SYNCH) + PREPARE_STATEMENT(CHAR_SEL_ACCOUNT_BY_GUID, "SELECT account FROM characters WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_ACCOUNT_NAME_BY_GUID, "SELECT account, name FROM characters WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_DEL_ACCOUNT_INSTANCE_LOCK_TIMES, "DELETE FROM account_instance_times WHERE accountId = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_INS_ACCOUNT_INSTANCE_LOCK_TIMES, "INSERT INTO account_instance_times (accountId, instanceId, releaseTime) VALUES (?, ?, ?)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_NAME_CLASS, "SELECT name, class FROM characters WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHARACTER_NAME, "SELECT name FROM characters WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_MATCH_MAKER_RATING, "SELECT matchMakerRating FROM character_arena_stats WHERE guid = ? AND slot = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_CHARACTER_COUNT, "SELECT account, COUNT(guid) FROM characters WHERE account = ? GROUP BY account", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_NAME, "UPDATE characters set name = ?, at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC); @@ -263,6 +276,13 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_SEL_PETITION_SIGNATURE, "SELECT playerguid FROM petition_sign WHERE petitionguid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_DEL_ALL_PETITION_SIGNATURES, "DELETE FROM petition_sign WHERE playerguid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_PETITION_SIGNATURE, "DELETE FROM petition_sign WHERE playerguid = ? AND type = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_SEL_PETITION_BY_OWNER, "SELECT petitionguid FROM petition WHERE ownerguid = ? AND type = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_PETITION_TYPE, "SELECT type FROM petition WHERE petitionguid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_PETITION_SIGNATURES, "SELECT ownerguid, (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = ?) AS signs, type FROM petition WHERE petitionguid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_PETITION_SIG_BY_ACCOUNT, "SELECT playerguid FROM petition_sign WHERE player_account = ? AND petitionguid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_PETITION_OWNER_BY_GUID, "SELECT ownerguid FROM petition WHERE petitionguid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_PETITION_SIG_BY_GUID, "SELECT ownerguid, petitionguid FROM petition_sign WHERE playerguid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_PETITION_SIG_BY_GUID_TYPE, "SELECT ownerguid, petitionguid FROM petition_sign WHERE playerguid = ? AND type = ?", CONNECTION_SYNCH); // Arena teams PREPARE_STATEMENT(CHAR_SEL_CHARACTER_ARENAINFO, "SELECT arenaTeamId, weekGames, seasonGames, seasonWins, personalRating FROM arena_team_member WHERE guid = ?", CONNECTION_ASYNC) @@ -280,7 +300,6 @@ void CharacterDatabaseConnection::DoPrepareStatements() // Character battleground data PREPARE_STATEMENT(CHAR_INS_PLAYER_BGDATA, "INSERT INTO character_battleground_data (guid, instanceId, team, joinX, joinY, joinZ, joinO, joinMapId, taxiStart, taxiEnd, mountSpell) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_PLAYER_BGDATA, "DELETE FROM character_battleground_data WHERE guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_PLAYERS_BGDATA, "UPDATE character_battleground_data SET instanceId = 0", CONNECTION_SYNCH) // Character homebind PREPARE_STATEMENT(CHAR_INS_PLAYER_HOMEBIND, "INSERT INTO character_homebind (guid, mapId, zoneId, posX, posY, posZ) VALUES (?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) @@ -293,7 +312,6 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_DEL_CORPSE, "DELETE FROM corpse WHERE corpseGuid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_PLAYER_CORPSES, "DELETE FROM corpse WHERE guid = ? AND corpseType <> 0", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_OLD_CORPSES, "DELETE FROM corpse WHERE corpseType = 0 OR time < (UNIX_TIMESTAMP(NOW()) - ?)", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_NONEXISTENT_INSTANCE_FOR_CORPSES, "UPDATE corpse SET instanceId = 0 WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)", CONNECTION_SYNCH) // Creature respawn PREPARE_STATEMENT(CHAR_SEL_CREATURE_RESPAWNS, "SELECT guid, respawnTime, instanceId FROM creature_respawn", CONNECTION_SYNCH) @@ -302,15 +320,12 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN_BY_GUID, "DELETE FROM creature_respawn WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE, "DELETE FROM creature_respawn WHERE instanceId = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_MAX_CREATURE_RESPAWNS, "SELECT MAX(respawnTime), instanceId FROM creature_respawn WHERE instanceId > 0 GROUP BY instanceId", CONNECTION_SYNCH) - PREPARE_STATEMENT(CHAR_DEL_NONEXISTENT_INSTANCE_CREATURE_RESPAWNS, "DELETE FROM creature_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)", CONNECTION_SYNCH) // Gameobject respawn PREPARE_STATEMENT(CHAR_SEL_GO_RESPAWNS, "SELECT guid, respawnTime, instanceId FROM gameobject_respawn", CONNECTION_SYNCH) PREPARE_STATEMENT(CHAR_REP_GO_RESPAWN, "REPLACE INTO gameobject_respawn (guid, respawnTime, instanceId) VALUES (?, ?, ?)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_GO_RESPAWN, "DELETE FROM gameobject_respawn WHERE guid = ? AND instanceId = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_GO_RESPAWN_BY_INSTANCE, "DELETE FROM gameobject_respawn WHERE instanceId = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_DEL_EXPIRED_GO_RESPAWNS, "DELETE FROM gameobject_respawn WHERE respawnTime <= UNIX_TIMESTAMP(NOW())", CONNECTION_SYNCH) - PREPARE_STATEMENT(CHAR_DEL_NONEXISTENT_INSTANCE_GO_RESPAWNS, "DELETE FROM gameobject_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)", CONNECTION_SYNCH) // GM Tickets PREPARE_STATEMENT(CHAR_SEL_GM_TICKETS, "SELECT ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, completed, escalated, viewed FROM gm_tickets", CONNECTION_SYNCH) @@ -383,7 +398,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_UPD_CHAR_NAME_AT_LOGIN, "UPDATE characters set name = ?, at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_WORLDSTATE, "UPDATE worldstates SET value = ? WHERE entry = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_INS_WORLDSTATE, "INSERT INTO worldstates (entry, value) VALUES (?, ?)", CONNECTION_ASYNC); - PREPARE_STATEMENT(CHAR_DEL_CHAR_INSTANCE, "DELETE FROM character_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID, "DELETE FROM character_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_CHAR_INSTANCE, "UPDATE character_instance SET instance = ?, permanent = ? WHERE guid = ? AND instance = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_INS_CHAR_INSTANCE, "INSERT INTO character_instance (guid, instance, permanent) VALUES (?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_GENDER_PLAYERBYTES, "UPDATE characters SET gender = ?, playerBytes = ?, playerBytes2 = ? WHERE guid = ?", CONNECTION_ASYNC); @@ -394,5 +409,145 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_DEL_CHARACTER_SOCIAL, "DELETE FROM character_social WHERE guid = ? AND friend = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_CHARACTER_SOCIAL_NOTE, "UPDATE character_social SET note = ? WHERE guid = ? AND friend = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_CHARACTER_POSITION, "UPDATE characters SET position_x = ?, position_y = ?, position_z = ?, orientation = ?, map = ?, zone = ?, trans_x = 0, trans_y = 0, trans_z = 0, transguid = 0, taxi_path = '' WHERE guid = ?", CONNECTION_ASYNC); - + PREPARE_STATEMENT(CHAR_SEL_CHARACTER_AURA_FROZEN, "SELECT characters.name FROM characters LEFT JOIN character_aura ON (characters.guid = character_aura.guid) WHERE character_aura.spell = 9454", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHARACTER_ONLINE, "SELECT name, account, map, zone FROM characters WHERE online > 0", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_DEL_INFO_BY_GUID, "SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL AND guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_DEL_INFO_BY_NAME, "SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL AND deleteInfos_Name LIKE CONCAT('%%', ?, '%%')", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_DEL_INFO, "SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHARS_BY_ACCOUNT_ID, "SELECT guid FROM characters WHERE account = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_PINFO, "SELECT totaltime, level, money, account, race, class, map, zone FROM characters WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_PINFO_BANS, "SELECT unbandate, bandate = unbandate, bannedby, banreason FROM character_banned WHERE guid = ? AND active ORDER BY bandate ASC LIMIT 1", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_HOMEBIND, "SELECT mapId, zoneId, posX, posY, posZ FROM character_homebind WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_GUID_NAME_BY_ACC, "SELECT guid, name FROM characters WHERE account = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_POOL_QUEST_SAVE, "SELECT quest_id FROM pool_quest_save WHERE pool_id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHARACTER_AT_LOGIN, "SELECT at_login FROM characters WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_CLASS_LVL_AT_LOGIN, "SELECT class, level, at_login FROM characters WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_INSTANCE, "SELECT data, completedEncounters FROM instance WHERE map = ? AND id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_PET_SPELL_LIST, "SELECT DISTINCT pet_spell.spell FROM pet_spell, character_pet WHERE character_pet.owner = ? AND character_pet.id = pet_spell.guid AND character_pet.id <> ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_PET, "SELECT id FROM character_pet WHERE owner = ? AND id <> ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_PETS, "SELECT id FROM character_pet WHERE owner = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_COD_ITEM_MAIL, "SELECT id, messageType, mailTemplateId, sender, subject, body, money, has_items FROM mail WHERE receiver = ? AND has_items <> 0 AND cod <> 0", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_SOCIAL, "SELECT DISTINCT guid FROM character_social WHERE friend = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_PET_AURA, "SELECT caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges FROM pet_aura WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_OLD_CHARS, "SELECT guid, deleteInfos_Account FROM characters WHERE deleteDate IS NOT NULL AND deleteDate < ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID, "SELECT arena_team_member.arenateamid FROM arena_team_member JOIN arena_team ON arena_team_member.arenateamid = arena_team.arenateamid WHERE guid = ? AND type = ? LIMIT 1", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_MAIL, "SELECT id, messageType, sender, receiver, subject, body, has_items, expire_time, deliver_time, money, cod, checked, stationery, mailTemplateId FROM mail WHERE receiver = ? ORDER BY id DESC", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_PLAYERBYTES2, "SELECT playerBytes2 FROM characters WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_PET_SPELL, "SELECT spell, active FROM pet_spell WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_PET_SPELL_COOLDOWN, "SELECT spell, time FROM pet_spell_cooldown WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_PET_DECLINED_NAME, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE owner = ? AND id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_GUID_BY_NAME, "SELECT characters.guid FROM characters WHERE characters.name = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_DEL_CHAR_AURA_FROZEN, "DELETE FROM character_aura WHERE character_aura.spell = 9454 AND character_aura.guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM character_inventory ci INNER JOIN item_instance ii ON ii.guid = ci.item WHERE itemEntry = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_MAIL_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM mail_items mi INNER JOIN item_instance ii ON ii.guid = mi.item_guid WHERE itemEntry = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_AUCTIONHOUSE_COUNT_ITEM,"SELECT COUNT(itemEntry) FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid WHERE itemEntry = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_GUILD_BANK_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM guild_bank_item gbi INNER JOIN item_instance ii ON ii.guid = gbi.item_guid WHERE itemEntry = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_INVENTORY_ITEM_BY_ENTRY, "SELECT ci.item, cb.slot AS bag, ci.slot, ci.guid, c.account, c.name FROM characters c INNER JOIN character_inventory ci ON ci.guid = c.guid INNER JOIN item_instance ii ON ii.guid = ci.item LEFT JOIN character_inventory cb ON cb.item = ci.bag WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_MAIL_ITEMS_BY_ENTRY, "SELECT mi.item_guid, m.sender, m.receiver, cs.account, cs.name, cr.account, cr.name FROM mail m INNER JOIN mail_items mi ON mi.mail_id = m.id INNER JOIN item_instance ii ON ii.guid = mi.item_guid INNER JOIN characters cs ON cs.guid = m.sender INNER JOIN characters cr ON cr.guid = m.receiver WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY, "SELECT ah.itemguid, ah.itemowner, c.account, c.name FROM auctionhouse ah INNER JOIN characters c ON c.guid = ah.itemowner INNER JOIN item_instance ii ON ii.guid = ah.itemguid WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_GUILD_BANK_ITEM_BY_ENTRY, "SELECT gi.item_guid, gi.guildid, g.name FROM guild_bank_item gi INNER JOIN guild g ON g.guildid = gi.guildid INNER JOIN item_instance ii ON ii.guid = gi.item_guid WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT_2, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND entry = ? AND (slot = ? OR slot > ?)", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND (slot = ? OR slot > ?) ", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_DEL_CHAR_ACHIEVEMENT, "DELETE FROM character_achievement WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS, "DELETE FROM character_achievement_progress WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_REPUTATION_BY_FACTION, "DELETE FROM character_reputation WHERE guid = ? AND faction = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_CHAR_REPUTATION_BY_FACTION, "INSERT INTO character_reputation (guid, faction, standing, flags) VALUES (?, ?, ? , ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPD_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = (arenaPoints + ?) WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_ITEM_REFUND_INSTANCE, "DELETE FROM item_refund_instance WHERE item_guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_ITEM_REFUND_INSTANCE, "INSERT INTO item_refund_instance (item_guid, player_guid, paidMoney, paidExtendedCost) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_GROUP, "DELETE FROM groups WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_GROUP_MEMBER_ALL, "DELETE FROM group_member WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_CHAR_GIFT, "INSERT INTO character_gifts (guid, item_guid, entry, flags) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_INSTANCE_BY_INSTANCE, "DELETE FROM instance WHERE id = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE, "DELETE FROM character_instance WHERE instance = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_INSTANCE_BY_MAP_DIFF, "DELETE FROM character_instance USING character_instance LEFT JOIN instance ON character_instance.instance = id WHERE map = ? and difficulty = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_GROUP_INSTANCE_BY_MAP_DIFF, "DELETE FROM group_instance USING group_instance LEFT JOIN instance ON group_instance.instance = id WHERE map = ? and difficulty = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_INSTANCE_BY_MAP_DIFF, "DELETE FROM instance WHERE map = ? and difficulty = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_MAIL_ITEM_BY_ID, "DELETE FROM mail_items WHERE mail_id = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_PET_DECLINEDNAME, "DELETE FROM character_pet_declinedname WHERE id = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_ADD_CHAR_PET_DECLINEDNAME, "INSERT INTO character_pet_declinedname (id, owner, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPD_CHAR_PET_NAME, "UPDATE character_pet SET name = ?, renamed = 1 WHERE owner = ? AND id = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_PETITION, "INSERT INTO petition (ownerguid, petitionguid, name, type) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_PETITION_BY_GUID, "DELETE FROM petition WHERE petitionguid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_PETITION_SIGNATURE_BY_GUID, "DELETE FROM petition_sign WHERE petitionguid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UDP_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID, "UPDATE character_pet SET slot = ? WHERE owner = ? AND slot = ? AND id <> ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UDP_CHAR_PET_SLOT_BY_SLOT, "UPDATE character_pet SET slot = ? WHERE owner = ? AND slot = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPD_CHAR_PET_SLOT_BY_ID, "UPDATE character_pet SET slot = ? WHERE owner = ? AND id = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_PET_BY_ID, "DELETE FROM character_pet WHERE id = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_PET_BY_SLOT, "DELETE FROM character_pet WHERE owner = ? AND (slot = ? OR slot > ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_PET_AURAS, "DELETE FROM pet_aura WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_PET_SPELLS, "DELETE FROM pet_spell WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_PET_SPELL_COOLDOWNS, "DELETE FROM pet_spell_cooldown WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_PET_SPELL_COOLDOWN, "INSERT INTO pet_spell_cooldown (guid, spell, time) VALUES (?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_PET_SPELL_BY_SPELL, "DELETE FROM pet_spell WHERE guid = ? and spell = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_PET_SPELL, "INSERT INTO pet_spell (guid, spell, active) VALUES (?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_PET_AURA, "INSERT INTO pet_aura (guid, caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_DECLINED_NAME, "DELETE FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_CHAR_DECLINED_NAME, "INSERT INTO character_declinedname (guid, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPD_FACTION_OR_RACE, "UPDATE characters SET name = ?, race = ?, at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_SKILL_LANGUAGES, "DELETE FROM character_skills WHERE skill IN (98, 113, 759, 111, 313, 109, 115, 315, 673, 137) AND guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_CHAR_SKILL_LANGUAGE, "INSERT INTO `character_skills` (guid, skill, value, max) VALUES (?, ?, 300, 300)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPD_CHAR_TAXI_PATH, "UPDATE characters SET taxi_path = '' WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPD_CHAR_TAXIMASK, "UPDATE characters SET taximask = ? WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_QUESTSTATUS, "DELETE FROM character_queststatus WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_SOCIAL_BY_GUID, "DELETE FROM character_social WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_SOCIAL_BY_FRIEND, "DELETE FROM character_social WHERE friend = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT, "DELETE FROM character_achievement WHERE achievement = ? AND guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPD_CHAR_ACHIEVEMENT, "UPDATE character_achievement SET achievement = ? where achievement = ? AND guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE, "UPDATE item_instance ii, character_inventory ci SET ii.itemEntry = ? WHERE ii.itemEntry = ? AND ci.guid = ? AND ci.item = ii.guid", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_SPELL_BY_SPELL, "DELETE FROM character_spell WHERE spell = ? AND guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPD_CHAR_SPELL_FACTION_CHANGE, "UPDATE character_spell SET spell = ? where spell = ? AND guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_REP_BY_FACTION, "DELETE FROM character_reputation WHERE faction = ? AND guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPD_CHAR_REP_FACTION_CHANGE, "UPDATE character_reputation SET faction = ? where faction = ? AND guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_SPELL_COOLDOWN, "DELETE FROM character_spell_cooldown WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHARACTER, "DELETE FROM characters WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_ACTION, "DELETE FROM character_action WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_AURA, "DELETE FROM character_aura WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_GIFT, "DELETE FROM character_gifts WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_INSTANCE, "DELETE FROM character_instance WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_INVENTORY, "DELETE FROM character_instance WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_QUESTSTATUS_REWARDED, "DELETE FROM character_queststatus_rewarded WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_REPUTATION, "DELETE FROM character_reputation WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_SPELL, "DELETE FROM character_spell WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_MAIL, "DELETE FROM mail WHERE receiver = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_MAIL_ITEMS, "DELETE FROM mail_items WHERE receiver = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_PET_BY_OWNER, "DELETE FROM character_pet WHERE owner = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_PET_DECLINEDNAME_BY_OWNER, "DELETE FROM character_pet_declinedname WHERE owner = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_ACHIEVEMENTS, "DELETE FROM character_achievement WHERE guid = ? AND achievement NOT BETWEEN '456' AND '467' AND achievement NOT BETWEEN '1400' AND '1427' AND achievement NOT IN(1463, 3117, 3259)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_EQUIPMENTSETS, "DELETE FROM character_equipmentsets WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_GUILD_EVENTLOG_BY_PLAYER, "DELETE FROM guild_eventlog WHERE PlayerGuid1 = ? OR PlayerGuid2 = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_GUILD_BANK_EVENTLOG_BY_PLAYER, "DELETE FROM guild_bank_eventlog WHERE PlayerGuid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_GLYPHS, "DELETE FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_QUESTSTATUS_DAILY, "DELETE FROM character_queststatus_daily WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_TALENT, "DELETE FROM character_talent WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_SKILLS, "DELETE FROM character_skills WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UDP_CHAR_HONOR_POINTS, "UPDATE characters SET totalHonorPoints = ? WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UDP_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = ? WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UDP_CHAR_MONEY, "UPDATE characters SET money = ? WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_CHAR_ACTION, "INSERT INTO character_action (guid, spec, button, action, type) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPD_CHAR_ACTION, "UPDATE character_action SET action = ?, type = ? WHERE guid = ? AND button = ? AND spec = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_ACTION_BY_BUTTON_SPEC, "DELETE FROM character_action WHERE guid = ? and button = ? and spec = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_INVENTORY_BY_ITEM, "DELETE FROM character_inventory WHERE item = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_INVENTORY_BY_BAG_SLOT, "DELETE FROM character_inventory WHERE bag = ? AND slot = ? AND guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPD_MAIL, "UPDATE mail SET has_items = ?, expire_time = ?, deliver_time = ?, money = ?, cod = ?, checked = ? WHERE id = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_REP_CHAR_QUESTSTATUS, "REPLACE INTO character_queststatus (guid, quest, status, explored, timer, mobcount1, mobcount2, mobcount3, mobcount4, itemcount1, itemcount2, itemcount3, itemcount4, playercount) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_QUESTSTATUS_BY_QUEST, "DELETE FROM character_queststatus WHERE guid = ? AND quest = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_CHAR_QUESTSTATUS, "INSERT IGNORE INTO character_queststatus_rewarded (guid, quest) VALUES (?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST, "DELETE FROM character_queststatus_rewarded WHERE guid = ? AND quest = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_SKILL_BY_SKILL, "DELETE FROM character_skills WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_CHAR_SKILLS, "INSERT INTO character_skills (guid, skill, value, max) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UDP_CHAR_SKILLS, "UPDATE character_skills SET value = ?, max = ? WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_CHAR_SPELL, "INSERT INTO character_spell (guid, spell, active, disabled) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_STATS, "DELETE FROM character_stats WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_CHAR_STATS, "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, maxpower6, maxpower7, strength, agility, stamina, intellect, spirit, armor, resHoly, resFire, resNature, resFrost, resShadow, resArcane, blockPct, dodgePct, parryPct, critPct, rangedCritPct, spellCritPct, attackPower, rangedAttackPower, spellPower, resilience) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_PETITION_BY_OWNER, "DELETE FROM petition WHERE ownerguid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER, "DELETE FROM petition_sign WHERE ownerguid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_PETITION_BY_OWNER_AND_TYPE, "DELETE FROM petition WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER_AND_TYPE, "DELETE FROM petition_sign WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_CHAR_GLYPHS, "INSERT INTO character_glyphs VALUES(?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC, "DELETE FROM character_talent WHERE guid = ? and spell = ? and spec = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_CHAR_TALENT, "INSERT INTO character_talent (guid, spell, spec) VALUES (?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC, "DELETE FROM character_action WHERE spec<>? AND guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND slot = ?", CONNECTION_SYNCH); } diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index ca53712fbaa..4d8433c74b2 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -48,6 +48,7 @@ enum CharacterDatabaseStatements CHAR_DEL_EXPIRED_BANS, CHAR_SEL_GUID_BY_NAME, CHAR_SEL_CHECK_NAME, + CHAR_SEL_CHECK_GUID, CHAR_SEL_SUM_CHARS, CHAR_SEL_CHAR_CREATE_INFO, CHAR_INS_CHARACTER_BAN, @@ -64,6 +65,11 @@ enum CharacterDatabaseStatements CHAR_SEL_PET_SLOT_BY_ID, CHAR_SEL_FREE_NAME, CHAR_SEL_GUID_RACE_ACC_BY_NAME, + CHAR_SEL_CHAR_RACE, + CHAR_SEL_CHAR_LEVEL, + CHAR_SEL_CHAR_ZONE, + CHAR_SEL_CHAR_POSITION_XYZ, + CHAR_SEL_CHAR_POSITION, CHAR_DEL_QUEST_STATUS_DAILY, CHAR_DEL_QUEST_STATUS_WEEKLY, CHAR_DEL_QUEST_STATUS_SEASONAL, @@ -91,6 +97,7 @@ enum CharacterDatabaseStatements CHAR_SEL_CHARACTER_ACTIONS_SPEC, CHAR_SEL_CHARACTER_MAILCOUNT, CHAR_SEL_CHARACTER_MAILDATE, + CHAR_SEL_MAIL_COUNT, CHAR_SEL_CHARACTER_SOCIALLIST, CHAR_SEL_CHARACTER_HOMEBIND, CHAR_SEL_CHARACTER_SPELLCOOLDOWNS, @@ -112,9 +119,11 @@ enum CharacterDatabaseStatements CHAR_SEL_AUCTION_ITEMS, CHAR_INS_AUCTION, CHAR_DEL_AUCTION, + CHAR_SEL_AUCTION_BY_TIME, + CHAR_UPD_AUCTION_BID, CHAR_SEL_AUCTIONS, CHAR_INS_MAIL, - CHAR_DEL_MAIL, + CHAR_DEL_MAIL_BY_ID, CHAR_INS_MAIL_ITEM, CHAR_DEL_MAIL_ITEM, CHAR_DEL_INVALID_MAIL_ITEM, @@ -136,14 +145,18 @@ enum CharacterDatabaseStatements CHAR_DEL_ITEM_INSTANCE, CHAR_UPD_GIFT_OWNER, CHAR_DEL_GIFT, + CHAR_SEL_CHARACTER_GIFT_BY_ITEM, CHAR_SEL_ACCOUNT_BY_NAME, + CHAR_SEL_ACCOUNT_BY_GUID, CHAR_DEL_ACCOUNT_INSTANCE_LOCK_TIMES, CHAR_INS_ACCOUNT_INSTANCE_LOCK_TIMES, CHAR_SEL_CHARACTER_NAME_CLASS, + CHAR_SEL_CHARACTER_NAME, CHAR_SEL_MATCH_MAKER_RATING, CHAR_SEL_CHARACTER_COUNT, CHAR_UPD_NAME, CHAR_DEL_DECLINED_NAME, + CHAR_SEL_ACCOUNT_NAME_BY_GUID, CHAR_INS_GUILD, CHAR_DEL_GUILD, @@ -259,10 +272,16 @@ enum CharacterDatabaseStatements CHAR_SEL_PETITION_SIGNATURE, CHAR_DEL_ALL_PETITION_SIGNATURES, CHAR_DEL_PETITION_SIGNATURE, + CHAR_SEL_PETITION_BY_OWNER, + CHAR_SEL_PETITION_TYPE, + CHAR_SEL_PETITION_SIGNATURES, + CHAR_SEL_PETITION_SIG_BY_ACCOUNT, + CHAR_SEL_PETITION_OWNER_BY_GUID, + CHAR_SEL_PETITION_SIG_BY_GUID, + CHAR_SEL_PETITION_SIG_BY_GUID_TYPE, CHAR_INS_PLAYER_BGDATA, CHAR_DEL_PLAYER_BGDATA, - CHAR_UPD_PLAYERS_BGDATA, CHAR_INS_PLAYER_HOMEBIND, CHAR_UPD_PLAYER_HOMEBIND, @@ -273,7 +292,6 @@ enum CharacterDatabaseStatements CHAR_DEL_CORPSE, CHAR_DEL_PLAYER_CORPSES, CHAR_DEL_OLD_CORPSES, - CHAR_UPD_NONEXISTENT_INSTANCE_FOR_CORPSES, CHAR_SEL_CREATURE_RESPAWNS, CHAR_REP_CREATURE_RESPAWN, @@ -281,14 +299,11 @@ enum CharacterDatabaseStatements CHAR_DEL_CREATURE_RESPAWN_BY_GUID, CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE, CHAR_SEL_MAX_CREATURE_RESPAWNS, - CHAR_DEL_NONEXISTENT_INSTANCE_CREATURE_RESPAWNS, CHAR_SEL_GO_RESPAWNS, CHAR_REP_GO_RESPAWN, CHAR_DEL_GO_RESPAWN, CHAR_DEL_GO_RESPAWN_BY_INSTANCE, - CHAR_DEL_EXPIRED_GO_RESPAWNS, - CHAR_DEL_NONEXISTENT_INSTANCE_GO_RESPAWNS, CHAR_SEL_GM_TICKETS, CHAR_REP_GM_TICKET, @@ -340,7 +355,7 @@ enum CharacterDatabaseStatements CHAR_UPD_CHAR_NAME_AT_LOGIN, CHAR_UPD_WORLDSTATE, CHAR_INS_WORLDSTATE, - CHAR_DEL_CHAR_INSTANCE, + CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID, CHAR_UPD_CHAR_INSTANCE, CHAR_INS_CHAR_INSTANCE, CHAR_UPD_GENDER_PLAYERBYTES, @@ -355,6 +370,150 @@ enum CharacterDatabaseStatements CHAR_INS_LFG_DATA, CHAR_DEL_LFG_DATA, + CHAR_SEL_CHARACTER_AURA_FROZEN, + CHAR_SEL_CHARACTER_ONLINE, + + CHAR_SEL_CHAR_DEL_INFO_BY_GUID, + CHAR_SEL_CHAR_DEL_INFO_BY_NAME, + CHAR_SEL_CHAR_DEL_INFO, + + CHAR_SEL_CHARS_BY_ACCOUNT_ID, + CHAR_SEL_CHAR_PINFO, + CHAR_SEL_PINFO_BANS, + CHAR_SEL_CHAR_HOMEBIND, + CHAR_SEL_CHAR_GUID_NAME_BY_ACC, + CHAR_SEL_POOL_QUEST_SAVE, + CHAR_SEL_CHARACTER_AT_LOGIN, + CHAR_SEL_CHAR_CLASS_LVL_AT_LOGIN, + CHAR_SEL_INSTANCE, + CHAR_SEL_PET_SPELL_LIST, + CHAR_SEL_CHAR_PET, + CHAR_SEL_CHAR_PETS, + CHAR_SEL_CHAR_COD_ITEM_MAIL, + CHAR_SEL_CHAR_SOCIAL, + CHAR_SEL_PET_AURA, + CHAR_SEL_CHAR_OLD_CHARS, + CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID, + CHAR_SEL_MAIL, + CHAR_SEL_CHAR_PLAYERBYTES2, + CHAR_SEL_PET_SPELL, + CHAR_SEL_PET_SPELL_COOLDOWN, + CHAR_SEL_PET_DECLINED_NAME, + CHAR_SEL_CHAR_GUID_BY_NAME, + CHAR_DEL_CHAR_AURA_FROZEN, + CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM, + CHAR_SEL_MAIL_COUNT_ITEM, + CHAR_SEL_AUCTIONHOUSE_COUNT_ITEM, + CHAR_SEL_GUILD_BANK_COUNT_ITEM, + CHAR_SEL_CHAR_INVENTORY_ITEM_BY_ENTRY, + CHAR_SEL_MAIL_ITEMS_BY_ENTRY, + CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY, + CHAR_SEL_GUILD_BANK_ITEM_BY_ENTRY, + CHAR_SEL_CHAR_PET_BY_ENTRY, + CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT_2, + CHAR_SEL_CHAR_PET_BY_SLOT, + CHAR_DEL_CHAR_ACHIEVEMENT, + CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS, + CHAR_DEL_CHAR_REPUTATION_BY_FACTION, + CHAR_INS_CHAR_REPUTATION_BY_FACTION, + CHAR_UPD_CHAR_ARENA_POINTS, + CHAR_DEL_ITEM_REFUND_INSTANCE, + CHAR_INS_ITEM_REFUND_INSTANCE, + CHAR_DEL_GROUP, + CHAR_DEL_GROUP_MEMBER_ALL, + CHAR_INS_CHAR_GIFT, + CHAR_DEL_INSTANCE_BY_INSTANCE, + CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE, + CHAR_DEL_CHAR_INSTANCE_BY_MAP_DIFF, + CHAR_DEL_GROUP_INSTANCE_BY_MAP_DIFF, + CHAR_DEL_INSTANCE_BY_MAP_DIFF, + CHAR_DEL_MAIL_ITEM_BY_ID, + CHAR_DEL_CHAR_PET_DECLINEDNAME, + CHAR_ADD_CHAR_PET_DECLINEDNAME, + CHAR_UPD_CHAR_PET_NAME, + CHAR_INS_PETITION, + CHAR_DEL_PETITION_BY_GUID, + CHAR_DEL_PETITION_SIGNATURE_BY_GUID, + CHAR_UDP_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID, + CHAR_UDP_CHAR_PET_SLOT_BY_SLOT, + CHAR_UPD_CHAR_PET_SLOT_BY_ID, + CHAR_DEL_CHAR_PET_BY_ID, + CHAR_DEL_CHAR_PET_BY_SLOT, + CHAR_DEL_PET_AURAS, + CHAR_DEL_PET_SPELLS, + CHAR_DEL_PET_SPELL_COOLDOWNS, + CHAR_INS_PET_SPELL_COOLDOWN, + CHAR_DEL_PET_SPELL_BY_SPELL, + CHAR_INS_PET_SPELL, + CHAR_INS_PET_AURA, + CHAR_DEL_CHAR_DECLINED_NAME, + CHAR_INS_CHAR_DECLINED_NAME, + CHAR_UPD_FACTION_OR_RACE, + CHAR_DEL_CHAR_SKILL_LANGUAGES, + CHAR_INS_CHAR_SKILL_LANGUAGE, + CHAR_UPD_CHAR_TAXI_PATH, + CHAR_UPD_CHAR_TAXIMASK, + CHAR_DEL_CHAR_QUESTSTATUS, + CHAR_DEL_CHAR_SOCIAL_BY_GUID, + CHAR_DEL_CHAR_SOCIAL_BY_FRIEND, + CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT, + CHAR_UPD_CHAR_ACHIEVEMENT, + CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE, + CHAR_DEL_CHAR_SPELL_BY_SPELL, + CHAR_UPD_CHAR_SPELL_FACTION_CHANGE, + CHAR_DEL_CHAR_REP_BY_FACTION, + CHAR_UPD_CHAR_REP_FACTION_CHANGE, + CHAR_DEL_CHAR_SPELL_COOLDOWN, + CHAR_DEL_CHARACTER, + CHAR_DEL_CHAR_ACTION, + CHAR_DEL_CHAR_AURA, + CHAR_DEL_CHAR_GIFT, + CHAR_DEL_CHAR_INSTANCE, + CHAR_DEL_CHAR_INVENTORY, + CHAR_DEL_CHAR_QUESTSTATUS_REWARDED, + CHAR_DEL_CHAR_REPUTATION, + CHAR_DEL_CHAR_SPELL, + CHAR_DEL_MAIL, + CHAR_DEL_MAIL_ITEMS, + CHAR_DEL_CHAR_PET_BY_OWNER, + CHAR_DEL_CHAR_PET_DECLINEDNAME_BY_OWNER, + CHAR_DEL_CHAR_ACHIEVEMENTS, + CHAR_DEL_CHAR_EQUIPMENTSETS, + CHAR_DEL_GUILD_EVENTLOG_BY_PLAYER, + CHAR_DEL_GUILD_BANK_EVENTLOG_BY_PLAYER, + CHAR_DEL_CHAR_GLYPHS, + CHAR_DEL_CHAR_QUESTSTATUS_DAILY, + CHAR_DEL_CHAR_TALENT, + CHAR_DEL_CHAR_SKILLS, + CHAR_UDP_CHAR_HONOR_POINTS, + CHAR_UDP_CHAR_ARENA_POINTS, + CHAR_UDP_CHAR_MONEY, + CHAR_INS_CHAR_ACTION, + CHAR_UPD_CHAR_ACTION, + CHAR_DEL_CHAR_ACTION_BY_BUTTON_SPEC, + CHAR_DEL_CHAR_INVENTORY_BY_ITEM, + CHAR_DEL_CHAR_INVENTORY_BY_BAG_SLOT, + CHAR_UPD_MAIL, + CHAR_REP_CHAR_QUESTSTATUS, + CHAR_DEL_CHAR_QUESTSTATUS_BY_QUEST, + CHAR_INS_CHAR_QUESTSTATUS, + CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST, + CHAR_DEL_CHAR_SKILL_BY_SKILL, + CHAR_INS_CHAR_SKILLS, + CHAR_UDP_CHAR_SKILLS, + CHAR_INS_CHAR_SPELL, + CHAR_DEL_CHAR_STATS, + CHAR_INS_CHAR_STATS, + CHAR_DEL_PETITION_BY_OWNER, + CHAR_DEL_PETITION_SIGNATURE_BY_OWNER, + CHAR_DEL_PETITION_BY_OWNER_AND_TYPE, + CHAR_DEL_PETITION_SIGNATURE_BY_OWNER_AND_TYPE, + CHAR_INS_CHAR_GLYPHS, + CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC, + CHAR_INS_CHAR_TALENT, + CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC, + CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, + MAX_CHARACTERDATABASE_STATEMENTS, }; diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index 8ef8d3b48cf..df92c6fa77c 100755 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -22,12 +22,16 @@ void LoginDatabaseConnection::DoPrepareStatements() if (!m_reconnecting) m_stmts.resize(MAX_LOGINDATABASE_STATEMENTS); - PREPARE_STATEMENT(LOGIN_SEL_REALMLIST, "SELECT id, name, address, port, icon, color, timezone, allowedSecurityLevel, population, gamebuild FROM realmlist WHERE color <> 3 ORDER BY name", CONNECTION_SYNCH) + PREPARE_STATEMENT(LOGIN_SEL_REALMLIST, "SELECT id, name, address, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild FROM realmlist WHERE flag <> 3 ORDER BY name", CONNECTION_SYNCH) PREPARE_STATEMENT(LOGIN_DEL_EXPIRED_IP_BANS, "DELETE FROM ip_banned WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC) PREPARE_STATEMENT(LOGIN_UPD_EXPIRED_ACCOUNT_BANS, "UPDATE account_banned SET active = 0 WHERE active = 1 AND unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC) PREPARE_STATEMENT(LOGIN_SEL_IP_BANNED, "SELECT * FROM ip_banned WHERE ip = ?", CONNECTION_SYNCH) PREPARE_STATEMENT(LOGIN_INS_IP_AUTO_BANNED, "INSERT INTO ip_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity realmd', 'Failed login autoban')", CONNECTION_ASYNC) + PREPARE_STATEMENT(LOGIN_SEL_IP_BANNED_ALL, "SELECT ip, bandate, unbandate, bannedby, banreason FROM ip_banned WHERE (bandate = unbandate OR unbandate > UNIX_TIMESTAMP()) ORDER BY unbandate", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_SEL_IP_BANNED_BY_IP, "SELECT ip, bandate, unbandate, bannedby, banreason FROM ip_banned WHERE (bandate = unbandate OR unbandate > UNIX_TIMESTAMP()) AND ip LIKE CONCAT('%%', ?, '%%') ORDER BY unbandate", CONNECTION_SYNCH); PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_BANNED, "SELECT bandate, unbandate FROM account_banned WHERE id = ? AND active = 1", CONNECTION_SYNCH) + PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_BANNED_ALL, "SELECT account.id, username FROM account, account_banned WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_BANNED_BY_USERNAME, "SELECT account.id, username FROM account, account_banned WHERE account.id = account_banned.id AND active = 1 AND username LIKE CONCAT('%%', ?, '%%') GROUP BY account.id", CONNECTION_SYNCH); PREPARE_STATEMENT(LOGIN_INS_ACCOUNT_AUTO_BANNED, "INSERT INTO account_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity realmd', 'Failed login autoban', 1)", CONNECTION_ASYNC) PREPARE_STATEMENT(LOGIN_SEL_SESSIONKEY, "SELECT a.sessionkey, a.id, aa.gmlevel FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE username = ?", CONNECTION_SYNCH) PREPARE_STATEMENT(LOGIN_UPD_VS, "UPDATE account SET v = ?, s = ? WHERE username = ?", CONNECTION_ASYNC) @@ -36,13 +40,18 @@ void LoginDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(LOGIN_UPD_FAILEDLOGINS, "UPDATE account SET failed_logins = failed_logins + 1 WHERE username = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(LOGIN_SEL_FAILEDLOGINS, "SELECT id, failed_logins FROM account WHERE username = ?", CONNECTION_SYNCH) PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_ID_BY_NAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH) + PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_LIST_BY_NAME, "SELECT id, username FROM account WHERE username = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT id, sessionkey, last_ip, locked, v, s, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_LIST_BY_EMAIL, "SELECT id, username FROM account WHERE email = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(LOGIN_SEL_NUM_CHARS_ON_REALM, "SELECT numchars FROM realmcharacters WHERE realmid = ? AND acctid= ?", CONNECTION_SYNCH) - PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_BY_IP, "SELECT id FROM account WHERE last_ip = ?", CONNECTION_SYNCH) + PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_BY_IP, "SELECT id, username FROM account WHERE last_ip = ?", CONNECTION_SYNCH) + PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_BY_ID, "SELECT 1 FROM account WHERE id = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(LOGIN_INS_IP_BANNED, "INSERT INTO ip_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, ?, ?)", CONNECTION_ASYNC) PREPARE_STATEMENT(LOGIN_DEL_IP_NOT_BANNED, "DELETE FROM ip_banned WHERE ip = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(LOGIN_INS_ACCOUNT_BANNED, "INSERT INTO account_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, ?, ?, 1)", CONNECTION_ASYNC) PREPARE_STATEMENT(LOGIN_UPD_ACCOUNT_NOT_BANNED, "UPDATE account_banned SET active = 0 WHERE id = ? AND active != 0", CONNECTION_ASYNC) - PREPARE_STATEMENT(LOGIN_DEL_REALM_CHARACTERS, "DELETE FROM realmcharacters WHERE acctid = ? AND realmid = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(LOGIN_DEL_REALM_CHARACTERS_BY_REALM, "DELETE FROM realmcharacters WHERE acctid = ? AND realmid = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(LOGIN_DEL_REALM_CHARACTERS, "DELETE FROM realmcharacters WHERE acctid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(LOGIN_INS_REALM_CHARACTERS, "INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (?, ?, ?)", CONNECTION_ASYNC) PREPARE_STATEMENT(LOGIN_SEL_SUM_REALM_CHARACTERS, "SELECT SUM(numchars) FROM realmcharacters WHERE acctid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(LOGIN_INS_ACCOUNT, "INSERT INTO account(username, sha_pass_hash, joindate) VALUES(?, ?, NOW())", CONNECTION_ASYNC); @@ -62,4 +71,22 @@ void LoginDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(LOGIN_DEL_ACCOUNT_ACCESS, "DELETE FROM account_access WHERE id = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(LOGIN_DEL_ACCOUNT_ACCESS_BY_REALM, "DELETE FROM account_access WHERE id = ? AND (RealmID = ? OR RealmID = -1)", CONNECTION_ASYNC); PREPARE_STATEMENT(LOGIN_INS_ACCOUNT_ACCESS, "INSERT INTO account_access (id,gmlevel,RealmID) VALUES (?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(LOGIN_GET_ACCOUNT_ID_BY_USERNAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_GET_ACCOUNT_ACCESS_GMLEVEL, "SELECT gmlevel FROM account_access WHERE id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_GET_GMLEVEL_BY_REALMID, "SELECT gmlevel FROM account_access WHERE id = ? AND (RealmID = ? OR RealmID = -1)", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_GET_USERNAME_BY_ID, "SELECT username FROM account WHERE id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_SEL_CHECK_PASSWORD, "SELECT 1 FROM account WHERE id = ? AND sha_pass_hash = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_SEL_CHECK_PASSWORD_BY_NAME, "SELECT 1 FROM account WHERE username = ? AND sha_pass_hash = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_SEL_PINFO, "SELECT a.username, aa.gmlevel, a.email, a.last_ip, DATE_FORMAT(a.last_login, '%Y-%m-%d %T'), a.mutetime FROM account a LEFT JOIN account_access aa ON (a.id = aa.id AND (aa.RealmID = ? OR aa.RealmID = -1)) WHERE a.id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_SEL_PINFO_BANS, "SELECT unbandate, bandate = unbandate, bannedby, banreason FROM account_banned WHERE id = ? AND active ORDER BY bandate ASC LIMIT 1", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_SEL_GM_ACCOUNTS, "SELECT a.username, aa.gmlevel FROM account a, account_access aa WHERE a.id=aa.id AND aa.gmlevel >= ? AND (aa.realmid = -1 OR aa.realmid = ?)", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_INFO, "SELECT a.username, a.last_ip, aa.gmlevel, a.expansion FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_ACCESS_GMLEVEL_TEST, "SELECT 1 FROM account_access WHERE id = ? AND gmlevel > ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_ACCESS, "SELECT a.id, aa.gmlevel, aa.RealmID FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_RECRUITER, "SELECT 1 FROM account WHERE recruiter = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_SEL_BANS, "SELECT 1 FROM account_banned WHERE id = ? AND active = 1 UNION SELECT 1 FROM ip_banned WHERE ip = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_WHOIS, "SELECT username, email, last_ip FROM account WHERE id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_SEL_REALMLIST_SECURITY_LEVEL, "SELECT allowedSecurityLevel from realmlist WHERE id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(LOGIN_DEL_ACCOUNT, "DELETE FROM account WHERE id = ?", CONNECTION_ASYNC); + } diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h index afb188020c7..4ad9ac1a251 100755 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ b/src/server/shared/Database/Implementation/LoginDatabase.h @@ -48,6 +48,8 @@ enum LoginDatabaseStatements LOGIN_SEL_IP_BANNED, LOGIN_INS_IP_AUTO_BANNED, LOGIN_SEL_ACCOUNT_BANNED, + LOGIN_SEL_ACCOUNT_BANNED_ALL, + LOGIN_SEL_ACCOUNT_BANNED_BY_USERNAME, LOGIN_INS_ACCOUNT_AUTO_BANNED, LOGIN_SEL_SESSIONKEY, LOGIN_UPD_VS, @@ -56,12 +58,19 @@ enum LoginDatabaseStatements LOGIN_UPD_FAILEDLOGINS, LOGIN_SEL_FAILEDLOGINS, LOGIN_SEL_ACCOUNT_ID_BY_NAME, + LOGIN_SEL_ACCOUNT_LIST_BY_NAME, + LOGIN_SEL_ACCOUNT_INFO_BY_NAME, + LOGIN_SEL_ACCOUNT_LIST_BY_EMAIL, LOGIN_SEL_NUM_CHARS_ON_REALM, LOGIN_SEL_ACCOUNT_BY_IP, LOGIN_INS_IP_BANNED, LOGIN_DEL_IP_NOT_BANNED, + LOGIN_SEL_IP_BANNED_ALL, + LOGIN_SEL_IP_BANNED_BY_IP, + LOGIN_SEL_ACCOUNT_BY_ID, LOGIN_INS_ACCOUNT_BANNED, LOGIN_UPD_ACCOUNT_NOT_BANNED, + LOGIN_DEL_REALM_CHARACTERS_BY_REALM, LOGIN_DEL_REALM_CHARACTERS, LOGIN_INS_REALM_CHARACTERS, LOGIN_SEL_SUM_REALM_CHARACTERS, @@ -82,6 +91,23 @@ enum LoginDatabaseStatements LOGIN_DEL_ACCOUNT_ACCESS, LOGIN_DEL_ACCOUNT_ACCESS_BY_REALM, LOGIN_INS_ACCOUNT_ACCESS, + LOGIN_GET_ACCOUNT_ID_BY_USERNAME, + LOGIN_GET_ACCOUNT_ACCESS_GMLEVEL, + LOGIN_GET_GMLEVEL_BY_REALMID, + LOGIN_GET_USERNAME_BY_ID, + LOGIN_SEL_CHECK_PASSWORD, + LOGIN_SEL_CHECK_PASSWORD_BY_NAME, + LOGIN_SEL_PINFO, + LOGIN_SEL_PINFO_BANS, + LOGIN_SEL_GM_ACCOUNTS, + LOGIN_SEL_ACCOUNT_INFO, + LOGIN_SEL_ACCOUNT_ACCESS_GMLEVEL_TEST, + LOGIN_SEL_ACCOUNT_ACCESS, + LOGIN_SEL_ACCOUNT_RECRUITER, + LOGIN_SEL_BANS, + LOGIN_SEL_ACCOUNT_WHOIS, + LOGIN_SEL_REALMLIST_SECURITY_LEVEL, + LOGIN_DEL_ACCOUNT, MAX_LOGINDATABASE_STATEMENTS, }; diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp index d9338bec401..e3455891909 100755 --- a/src/server/shared/Database/Implementation/WorldDatabase.cpp +++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp @@ -36,6 +36,7 @@ void WorldDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(WORLD_DEL_GAME_TELE, "DELETE FROM game_tele WHERE name = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_INS_NPC_VENODR, "INSERT INTO npc_vendor (entry, item, maxcount, incrtime, extendedcost) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_DEL_NPC_VENDOR, "DELETE FROM npc_vendor WHERE entry = ? AND item = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(WORLD_SEL_NPC_VENDOR_REF, "SELECT item, maxcount, incrtime, ExtendedCost FROM npc_vendor WHERE entry = ? ORDER BY slot ASC", CONNECTION_SYNCH); PREPARE_STATEMENT(WORLD_UPD_CREATURE_MOVEMENT_TYPE, "UPDATE creature SET MovementType = ? WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_UPD_CREATURE_FACTION, "UPDATE creature_template SET faction_A = ?, faction_H = ? WHERE entry = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_UPD_CREATURE_NPCFLAG, "UPDATE creature_template SET npcflag = ? WHERE entry = ?", CONNECTION_ASYNC); @@ -48,10 +49,23 @@ void WorldDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(WORLD_UPD_WAYPOINT_DATA_POINT, "UPDATE waypoint_data SET point = point - 1 WHERE id = ? AND point > ?", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_UPD_WAYPOINT_DATA_POSITION, "UPDATE waypoint_data SET position_x = ?, position_y = ?, position_z = ? where id = ? AND point = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_UPD_WAYPOINT_DATA_WPGUID, "UPDATE waypoint_data SET wpguid = ? WHERE id = ? and point = ?", CONNECTION_ASYNC); - PREPARE_STATEMENT(WORLD_UPD_ALL_WAYPOINT_DATA_WPGUID, "UPDATE waypoint_data SET wpguid = 0", CONNECTION_ASYNC); + PREPARE_STATEMENT(WORLD_SEL_WAYPOINT_DATA_MAX_ID, "SELECT MAX(id) FROM waypoint_data", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_WAYPOINT_DATA_MAX_POINT, "SELECT MAX(point) FROM waypoint_data WHERE id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_WAYPOINT_DATA_BY_ID, "SELECT point, position_x, position_y, position_z, orientation, move_flag, delay, action, action_chance FROM waypoint_data WHERE id = ? ORDER BY point", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_WAYPOINT_DATA_POS_BY_ID, "SELECT point, position_x, position_y, position_z FROM waypoint_data WHERE id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_WAYPOINT_DATA_POS_FIRST_BY_ID, "SELECT position_x, position_y, position_z FROM waypoint_data WHERE point = 1 AND id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_WAYPOINT_DATA_POS_LAST_BY_ID, "SELECT position_x, position_y, position_z, orientation FROM waypoint_data WHERE id = ? ORDER BY point DESC LIMIT 1", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_WAYPOINT_DATA_BY_WPGUID, "SELECT id, point FROM waypoint_data WHERE wpguid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_WAYPOINT_DATA_ALL_BY_WPGUID, "SELECT id, point, delay, move_flag, action, action_chance FROM waypoint_data WHERE wpguid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_UPD_WAYPOINT_DATA_ALL_WPGUID, "UPDATE waypoint_data SET wpguid = 0", CONNECTION_ASYNC); + PREPARE_STATEMENT(WORLD_SEL_WAYPOINT_DATA_BY_POS, "SELECT id, point FROM waypoint_data WHERE (abs(position_x - ?) <= ?) and (abs(position_y - ?) <= ?) and (abs(position_z - ?) <= ?)", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_WAYPOINT_DATA_WPGUID_BY_ID, "SELECT wpguid FROM waypoint_data WHERE id = ? and wpguid <> 0", CONNECTION_SYNCH); + PREPARE_STATEMENT(WOLRD_SEL_WAYPOINT_DATA_ACTION, "SELECT DISTINCT action FROM waypoint_data", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_WAYPOINT_SCRIPTS_MAX_ID, "SELECT MAX(guid) FROM waypoint_scripts", CONNECTION_SYNCH); PREPARE_STATEMENT(WORLD_INS_CREATURE_ADDON, "INSERT INTO creature_addon(guid, path_id) VALUES (?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_UPD_CREATURE_ADDON_PATH, "UPDATE creature_addon SET path_id = ? WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_DEL_CREATURE_ADDON, "DELETE FROM creature_addon WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(WORLD_SEL_CREATURE_ADDON_BY_GUID, "SELECT guid FROM creature_addon WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(WORLD_INS_WAYPOINT_SCRIPT, "INSERT INTO waypoint_scripts (guid) VALUES (?)", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_DEL_WAYPOINT_SCRIPT, "DELETE FROM waypoint_scripts WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_UPD_WAYPOINT_SCRIPT_ID, "UPDATE waypoint_scripts SET id = ? WHERE guid = ?", CONNECTION_ASYNC); @@ -59,7 +73,19 @@ void WorldDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(WORLD_UPD_WAYPOINT_SCRIPT_Y, "UPDATE waypoint_scripts SET y = ? WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_UPD_WAYPOINT_SCRIPT_Z, "UPDATE waypoint_scripts SET z = ? WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_UPD_WAYPOINT_SCRIPT_O, "UPDATE waypoint_scripts SET o = ? WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID, "SELECT id FROM waypoint_scripts WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(WORLD_DEL_CREATURE, "DELETE FROM creature WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_INS_CREATURE_TRANSPORT, "INSERT INTO creature_transport (guid, npc_entry, transport_entry, TransOffsetX, TransOffsetY, TransOffsetZ, TransOffsetO) values (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_UPD_CREATURE_TRANSPORT_EMOTE, "UPDATE creature_transport SET emote = ? WHERE transport_entry = ? AND guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(WORLD_SEL_COMMANDS, "SELECT name, security, help FROM command", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_CREATURE_TEMPLATE, "SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_IP2NATION_COUNTRY, "SELECT c.country FROM ip2nationCountries c, ip2nation i WHERE i.ip < ? AND c.code = i.country ORDER BY i.ip DESC LIMIT 0,1", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_ITEM_TEMPLATE_BY_NAME, "SELECT entry FROM item_template WHERE name = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_GAMEOBJECT_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM gameobject WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_INS_CREATURE, "INSERT INTO creature (guid, id , map, spawnMask, phaseMask, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint, curhealth, curmana, MovementType, npcflag, unit_flags, dynamicflags) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(WORLD_DEL_GAME_EVENT_CREATURE, "DELETE FROM game_event_creature WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(WORLD_DEL_GAME_EVENT_MODEL_EQUIP, "DELETE FROM game_event_model_equip WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(WORLD_INS_GAMEOBJECT, "INSERT INTO gameobject (guid, id, map, spawnMask, phaseMask, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); } diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h index 1d7cd1151e5..0580cecec7e 100755 --- a/src/server/shared/Database/Implementation/WorldDatabase.h +++ b/src/server/shared/Database/Implementation/WorldDatabase.h @@ -56,6 +56,7 @@ enum WorldDatabaseStatements WORLD_DEL_GAME_TELE, WORLD_INS_NPC_VENODR, WORLD_DEL_NPC_VENDOR, + WORLD_SEL_NPC_VENDOR_REF, WORLD_UPD_CREATURE_MOVEMENT_TYPE, WORLD_UPD_CREATURE_FACTION, WORLD_UPD_CREATURE_NPCFLAG, @@ -68,10 +69,23 @@ enum WorldDatabaseStatements WORLD_UPD_WAYPOINT_DATA_POINT, WORLD_UPD_WAYPOINT_DATA_POSITION, WORLD_UPD_WAYPOINT_DATA_WPGUID, - WORLD_UPD_ALL_WAYPOINT_DATA_WPGUID, + WORLD_UPD_WAYPOINT_DATA_ALL_WPGUID, + WORLD_SEL_WAYPOINT_DATA_MAX_ID, + WORLD_SEL_WAYPOINT_DATA_BY_ID, + WORLD_SEL_WAYPOINT_DATA_POS_BY_ID, + WORLD_SEL_WAYPOINT_DATA_POS_FIRST_BY_ID, + WORLD_SEL_WAYPOINT_DATA_POS_LAST_BY_ID, + WORLD_SEL_WAYPOINT_DATA_BY_WPGUID, + WORLD_SEL_WAYPOINT_DATA_ALL_BY_WPGUID, + WORLD_SEL_WAYPOINT_DATA_MAX_POINT, + WORLD_SEL_WAYPOINT_DATA_BY_POS, + WORLD_SEL_WAYPOINT_DATA_WPGUID_BY_ID, + WOLRD_SEL_WAYPOINT_DATA_ACTION, + WORLD_SEL_WAYPOINT_SCRIPTS_MAX_ID, WORLD_UPD_CREATURE_ADDON_PATH, WORLD_INS_CREATURE_ADDON, WORLD_DEL_CREATURE_ADDON, + WORLD_SEL_CREATURE_ADDON_BY_GUID, WORLD_INS_WAYPOINT_SCRIPT, WORLD_DEL_WAYPOINT_SCRIPT, WORLD_UPD_WAYPOINT_SCRIPT_ID, @@ -79,9 +93,22 @@ enum WorldDatabaseStatements WORLD_UPD_WAYPOINT_SCRIPT_Y, WORLD_UPD_WAYPOINT_SCRIPT_Z, WORLD_UPD_WAYPOINT_SCRIPT_O, + WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID, WORLD_DEL_CREATURE, WORLD_INS_CREATURE_TRANSPORT, WORLD_UPD_CREATURE_TRANSPORT_EMOTE, + WORLD_SEL_COMMANDS, + WORLD_SEL_CREATURE_TEMPLATE, + WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, + WORLD_SEL_IP2NATION_COUNTRY, + WORLD_SEL_ITEM_TEMPLATE_BY_NAME, + WORLD_SEL_CREATURE_BY_ID, + WORLD_SEL_GAMEOBJECT_NEAREST, + WORLD_SEL_GAMEOBJECT_TARGET, + WORLD_INS_CREATURE, + WORLD_DEL_GAME_EVENT_CREATURE, + WORLD_DEL_GAME_EVENT_MODEL_EQUIP, + WORLD_INS_GAMEOBJECT, MAX_WORLDDATABASE_STATEMENTS, }; diff --git a/src/server/shared/Database/MySQLConnection.cpp b/src/server/shared/Database/MySQLConnection.cpp index f686db4c199..7fb4a4f7025 100755 --- a/src/server/shared/Database/MySQLConnection.cpp +++ b/src/server/shared/Database/MySQLConnection.cpp @@ -58,17 +58,13 @@ MySQLConnection::~MySQLConnection() { ASSERT (m_Mysql); /// MySQL context must be present at this point - sLog->outSQLDriver("MySQLConnection::~MySQLConnection()"); for (size_t i = 0; i < m_stmts.size(); ++i) delete m_stmts[i]; for (PreparedStatementMap::const_iterator itr = m_queries.begin(); itr != m_queries.end(); ++itr) - { free((void *)m_queries[itr->first].first); - } mysql_close(m_Mysql); - Unlock(); /// Unlock while we die, how ironic } void MySQLConnection::Close() diff --git a/src/server/shared/Database/PreparedStatement.cpp b/src/server/shared/Database/PreparedStatement.cpp index baeb591ffb1..dd1b85f70a6 100755 --- a/src/server/shared/Database/PreparedStatement.cpp +++ b/src/server/shared/Database/PreparedStatement.cpp @@ -201,6 +201,11 @@ m_bind(NULL) MySQLPreparedStatement::~MySQLPreparedStatement() { ClearParameters(); + if(m_Mstmt->bind_result_done) + { + delete[] m_Mstmt->bind->length; + delete[] m_Mstmt->bind->is_null; + } mysql_stmt_close(m_Mstmt); delete[] m_bind; } diff --git a/src/server/shared/Database/QueryResult.h b/src/server/shared/Database/QueryResult.h index 524532f30ec..e32b16555bc 100755 --- a/src/server/shared/Database/QueryResult.h +++ b/src/server/shared/Database/QueryResult.h @@ -19,7 +19,7 @@ #ifndef QUERYRESULT_H #define QUERYRESULT_H -#include <ace/Refcounted_Auto_Ptr.h> +#include "AutoPtr.h" #include <ace/Thread_Mutex.h> #include "Field.h" @@ -58,7 +58,7 @@ class ResultSet MYSQL_FIELD* _fields; }; -typedef ACE_Refcounted_Auto_Ptr<ResultSet, ACE_Null_Mutex> QueryResult; +typedef Trinity::AutoPtr<ResultSet, ACE_Thread_Mutex> QueryResult; class PreparedResultSet { @@ -103,7 +103,7 @@ class PreparedResultSet }; -typedef ACE_Refcounted_Auto_Ptr<PreparedResultSet, ACE_Null_Mutex> PreparedQueryResult; +typedef Trinity::AutoPtr<PreparedResultSet, ACE_Thread_Mutex> PreparedQueryResult; #endif diff --git a/src/server/shared/Database/Transaction.h b/src/server/shared/Database/Transaction.h index 92002819951..805d48f76cf 100755 --- a/src/server/shared/Database/Transaction.h +++ b/src/server/shared/Database/Transaction.h @@ -47,7 +47,7 @@ class Transaction bool _cleanedUp; }; -typedef ACE_Refcounted_Auto_Ptr<Transaction, ACE_Null_Mutex> SQLTransaction; +typedef Trinity::AutoPtr<Transaction, ACE_Thread_Mutex> SQLTransaction; /*! Low level class*/ class TransactionTask : public SQLOperation diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp index 52ce74be8f8..7bedf9690ca 100755 --- a/src/server/shared/Utilities/Util.cpp +++ b/src/server/shared/Utilities/Util.cpp @@ -19,15 +19,10 @@ #include <iostream> #include "Util.h" #include "utf8.h" -#ifdef USE_SFMT_FOR_RNG #include "SFMT.h" -#else -#include "MersenneTwister.h" -#endif #include <ace/TSS_T.h> #include <ace/INET_Addr.h> -#ifdef USE_SFMT_FOR_RNG typedef ACE_TSS<SFMTRand> SFMTRandTSS; static SFMTRandTSS sfmtRand; @@ -61,41 +56,6 @@ double rand_chance(void) return sfmtRand->Random() * 100.0; } -#else -typedef ACE_TSS<MTRand> MTRandTSS; -static MTRandTSS mtRand; - -int32 irand(int32 min, int32 max) -{ - return int32(mtRand->randInt(max - min)) + min; -} - -uint32 urand(uint32 min, uint32 max) -{ - return mtRand->randInt(max - min) + min; -} - -float frand(float min, float max) -{ - return float(mtRand->randExc(max - min) + min); -} - -int32 rand32() -{ - return mtRand->randInt(); -} - -double rand_norm(void) -{ - return mtRand->randExc(); -} - -double rand_chance(void) -{ - return mtRand->randExc(100.0); -} -#endif - Tokens::Tokens(const std::string &src, const char sep, uint32 vectorReserve) { m_str = new char[src.length() + 1]; diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt index b75dfcfc064..d1419cb0fcb 100644 --- a/src/server/worldserver/CMakeLists.txt +++ b/src/server/worldserver/CMakeLists.txt @@ -134,6 +134,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/game/Weather ${CMAKE_SOURCE_DIR}/src/server/game/World ${CMAKE_SOURCE_DIR}/src/server/authserver/Server + ${CMAKE_SOURCE_DIR}/src/server/authserver/Realms ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/CommandLine ${CMAKE_CURRENT_SOURCE_DIR}/RemoteAccess @@ -201,4 +202,3 @@ if( USE_COREPCH ) add_native_precompiled_header(worldserver ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders/worldPCH) endif() endif() - diff --git a/src/server/worldserver/CommandLine/CliRunnable.cpp b/src/server/worldserver/CommandLine/CliRunnable.cpp index 8e04a9c2f34..0721515ea73 100755 --- a/src/server/worldserver/CommandLine/CliRunnable.cpp +++ b/src/server/worldserver/CommandLine/CliRunnable.cpp @@ -125,29 +125,44 @@ void commandFinished(void*, bool /*success*/) */ bool ChatHandler::GetDeletedCharacterInfoList(DeletedInfoList& foundList, std::string searchString) { - QueryResult resultChar; + PreparedQueryResult result; + PreparedStatement* stmt; if (!searchString.empty()) { // search by GUID if (isNumeric(searchString.c_str())) - resultChar = CharacterDatabase.PQuery("SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL AND guid = %u", uint64(atoi(searchString.c_str()))); + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO_BY_GUID); + + stmt->setUInt32(0, uint32(atoi(searchString.c_str()))); + + result = CharacterDatabase.Query(stmt); + } // search by name else { if (!normalizePlayerName(searchString)) return false; - resultChar = CharacterDatabase.PQuery("SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL AND deleteInfos_Name " _LIKE_ " " _CONCAT3_("'%%'", "'%s'", "'%%'"), searchString.c_str()); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO_BY_NAME); + + stmt->setString(0, searchString); + + result = CharacterDatabase.Query(stmt); } } else - resultChar = CharacterDatabase.Query("SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL"); + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO); + + result = CharacterDatabase.Query(stmt); + } - if (resultChar) + if (result) { do { - Field* fields = resultChar->Fetch(); + Field* fields = result->Fetch(); DeletedInfo info; @@ -161,7 +176,7 @@ bool ChatHandler::GetDeletedCharacterInfoList(DeletedInfoList& foundList, std::s info.deleteDate = time_t(fields[3].GetUInt32()); foundList.push_back(info); - } while (resultChar->NextRow()); + } while (result->NextRow()); } return true; diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index d84cfc1a4a4..f4945e025b0 100755 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -41,6 +41,7 @@ #include "Timer.h" #include "Util.h" #include "AuthSocket.h" +#include "RealmList.h" #include "BigNumber.h" @@ -136,13 +137,6 @@ int Master::Run() sLog->outString(" C O R E /\\___/"); sLog->outString("http://TrinityCore.org \\/__/\n"); -#ifdef USE_SFMT_FOR_RNG - sLog->outString("\n"); - sLog->outString("SFMT has been enabled as the random number generator, if worldserver"); - sLog->outString("freezes or crashes randomly, first, try disabling SFMT in CMAKE configuration"); - sLog->outString("\n"); -#endif //USE_SFMT_FOR_RNG - /// worldserver PID file creation std::string pidfile = ConfigMgr::GetStringDefault("PidFile", ""); if (!pidfile.empty()) @@ -162,7 +156,7 @@ int Master::Run() return 1; // set server offline (not connectable) - LoginDatabase.DirectPExecute("UPDATE realmlist SET color = (color & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmID); + LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmID); ///- Initialize the World sWorld->SetInitialWorldSettings(); @@ -273,7 +267,7 @@ int Master::Run() } // set server online (allow connecting now) - LoginDatabase.DirectPExecute("UPDATE realmlist SET color = color & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID); + LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID); sLog->outString("%s (worldserver-daemon) ready...", _FULLVERSION); sWorldSocketMgr->Wait(); @@ -286,7 +280,7 @@ int Master::Run() } // set server offline - LoginDatabase.DirectPExecute("UPDATE realmlist SET color = color | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID); + LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID); // when the main thread closes the singletons get unloaded // since worldrunnable uses them, it will crash if unloaded after master @@ -294,7 +288,7 @@ int Master::Run() rar_thread.wait(); ///- Clean database before leaving - clearOnlineAccounts(); + ClearOnlineAccounts(); _StopDB(); @@ -454,7 +448,7 @@ bool Master::_StartDB() sLog->SetRealmID(realmID); ///- Clean the database before starting - clearOnlineAccounts(); + ClearOnlineAccounts(); ///- Insert version info into DB WorldDatabase.PExecute("UPDATE version SET core_version = '%s', core_revision = '%s'", _FULLVERSION, _HASH); // One-time query @@ -475,16 +469,14 @@ void Master::_StopDB() } /// Clear 'online' status for all accounts with characters in this realm -void Master::clearOnlineAccounts() +void Master::ClearOnlineAccounts() { - // Cleanup online status for characters hosted at current realm - /// \todo Only accounts with characters logged on *this* realm should have online status reset. Move the online column from 'account' to 'realmcharacters'? - LoginDatabase.DirectPExecute( - "UPDATE account SET online = 0 WHERE online > 0 " - "AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = '%d')", realmID); + // Reset online status for all accounts with characters on the current realm + LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = %d)", realmID); + // Reset online status for all characters CharacterDatabase.DirectExecute("UPDATE characters SET online = 0 WHERE online <> 0"); // Battleground instance ids reset at server restart - CharacterDatabase.DirectExecute(CharacterDatabase.GetPreparedStatement(CHAR_UPD_PLAYERS_BGDATA)); + CharacterDatabase.DirectExecute("UPDATE character_battleground_data SET instanceId = 0"); } diff --git a/src/server/worldserver/Master.h b/src/server/worldserver/Master.h index 17c230ef7c7..548cd02c64a 100755 --- a/src/server/worldserver/Master.h +++ b/src/server/worldserver/Master.h @@ -37,7 +37,7 @@ class Master bool _StartDB(); void _StopDB(); - void clearOnlineAccounts(); + void ClearOnlineAccounts(); }; #define sMaster ACE_Singleton<Master, ACE_Null_Mutex>::instance() diff --git a/src/server/worldserver/RemoteAccess/RASocket.cpp b/src/server/worldserver/RemoteAccess/RASocket.cpp index e5637d282c6..ebc7c7624d9 100755 --- a/src/server/worldserver/RemoteAccess/RASocket.cpp +++ b/src/server/worldserver/RemoteAccess/RASocket.cpp @@ -32,7 +32,7 @@ RASocket::RASocket() { - iMinLevel = ConfigMgr::GetIntDefault("RA.MinLevel", 3); + _minLevel = ConfigMgr::GetIntDefault("RA.MinLevel", 3); } RASocket::~RASocket() @@ -174,12 +174,15 @@ int RASocket::process_command(const std::string& command) int RASocket::check_access_level(const std::string& user) { - std::string safe_user = user; + std::string safeUser = user; + + AccountMgr::normalizeString(safeUser); + - AccountMgr::normalizeString(safe_user); - LoginDatabase.EscapeString(safe_user); - QueryResult result = LoginDatabase.PQuery("SELECT a.id, aa.gmlevel, aa.RealmID FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = '%s'", safe_user.c_str()); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_ACCESS); + stmt->setString(0, safeUser); + PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) { @@ -189,7 +192,7 @@ int RASocket::check_access_level(const std::string& user) Field* fields = result->Fetch(); - if (fields[1].GetUInt32() < iMinLevel) + if (fields[1].GetUInt8() < _minLevel) { sLog->outRemote("User %s has no privilege to login", user.c_str()); return -1; @@ -207,19 +210,20 @@ int RASocket::check_password(const std::string& user, const std::string& pass) { std::string safe_user = user; AccountMgr::normalizeString(safe_user); - LoginDatabase.EscapeString(safe_user); std::string safe_pass = pass; AccountMgr::normalizeString(safe_pass); - LoginDatabase.EscapeString(safe_pass); std::string hash = AccountMgr::CalculateShaPassHash(safe_user, safe_pass); - QueryResult check = LoginDatabase.PQuery( - "SELECT 1 FROM account WHERE username = '%s' AND sha_pass_hash = '%s'", - safe_user.c_str(), hash.c_str()); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_CHECK_PASSWORD_BY_NAME); - if (!check) + stmt->setString(0, safe_user); + stmt->setString(1, hash); + + PreparedQueryResult result = LoginDatabase.Query(stmt); + + if (!result) { sLog->outRemote("Wrong password for user: %s", user.c_str()); return -1; diff --git a/src/server/worldserver/RemoteAccess/RASocket.h b/src/server/worldserver/RemoteAccess/RASocket.h index 1c9b1ac24b5..450245a0ff4 100755 --- a/src/server/worldserver/RemoteAccess/RASocket.h +++ b/src/server/worldserver/RemoteAccess/RASocket.h @@ -56,7 +56,7 @@ class RASocket: public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH> private: /// Minimum security level required to connect - uint8 iMinLevel; + uint8 _minLevel; }; #endif /// @} diff --git a/src/server/worldserver/WorldThread/WorldRunnable.cpp b/src/server/worldserver/WorldThread/WorldRunnable.cpp index 8ea54ca599e..42cfaae41ec 100755 --- a/src/server/worldserver/WorldThread/WorldRunnable.cpp +++ b/src/server/worldserver/WorldThread/WorldRunnable.cpp @@ -30,6 +30,7 @@ #include "MapManager.h" #include "Timer.h" #include "WorldRunnable.h" +#include "OutdoorPvPMgr.h" #define WORLD_SLEEP_CONST 50 @@ -93,4 +94,5 @@ void WorldRunnable::run() sMapMgr->UnloadAll(); // unload all grids (including locked in memory) sObjectAccessor->UnloadAll(); // unload 'i_player2corpse' storage and remove from world sScriptMgr->Unload(); + sOutdoorPvPMgr->Die(); } |
