diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/CharacterHandler.cpp | 2 | ||||
-rw-r--r-- | src/game/Player.cpp | 14 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 2 | ||||
-rw-r--r-- | src/game/Unit.cpp | 4 | ||||
-rw-r--r-- | src/game/WorldSocketMgr.cpp | 1 | ||||
-rw-r--r-- | src/trinityrealm/AuthSocket.cpp | 267 | ||||
-rw-r--r-- | src/trinityrealm/AuthSocket.h | 9 |
7 files changed, 156 insertions, 143 deletions
diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index d86bf7734a0..36e0720a08d 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -61,7 +61,7 @@ bool LoginQueryHolder::Initialize() // NOTE: all fields in `characters` must be read to prevent lost character data at next save in case wrong DB structure. // !!! NOTE: including unused `zone`,`online` - res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, gmstate, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT leaderGuid FROM group_member WHERE memberGuid ='%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid)); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 32413aba503..5aa67b645fd 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -13664,7 +13664,7 @@ float Player::GetFloatValueFromDB(uint16 index, uint64 guid) bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) { //// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [28] [29] 30 31 32 - //QueryResult *result = CharacterDatabase.PQuery("SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, gmstate, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty FROM characters WHERE guid = '%u'", guid); + //QueryResult *result = CharacterDatabase.PQuery("SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extraflags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty FROM characters WHERE guid = '%u'", guid); QueryResult *result = holder->GetResult(PLAYER_LOGIN_QUERY_LOADFROM); if(!result) @@ -13899,7 +13899,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) m_taxi.LoadTaxiMask( fields[11].GetString() ); // must be before InitTaxiNodesForLevel - uint32 gmstate = fields[25].GetUInt32(); + uint32 extraflags = fields[25].GetUInt32(); m_stableSlots = fields[26].GetUInt32(); if(m_stableSlots > 2) @@ -14089,7 +14089,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) case 0: break; // disable case 1: SetGameMaster(true); break; // enable case 2: // save state - if(gmstate & PLAYER_EXTRA_GM_ON) + if(extraflags & PLAYER_EXTRA_GM_ON) SetGameMaster(true); break; } @@ -14100,7 +14100,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) case 0: break; // disable case 1: SetAcceptTicket(true); break; // enable case 2: // save state - if(gmstate & PLAYER_EXTRA_GM_ACCEPT_TICKETS) + if(extraflags & PLAYER_EXTRA_GM_ACCEPT_TICKETS) SetAcceptTicket(true); break; } @@ -14111,7 +14111,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) case 0: break; // disable case 1: SetGMChat(true); break; // enable case 2: // save state - if(gmstate & PLAYER_EXTRA_GM_CHAT) + if(extraflags & PLAYER_EXTRA_GM_CHAT) SetGMChat(true); break; } @@ -14122,7 +14122,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) case 0: break; // disable case 1: SetAcceptWhispers(true); break; // enable case 2: // save state - if(gmstate & PLAYER_EXTRA_ACCEPT_WHISPERS) + if(extraflags & PLAYER_EXTRA_ACCEPT_WHISPERS) SetAcceptWhispers(true); break; } @@ -15109,7 +15109,7 @@ void Player::SaveToDB() "map, dungeon_difficulty, position_x, position_y, position_z, orientation, data, " "taximask, online, cinematic, " "totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, " - "trans_x, trans_y, trans_z, trans_o, transguid, gmstate, stable_slots, at_login, zone, " + "trans_x, trans_y, trans_z, trans_o, transguid, extraflags, stable_slots, at_login, zone, " "death_expire_time, taxi_path) VALUES (" << GetGUIDLow() << ", " << GetSession()->GetAccountId() << ", '" diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 600d9a27cf1..f0c67b66918 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -1953,7 +1953,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) case 43873: // Headless Horseman Laugh if(caster->GetTypeId() == TYPEID_PLAYER) { - ((Player*)caster)->PlaySound(11965, false); + ((Player*)caster)->SendPlaySound(11965, false); } return; case 46354: // Blood Elf Illusion diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 51991c01d2d..24acc4c18f8 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -7764,7 +7764,9 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, // Healing Done // These Spells are doing fixed amount of healing (TODO found less hack-like check) - if(spellProto->Id == 15290 || spellProto->Id == 39373 || spellProto->Id == 33778 || spellProto->Id == 379 || spellProto->Id == 38395) + if (spellProto->Id == 15290 || spellProto->Id == 39373 || + spellProto->Id == 33778 || spellProto->Id == 379 || + spellProto->Id == 38395 || spellProto->Id == 40972) return healamount; diff --git a/src/game/WorldSocketMgr.cpp b/src/game/WorldSocketMgr.cpp index c431bf21b73..7d4a7e84078 100644 --- a/src/game/WorldSocketMgr.cpp +++ b/src/game/WorldSocketMgr.cpp @@ -362,7 +362,6 @@ WorldSocketMgr::OnSocketOpen (WorldSocket* sock) return m_NetThreads[min].AddSocket (sock); - return 0; } WorldSocketMgr* diff --git a/src/trinityrealm/AuthSocket.cpp b/src/trinityrealm/AuthSocket.cpp index b06ac605e4f..4be14a52d30 100644 --- a/src/trinityrealm/AuthSocket.cpp +++ b/src/trinityrealm/AuthSocket.cpp @@ -137,7 +137,7 @@ typedef struct XFER_INIT { uint8 cmd; // XFER_INITIATE uint8 fileNameLen; // strlen(fileName); - uint8 fileName[1]; // fileName[fileNameLen] + uint8 fileName[5]; // fileName[fileNameLen] uint64 file_size; // file size (bytes) uint8 md5[MD5_DIGEST_LENGTH]; // MD5 }XFER_INIT; @@ -217,7 +217,7 @@ AuthSocket::AuthSocket(ISocketHandler &h) : TcpSocket(h) N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); g.SetDword(7); _authed = false; - pPatch=NULL; + pPatch = NULL; _accountSecurityLevel = SEC_PLAYER; } @@ -225,6 +225,7 @@ AuthSocket::AuthSocket(ISocketHandler &h) : TcpSocket(h) /// Close patch file descriptor before leaving AuthSocket::~AuthSocket() { + ZThread::Guard<ZThread::Mutex> g(patcherLock); if(pPatch) fclose(pPatch); } @@ -360,6 +361,7 @@ bool AuthSocket::_HandleLogonChallenge() ByteBuffer pkt; _login = (const char*)ch->I; + _build = ch->build; ///- Normalize account name //utf8ToUpperOnlyLatin(_login); -- client already send account in expected form @@ -369,154 +371,169 @@ bool AuthSocket::_HandleLogonChallenge() _safelogin=_login; dbRealmServer.escape_string(_safelogin); - ///- Check if the client has one of the expected version numbers - bool valid_version=false; - int accepted_versions[]=EXPECTED_TRINITY_CLIENT_BUILD; - for(int i=0;accepted_versions[i];i++) - if(ch->build==accepted_versions[i]) + pkt << (uint8) AUTH_LOGON_CHALLENGE; + pkt << (uint8) 0x00; + + ///- Verify that this IP is not in the ip_banned table + // No SQL injection possible (paste the IP address as passed by the socket) + dbRealmServer.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); + + std::string address = GetRemoteAddress(); + dbRealmServer.escape_string(address); + QueryResult *result = dbRealmServer.PQuery( "SELECT * FROM ip_banned WHERE ip = '%s'",address.c_str()); + if(result) { - valid_version=true; - break; + pkt << (uint8)REALM_AUTH_ACCOUNT_BANNED; + sLog.outBasic("[AuthChallenge] Banned ip %s tries to login!",GetRemoteAddress().c_str ()); + delete result; } - - /// <ul><li> if this is a valid version - if(valid_version) + else { - pkt << (uint8) AUTH_LOGON_CHALLENGE; - pkt << (uint8) 0x00; + ///- Get the account details from the account table + // No SQL injection (escaped user name) - ///- Verify that this IP is not in the ip_banned table - // No SQL injection possible (paste the IP address as passed by the socket) - dbRealmServer.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); - - std::string address = GetRemoteAddress(); - dbRealmServer.escape_string(address); - QueryResult *result = dbRealmServer.PQuery( "SELECT * FROM ip_banned WHERE ip = '%s'",address.c_str()); - if(result) - { - pkt << (uint8)REALM_AUTH_ACCOUNT_BANNED; - sLog.outBasic("[AuthChallenge] Banned ip %s tries to login!",GetRemoteAddress().c_str ()); - delete result; - } - else + result = dbRealmServer.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel FROM account WHERE username = '%s'",_safelogin.c_str ()); + if( result ) { - ///- Get the account details from the account table - // No SQL injection (escaped user name) - - result = dbRealmServer.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel FROM account WHERE username = '%s'",_safelogin.c_str ()); - if( result ) + ///- If the IP is 'locked', check that the player comes indeed from the correct IP address + bool locked = false; + if((*result)[2].GetUInt8() == 1) // if ip is locked { - ///- If the IP is 'locked', check that the player comes indeed from the correct IP address - bool locked = false; - if((*result)[2].GetUInt8() == 1) // if ip is locked + DEBUG_LOG("[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), (*result)[3].GetString()); + DEBUG_LOG("[AuthChallenge] Player address is '%s'", GetRemoteAddress().c_str()); + if ( strcmp((*result)[3].GetString(),GetRemoteAddress().c_str()) ) { - DEBUG_LOG("[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), (*result)[3].GetString()); - DEBUG_LOG("[AuthChallenge] Player address is '%s'", GetRemoteAddress().c_str()); - if ( strcmp((*result)[3].GetString(),GetRemoteAddress().c_str()) ) - { - DEBUG_LOG("[AuthChallenge] Account IP differs"); - pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED; - locked=true; - } - else - { - DEBUG_LOG("[AuthChallenge] Account IP matches"); - } + DEBUG_LOG("[AuthChallenge] Account IP differs"); + pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED; + locked=true; } else { - DEBUG_LOG("[AuthChallenge] Account '%s' is not locked to ip", _login.c_str()); + DEBUG_LOG("[AuthChallenge] Account IP matches"); } + } + else + { + DEBUG_LOG("[AuthChallenge] Account '%s' is not locked to ip", _login.c_str()); + } - if (!locked) + if (!locked) + { + //set expired bans to inactive + dbRealmServer.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); + ///- If the account is banned, reject the logon attempt + QueryResult *banresult = dbRealmServer.PQuery("SELECT bandate,unbandate FROM account_banned WHERE id = %u AND active = 1", (*result)[1].GetUInt32()); + if(banresult) { - //set expired bans to inactive - dbRealmServer.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); - ///- If the account is banned, reject the logon attempt - QueryResult *banresult = dbRealmServer.PQuery("SELECT bandate,unbandate FROM account_banned WHERE id = %u AND active = 1", (*result)[1].GetUInt32()); - if(banresult) + if((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64()) { - if((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64()) - { - pkt << (uint8) REALM_AUTH_ACCOUNT_BANNED; - sLog.outBasic("[AuthChallenge] Banned account %s tries to login!",_login.c_str ()); - } - else - { - pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED; - sLog.outBasic("[AuthChallenge] Temporarily banned account %s tries to login!",_login.c_str ()); - } - - delete banresult; + pkt << (uint8) REALM_AUTH_ACCOUNT_BANNED; + sLog.outBasic("[AuthChallenge] Banned account %s tries to login!",_login.c_str ()); } else { - ///- Get the password from the account table, upper it, and make the SRP6 calculation - std::string rI = (*result)[0].GetCppString(); - _SetVSFields(rI); + pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED; + sLog.outBasic("[AuthChallenge] Temporarily banned account %s tries to login!",_login.c_str ()); + } - b.SetRand(19 * 8); - BigNumber gmod=g.ModExp(b, N); - B = ((v * 3) + gmod) % N; + delete banresult; + } + else + { + ///- Get the password from the account table, upper it, and make the SRP6 calculation + std::string rI = (*result)[0].GetCppString(); + _SetVSFields(rI); - ASSERT(gmod.GetNumBytes() <= 32); + b.SetRand(19 * 8); + BigNumber gmod=g.ModExp(b, N); + B = ((v * 3) + gmod) % N; - BigNumber unk3; - unk3.SetRand(16*8); + ASSERT(gmod.GetNumBytes() <= 32); - ///- Fill the response packet with the result - pkt << (uint8)REALM_AUTH_SUCCESS; + BigNumber unk3; + unk3.SetRand(16*8); - // B may be calculated < 32B so we force minnimal length to 32B - pkt.append(B.AsByteArray(32), 32); // 32 bytes - pkt << (uint8)1; - pkt.append(g.AsByteArray(), 1); - pkt << (uint8)32; - pkt.append(N.AsByteArray(), 32); - pkt.append(s.AsByteArray(), s.GetNumBytes()); // 32 bytes - pkt.append(unk3.AsByteArray(), 16); - pkt << (uint8)0; // Added in 1.12.x client branch + ///- Fill the response packet with the result + pkt << (uint8)REALM_AUTH_SUCCESS; - uint8 secLevel = (*result)[4].GetUInt8(); - _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; + // B may be calculated < 32B so we force minnimal length to 32B + pkt.append(B.AsByteArray(32), 32); // 32 bytes + pkt << (uint8)1; + pkt.append(g.AsByteArray(), 1); + pkt << (uint8)32; + pkt.append(N.AsByteArray(), 32); + pkt.append(s.AsByteArray(), s.GetNumBytes()); // 32 bytes + pkt.append(unk3.AsByteArray(), 16); + pkt << (uint8)0; // Added in 1.12.x client branch - std::string localeName; - localeName.resize(4); - for(int i = 0; i <4; ++i) - localeName[i] = ch->country[4-i-1]; + uint8 secLevel = (*result)[4].GetUInt8(); + _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; - _localization = GetLocaleByName(localeName); + _localizationName.resize(4); + for(int i = 0; i <4; ++i) + _localizationName[i] = ch->country[4-i-1]; - sLog.outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3],ch->country[2],ch->country[1],ch->country[0], _localization); - } + sLog.outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3],ch->country[2],ch->country[1],ch->country[0], GetLocaleByName(_localizationName)); } - delete result; - } - else //no account - { - pkt<< (uint8) REALM_AUTH_NO_MATCH; } + delete result; } - } //valid version - else - ///<li> else + else //no account + { + pkt<< (uint8) REALM_AUTH_NO_MATCH; + } + } + SendBuf((char const*)pkt.contents(), pkt.size()); + return true; +} + +/// Logon Proof command handler +bool AuthSocket::_HandleLogonProof() +{ + DEBUG_LOG("Entering _HandleLogonProof"); + ///- Read the packet + if (ibuf.GetLength() < sizeof(sAuthLogonProof_C)) + return false; + sAuthLogonProof_C lp; + ibuf.Read((char *)&lp, sizeof(sAuthLogonProof_C)); + + ///- Check if the client has one of the expected version numbers + bool valid_version=false; + int accepted_versions[]=EXPECTED_TRINITY_CLIENT_BUILD; + for(int i=0;accepted_versions[i];i++) + { + if(_build==accepted_versions[i]) + { + valid_version=true; + break; + } + } + + /// <ul><li> If the client has no valid version + if(!valid_version) { ///- Check if we have the apropriate patch on the disk - char tmp[64]; + + // 24 = len("./patches/65535enGB.mpq")+1 + char tmp[24]; // No buffer overflow (fixed length of arguments) - sprintf(tmp,"./patches/%d%c%c%c%c.mpq",ch->build,ch->country[3], - ch->country[2],ch->country[1],ch->country[0]); + sprintf(tmp,"./patches/%d%s.mpq",_build, _localizationName.c_str()); // This will be closed at the destruction of the AuthSocket (client deconnection) FILE *pFile=fopen(tmp,"rb"); + if(!pFile) { + ByteBuffer pkt; pkt << (uint8) AUTH_LOGON_CHALLENGE; pkt << (uint8) 0x00; pkt << (uint8) REALM_AUTH_WRONG_BUILD_NUMBER; - DEBUG_LOG("[AuthChallenge] %u is not a valid client version!", ch->build); + DEBUG_LOG("[AuthChallenge] %u is not a valid client version!", _build); DEBUG_LOG("[AuthChallenge] Patch %s not found",tmp); - }else - { //have patch + SendBuf((char const*)pkt.contents(), pkt.size()); + return true; + } + else // have patch + { pPatch=pFile; XFER_INIT xferh; @@ -546,20 +563,6 @@ bool AuthSocket::_HandleLogonChallenge() } } /// </ul> - SendBuf((char const*)pkt.contents(), pkt.size()); - return true; -} - -/// Logon Proof command handler -bool AuthSocket::_HandleLogonProof() -{ - DEBUG_LOG("Entering _HandleLogonProof"); - ///- Read the packet - if (ibuf.GetLength() < sizeof(sAuthLogonProof_C)) - return false; - - sAuthLogonProof_C lp; - ibuf.Read((char *)&lp, sizeof(sAuthLogonProof_C)); ///- Continue the SRP6 calculation based on data received from the client BigNumber A; @@ -638,7 +641,7 @@ bool AuthSocket::_HandleLogonProof() ///- Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account // No SQL injection (escaped user name) and IP address as received by socket const char* K_hex = K.AsHexStr(); - dbRealmServer.PExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = '%u', failed_logins = 0 WHERE username = '%s'", K_hex, GetRemoteAddress().c_str(), _localization, _safelogin.c_str() ); + dbRealmServer.PExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = '%u', failed_logins = 0 WHERE username = '%s'", K_hex, GetRemoteAddress().c_str(), GetLocaleByName(_localizationName), _safelogin.c_str() ); OPENSSL_free((void*)K_hex); ///- Finish SRP6 and send the final result to the client @@ -684,7 +687,7 @@ bool AuthSocket::_HandleLogonProof() if(WrongPassBanType) { uint32 acc_id = fields[0].GetUInt32(); - dbRealmServer.PExecute("INSERT INTO account_banned VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Trinity realm','Failed login autoban',1)", + dbRealmServer.PExecute("INSERT INTO account_banned VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Trinity realmd','Failed login autoban',1)", acc_id, WrongPassBanTime); sLog.outBasic("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times", _login.c_str(), WrongPassBanTime, failed_logins); @@ -693,7 +696,7 @@ bool AuthSocket::_HandleLogonProof() { std::string current_ip = GetRemoteAddress(); dbRealmServer.escape_string(current_ip); - dbRealmServer.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Trinity realm','Failed login autoban')", + dbRealmServer.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Trinity realmd','Failed login autoban')", current_ip.c_str(), WrongPassBanTime); sLog.outBasic("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times", current_ip.c_str(), WrongPassBanTime, _login.c_str(), failed_logins); @@ -850,6 +853,7 @@ PatcherRunnable::PatcherRunnable(class AuthSocket * as) /// Send content of patch file to the client void PatcherRunnable::run() { + ZThread::Guard<ZThread::Mutex> g(mySocket->patcherLock); XFER_DATA_STRUCT xfdata; xfdata.opcode = XFER_DATA; @@ -868,7 +872,7 @@ void PatcherRunnable::run() /// Preload MD5 hashes of existing patch files on server #ifndef _WIN32 -#include <sys/dir.h> +#include <dirent.h> #include <errno.h> void Patcher::LoadPatchesInfo() { @@ -911,10 +915,11 @@ void Patcher::LoadPatchesInfo() if(hFil==INVALID_HANDLE_VALUE) return; //no patches were found - LoadPatchMD5(fil.cFileName); - - while(FindNextFile(hFil,&fil)) + do + { LoadPatchMD5(fil.cFileName); + } + while(FindNextFile(hFil,&fil)); } #endif diff --git a/src/trinityrealm/AuthSocket.h b/src/trinityrealm/AuthSocket.h index b58f1d79eec..ab9c2cf3da9 100644 --- a/src/trinityrealm/AuthSocket.h +++ b/src/trinityrealm/AuthSocket.h @@ -33,6 +33,7 @@ #include "sockets/Utility.h" #include "sockets/Parse.h" #include "sockets/Socket.h" +#include "zthread/Mutex.h" /// Handle login commands class AuthSocket: public TcpSocket @@ -58,6 +59,7 @@ class AuthSocket: public TcpSocket void _SetVSFields(std::string rI); FILE *pPatch; + ZThread::Mutex patcherLock; bool IsLag(); private: @@ -70,7 +72,12 @@ class AuthSocket: public TcpSocket std::string _login; std::string _safelogin; - uint8 _localization; + + + // Since GetLocaleByName() is _NOT_ bijective, we have to store the locale as a string. Otherwise we can't differ + // between enUS and enGB, which is important for the patch system + std::string _localizationName; + uint16 _build; AccountTypes _accountSecurityLevel; }; #endif |