All pastes #1288844 Raw Edit

Unnamed

public text v1 · immutable
#1288844 ·published 2008-12-18 22:37 UTC
rendered paste body
diff --git a/dep/include/mersennetwister/MersenneTwister.h b/dep/include/mersennetwister/MersenneTwister.h
index af91931..ab8d94c 100644
--- a/dep/include/mersennetwister/MersenneTwister.h
+++ b/dep/include/mersennetwister/MersenneTwister.h
@@ -70,69 +70,69 @@ class MTRand {
 // Data
 public:
     typedef ::uint32 uint32;
-	enum { N = 624 };       // length of state vector
-	enum { SAVE = N + 1 };  // length of array for save()
+    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
+    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
+    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
     /* Mangos 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 );
+    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 );
+    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&)
@@ -142,232 +142,232 @@ inline MTRand& MTRand::operator=(const MTRand&)
     { return *this; }
 
 inline MTRand::MTRand( const uint32& oneSeed )
-	{ seed(oneSeed); }
+    { seed(oneSeed); }
 
 inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength )
-	{ seed(bigSeed,seedLength); }
+    { seed(bigSeed,seedLength); }
 
 inline MTRand::MTRand()
-	{ seed(); }
+    { seed(); }
 
 inline double MTRand::rand()
-	{ return double(randInt()) * (1.0/4294967295.0); }
+    { return double(randInt()) * (1.0/4294967295.0); }
 
 inline double MTRand::rand( const double& n )
-	{ return rand() * n; }
+    { return rand() * n; }
 
 inline double MTRand::randExc()
-	{ return double(randInt()) * (1.0/4294967296.0); }
+    { return double(randInt()) * (1.0/4294967296.0); }
 
 inline double MTRand::randExc( const double& n )
-	{ return randExc() * n; }
+    { return randExc() * n; }
 
 inline double MTRand::randDblExc()
-	{ return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
+    { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
 
 inline double MTRand::randDblExc( const double& n )
-	{ return randDblExc() * 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
+    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);
+    // 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) );
+    // 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;
+    // 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();
+    // 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 > seedLength ? N : 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();
+    // 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 > seedLength ? N : 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() ) );
+    // 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++;
-	}
+    // 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;
+    // 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;
+    // 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;
+    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];
+    register uint32 *s = state;
+    register uint32 *la = loadArray;
+    register int i = N;
+    for( ; i--; *s++ = *la++ ) {}
+    left = *la;
+    pNext = &state[N-left];
 }
 
 /* Mangos 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;
+    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;
+    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;
 }
 */
 
diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
index ecde680..e1f0ad5 100644
--- a/src/game/CharacterHandler.cpp
+++ b/src/game/CharacterHandler.cpp
@@ -937,10 +937,14 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)
 
     CharacterDatabase.escape_string(newname);
 
-    CharacterDatabase.AsyncPQuery(&WorldSession::HandleChangePlayerNameOpcodeCallBack, GUID_LOPART(guid), newname, "SELECT guid, at_login, name FROM characters WHERE guid = '%u' XOR name = '%s'", GUID_LOPART(guid), newname.c_str());
+    CharacterDatabase.AsyncPQuery(&WorldSession::HandleChangePlayerNameOpcodeCallBack,
+        GetAccountId(), newname, GUID_LOPART(guid),
+        "SELECT NULL FROM characters WHERE guid = '%d' and account = '%d' and (at_login & 1) = 1 and not exists (SELECT NULL FROM characters WHERE name = 'Timoha2')", 
+        GUID_LOPART(guid), newname.c_str()
+    );
 }
 
-void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uint32 accountId, std::string newname)
+void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uint32 accountId, std::string newname, uint32 guid_low)
 {
     WorldSession * session = sWorld.FindSession(accountId);
     if(!session)
diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h
index 7e20ad4..eca441f 100644
--- a/src/game/WorldSession.h
+++ b/src/game/WorldSession.h
@@ -542,7 +542,7 @@ class MANGOS_DLL_SPEC WorldSession
         void HandleSetActionBar(WorldPacket& recv_data);
 
         void HandleChangePlayerNameOpcode(WorldPacket& recv_data);
-        static void HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uint32 accountId, std::string newname);
+        static void HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uint32 accountId, std::string newname, uint32 guid_low);
         void HandleDeclinedPlayerNameOpcode(WorldPacket& recv_data);
 
         void HandleTotemDestroy(WorldPacket& recv_data);
diff --git a/src/shared/Database/Database.h b/src/shared/Database/Database.h
index a62675c..16fa0e9 100644
--- a/src/shared/Database/Database.h
+++ b/src/shared/Database/Database.h
@@ -55,27 +55,41 @@ class MANGOS_DLL_SPEC Database
         QueryResult* PQuery(const char *format,...) ATTR_PRINTF(2,3);
 
         /// Async queries and query holders, implemented in DatabaseImpl.h
+
+        // Query / member
         template<class Class>
             bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*), const char *sql);
         template<class Class, typename ParamType1>
             bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql);
         template<class Class, typename ParamType1, typename ParamType2>
             bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql);
+        template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
+            bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql);
+        // Query / static
         template<typename ParamType1>
             bool AsyncQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql);
         template<typename ParamType1, typename ParamType2>
             bool AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql);
+        template<typename ParamType1, typename ParamType2, typename ParamType3>
+            bool AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql);
+        // PQuery / member
         template<class Class>
             bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...) ATTR_PRINTF(4,5);
         template<class Class, typename ParamType1>
             bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(5,6);
         template<class Class, typename ParamType1, typename ParamType2>
             bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(5,6);
+        template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
+            bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) ATTR_PRINTF(5,6);
+        // PQuery / static
         template<typename ParamType1>
             bool AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(5,6);
         template<typename ParamType1, typename ParamType2>
             bool AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(5,6);
+        template<typename ParamType1, typename ParamType2, typename ParamType3>
+            bool AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) ATTR_PRINTF(5,6);
         template<class Class>
+        // QueryHolder
             bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*), SqlQueryHolder *holder);
         template<class Class, typename ParamType1>
             bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*, ParamType1), SqlQueryHolder *holder, ParamType1 param1);
diff --git a/src/shared/Database/DatabaseImpl.h b/src/shared/Database/DatabaseImpl.h
index d3eae74..0a150b7 100644
--- a/src/shared/Database/DatabaseImpl.h
+++ b/src/shared/Database/DatabaseImpl.h
@@ -21,84 +21,100 @@
 
 /// Function body definitions for the template function members of the Database class
 
+#define ASYNC_QUERY_BODY(new_sqlquery) \
+    if (!sql) return false; \
+    ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current(); \
+    QueryQueues::iterator itr = m_queryQueues.find(queryThread); \
+    if (itr == m_queryQueues.end()) return false;
+
+#define ASYNC_PQUERY_BODY \
+    if(!format) return false; \
+    \
+    va_list ap; \
+    char szQuery [MAX_QUERY_LEN]; \
+    va_start(ap, format); \
+    int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap ); \
+    va_end(ap); \
+    \
+    if(res==-1) \
+    { \
+        sLog.outError("SQL Query truncated (and not execute) for format: %s",format); \
+        return false; \
+    }
+
+#define ASYNC_DELAYHOLDER_BODY \
+    if (!holder) return false; \
+    ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current(); \
+    QueryQueues::iterator itr = m_queryQueues.find(queryThread); \
+    if (itr == m_queryQueues.end()) return false;
+
+// -- Query / member --
+
 template<class Class>
 bool
 Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*), const char *sql)
 {
-    if (!sql) return false;
-    ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current();
-    QueryQueues::iterator itr = m_queryQueues.find(queryThread);
-    if (itr == m_queryQueues.end()) return false;
-    m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class>(object, method), itr->second));
-    return true;
+    ASYNC_QUERY_BODY
+    return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class>(object, method), itr->second));
 }
 
 template<class Class, typename ParamType1>
 bool
 Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql)
 {
-    if (!sql) return false;
-    ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current();
-    QueryQueues::iterator itr = m_queryQueues.find(queryThread);
-    if (itr == m_queryQueues.end()) return false;
-    m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class, ParamType1>(object, method, (QueryResult*)NULL, param1), itr->second));
-    return true;
+    ASYNC_QUERY_BODY
+    return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class, ParamType1>(object, method, (QueryResult*)NULL, param1), itr->second));
 }
 
 template<class Class, typename ParamType1, typename ParamType2>
 bool
 Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql)
 {
-    if (!sql) return false;
-    ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current();
-    QueryQueues::iterator itr = m_queryQueues.find(queryThread);
-    if (itr == m_queryQueues.end()) return false;
-    m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class, ParamType1, ParamType2>(object, method, (QueryResult*)NULL, param1, param2), itr->second));
-    return true;
+    ASYNC_QUERY_BODY
+    return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class, ParamType1, ParamType2>(object, method, (QueryResult*)NULL, param1, param2), itr->second));
+}
+
+template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
+bool
+Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql)
+{
+    ASYNC_QUERY_BODY
+    return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class, ParamType1, ParamType2, ParamType3>(object, method, (QueryResult*)NULL, param1, param2, param3), itr->second));
 }
 
+// -- Query / static -- 
+
 template<typename ParamType1>
 bool
 Database::AsyncQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql)
 {
-    if (!sql) return false;
-    ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current();
-    QueryQueues::iterator itr = m_queryQueues.find(queryThread);
-    if (itr == m_queryQueues.end()) return false;
-    m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback<ParamType1>(method, (QueryResult*)NULL, param1), itr->second));
-    return true;
+    ASYNC_QUERY_BODY
+    return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback<ParamType1>(method, (QueryResult*)NULL, param1), itr->second));
 }
 
 template<typename ParamType1, typename ParamType2>
 bool
 Database::AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql)
 {
-    if (!sql) return false;
-    ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current();
-    QueryQueues::iterator itr = m_queryQueues.find(queryThread);
-    if (itr == m_queryQueues.end()) return false;
-    m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback<ParamType1, ParamType2>(method, (QueryResult*)NULL, param1, param2), itr->second));
-    return true;
+    ASYNC_QUERY_BODY
+    return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback<ParamType1, ParamType2>(method, (QueryResult*)NULL, param1, param2), itr->second));
 }
 
-template<class Class>
+template<typename ParamType1, typename ParamType2, typename ParamType3>
 bool
-Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...)
+Database::AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql)
 {
-    if(!format) return false;
+    ASYNC_QUERY_BODY
+    return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback<ParamType1, ParamType2, ParamType3>(method, (QueryResult*)NULL, param1, param2, param3), itr->second));
+}
 
-    va_list ap;
-    char szQuery [MAX_QUERY_LEN];
-    va_start(ap, format);
-    int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap );
-    va_end(ap);
-
-    if(res==-1)
-    {
-        sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
-        return false;
-    }
+// -- PQuery / member --
 
+template<class Class>
+bool
+Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...)
+{
+    ASYNC_PQUERY_BODY
     return AsyncQuery(object, method, szQuery);
 }
 
@@ -106,20 +122,7 @@ template<class Class, typename ParamType1>
 bool
 Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...)
 {
-    if(!format) return false;
-
-    va_list ap;
-    char szQuery [MAX_QUERY_LEN];
-    va_start(ap, format);
-    int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap );
-    va_end(ap);
-
-    if(res==-1)
-    {
-        sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
-        return false;
-    }
-
+    ASYNC_PQUERY_BODY
     return AsyncQuery(object, method, param1, szQuery);
 }
 
@@ -127,41 +130,25 @@ template<class Class, typename ParamType1, typename ParamType2>
 bool
 Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...)
 {
-    if(!format) return false;
-
-    va_list ap;
-    char szQuery [MAX_QUERY_LEN];
-    va_start(ap, format);
-    int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap );
-    va_end(ap);
-
-    if(res==-1)
-    {
-        sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
-        return false;
-    }
-
+    ASYNC_PQUERY_BODY
     return AsyncQuery(object, method, param1, param2, szQuery);
 }
 
-template<typename ParamType1>
+template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
 bool
-Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...)
+Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...)
 {
-    if(!format) return false;
+    ASYNC_PQUERY_BODY
+    return AsyncQuery(object, method, param1, param2, param3, szQuery);
+}
 
-    va_list ap;
-    char szQuery [MAX_QUERY_LEN];
-    va_start(ap, format);
-    int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap );
-    va_end(ap);
-
-    if(res==-1)
-    {
-        sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
-        return false;
-    }
+// -- PQuery / static --
 
+template<typename ParamType1>
+bool
+Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...)
+{
+    ASYNC_PQUERY_BODY
     return AsyncQuery(method, param1, szQuery);
 }
 
@@ -169,43 +156,32 @@ template<typename ParamType1, typename ParamType2>
 bool
 Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...)
 {
-    if(!format) return false;
-
-    va_list ap;
-    char szQuery [MAX_QUERY_LEN];
-    va_start(ap, format);
-    int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap );
-    va_end(ap);
-
-    if(res==-1)
-    {
-        sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
-        return false;
-    }
-
+    ASYNC_PQUERY_BODY
     return AsyncQuery(method, param1, param2, szQuery);
 }
 
+template<typename ParamType1, typename ParamType2, typename ParamType3>
+bool
+Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...)
+{
+    ASYNC_PQUERY_BODY
+    return AsyncQuery(method, param1, param2, param3, szQuery);
+}
+
+// -- QueryHolder --
+
 template<class Class>
 bool
 Database::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*), SqlQueryHolder *holder)
 {
-    if (!holder) return false;
-    ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current();
-    QueryQueues::iterator itr = m_queryQueues.find(queryThread);
-    if (itr == m_queryQueues.end()) return false;
-    holder->Execute(new MaNGOS::QueryCallback<Class, SqlQueryHolder*>(object, method, (QueryResult*)NULL, holder), m_threadBody, itr->second);
-    return true;
+    ASYNC_DELAYHOLDER_BODY
+    return holder->Execute(new MaNGOS::QueryCallback<Class, SqlQueryHolder*>(object, method, (QueryResult*)NULL, holder), m_threadBody, itr->second);
 }
 
 template<class Class, typename ParamType1>
 bool
 Database::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*, ParamType1), SqlQueryHolder *holder, ParamType1 param1)
 {
-    if (!holder) return false;
-    ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current();
-    QueryQueues::iterator itr = m_queryQueues.find(queryThread);
-    if (itr == m_queryQueues.end()) return false;
-    holder->Execute(new MaNGOS::QueryCallback<Class, SqlQueryHolder*, ParamType1>(object, method, (QueryResult*)NULL, holder, param1), m_threadBody, itr->second);
-    return true;
+    ASYNC_DELAYHOLDER_BODY
+    return holder->Execute(new MaNGOS::QueryCallback<Class, SqlQueryHolder*, ParamType1>(object, method, (QueryResult*)NULL, holder, param1), m_threadBody, itr->second);
 }
diff --git a/src/shared/Database/SqlDelayThread.h b/src/shared/Database/SqlDelayThread.h
index d80098d..7d3187a 100644
--- a/src/shared/Database/SqlDelayThread.h
+++ b/src/shared/Database/SqlDelayThread.h
@@ -40,7 +40,7 @@ class SqlDelayThread : public ZThread::Runnable
         SqlDelayThread(Database* db);
 
         ///< Put sql statement to delay queue
-        inline void Delay(SqlOperation* sql) { m_sqlQueue.add(sql); }
+        inline bool Delay(SqlOperation* sql) { m_sqlQueue.add(sql); return true; }
 
         virtual void Stop();                                ///< Stop event
         virtual void run();                                 ///< Main Thread loop
diff --git a/src/shared/Database/SqlOperations.cpp b/src/shared/Database/SqlOperations.cpp
index bc75c59..70a1ff0 100644
--- a/src/shared/Database/SqlOperations.cpp
+++ b/src/shared/Database/SqlOperations.cpp
@@ -79,15 +79,16 @@ void SqlResultQueue::Update()
     }
 }
 
-void SqlQueryHolder::Execute(MaNGOS::IQueryCallback * callback, SqlDelayThread *thread, SqlResultQueue *queue)
+bool SqlQueryHolder::Execute(MaNGOS::IQueryCallback * callback, SqlDelayThread *thread, SqlResultQueue *queue)
 {
     if(!callback || !thread || !queue)
-        return;
+        return false;
 
     /// delay the execution of the queries, sync them with the delay thread
     /// which will in turn resync on execution (via the queue) and call back
     SqlQueryHolderEx *holderEx = new SqlQueryHolderEx(this, callback, queue);
     thread->Delay(holderEx);
+    return true;
 }
 
 bool SqlQueryHolder::SetQuery(size_t index, const char *sql)
diff --git a/src/shared/Database/SqlOperations.h b/src/shared/Database/SqlOperations.h
index a5aa911..41ae69e 100644
--- a/src/shared/Database/SqlOperations.h
+++ b/src/shared/Database/SqlOperations.h
@@ -104,7 +104,7 @@ class SqlQueryHolder
         void SetSize(size_t size);
         QueryResult* GetResult(size_t index);
         void SetResult(size_t index, QueryResult *result);
-        void Execute(MaNGOS::IQueryCallback * callback, SqlDelayThread *thread, SqlResultQueue *queue);
+        bool Execute(MaNGOS::IQueryCallback * callback, SqlDelayThread *thread, SqlResultQueue *queue);
 };
 
 class SqlQueryHolderEx : public SqlOperation
diff --git a/win/VC90/shared.vcproj b/win/VC90/shared.vcproj
index 3254e55..5f8c07a 100644
--- a/win/VC90/shared.vcproj
+++ b/win/VC90/shared.vcproj
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="9,00"
+	Version="9.00"
 	Name="shared"
 	ProjectGUID="{90297C34-F231-4DF4-848E-A74BCC0E40ED}"
 	RootNamespace="shared"
@@ -211,7 +211,7 @@
 				AdditionalOptions="/MP"
 				Optimization="0"
 				AdditionalIncludeDirectories="..\..\dep\include;..\..\dep\include\g3dlite;..\..\src\framework;..\..\src\shared;..\..\dep\ACE_wrappers"
-				PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
+				PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;DO_POSTGRESQL"
 				BasicRuntimeChecks="3"
 				RuntimeLibrary="3"
 				EnableFunctionLevelLinking="true"
@@ -373,6 +373,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\shared\Database\DatabasePostgre.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\shared\Database\DatabasePostgre.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\shared\Database\DatabaseSqlite.cpp"
 				>
 			</File>
@@ -393,6 +401,30 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\shared\Database\MySQLPreparedStatement.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\shared\Database\MySQLPreparedStatement.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\shared\Database\PGSQLPreparedStatement.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\shared\Database\PGSQLPreparedStatement.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\shared\Database\PreparedStatement.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\shared\Database\PreparedStatement.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\shared\Database\QueryResult.h"
 				>
 			</File>
@@ -405,6 +437,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\shared\Database\QueryResultPostgre.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\shared\Database\QueryResultPostgre.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\shared\Database\QueryResultSqlite.cpp"
 				>
 			</File>