Beispiel #1
0
void WorldSession::SaveTutorialsData()
{
    static SqlStatementID updTutorial ;
    static SqlStatementID insTutorial ;

    switch(m_tutorialState)
    {
    case TUTORIALDATA_CHANGED:
    {
        SqlStatement stmt = CharacterDatabase.CreateStatement(updTutorial, "UPDATE character_tutorial SET tut0=?, tut1=?, tut2=?, tut3=?, tut4=?, tut5=?, tut6=?, tut7=? WHERE account = ?");
        for (int i = 0; i < 8; ++i)
            stmt.addUInt32(m_Tutorials[i]);

        stmt.addUInt32(GetAccountId());
        stmt.Execute();
    }
    break;

    case TUTORIALDATA_NEW:
    {
        SqlStatement stmt = CharacterDatabase.CreateStatement(insTutorial, "INSERT INTO character_tutorial (account,tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");

        stmt.addUInt32(GetAccountId());
        for (int i = 0; i < 8; ++i)
            stmt.addUInt32(m_Tutorials[i]);

        stmt.Execute();
    }
    break;
    case TUTORIALDATA_UNCHANGED:
        break;
    }

    m_tutorialState = TUTORIALDATA_UNCHANGED;
}
Beispiel #2
0
void Corpse::SaveToDB()
{
    // prevent DB data inconsistence problems and duplicates
    RealmDataDatabase.BeginTransaction();
    DeleteFromDB();

    static SqlStatementID saveCorpse;
    SqlStatement stmt = RealmDataDatabase.CreateStatement(saveCorpse, "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,data,time,corpse_type,instance) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");

    stmt.addUInt64(GetGUIDLow());
    stmt.addUInt64(GUID_LOPART(GetOwnerGUID()));
    stmt.addFloat(GetPositionX());
    stmt.addFloat(GetPositionY());
    stmt.addFloat(GetPositionZ());
    stmt.addFloat(GetOrientation());
    stmt.addUInt32(GetZoneId());
    stmt.addUInt32(GetMapId());
    stmt.addString(GetUInt32ValuesString());
    stmt.addUInt64(m_time);
    stmt.addUInt32(GetType());
    stmt.addInt32(GetInstanceId());

    stmt.Execute();
    RealmDataDatabase.CommitTransaction();
}
Beispiel #3
0
void GuildFinderMgr::RemoveAllMembershipRequestsFromPlayer(uint32 playerId)
{
    CharacterDatabase.BeginTransaction();

    for (MembershipRequestStore::iterator itr = m_membershipRequests.begin(); itr != m_membershipRequests.end(); ++itr)
    {
        std::vector<MembershipRequest>::iterator itr2 = itr->second.begin();
        for(; itr2 != itr->second.end(); ++itr2)
            if (itr2->GetPlayerGuid() == playerId)
                break;

        if (itr2 == itr->second.end())
            continue;

        static SqlStatementID deleteFinderApplicant;
        CharacterDatabase.BeginTransaction();
        SqlStatement stmt = CharacterDatabase.CreateStatement(deleteFinderApplicant, "DELETE FROM guild_finder_applicant WHERE guildId = ? AND playerGuid = ?");
        stmt.addUInt32(itr2->GetGuildId());
        stmt.addUInt32(itr2->GetPlayerGuid());
        stmt.Execute();
        CharacterDatabase.CommitTransaction();

        itr->second.erase(itr2);

        // Notify the guild master and officers the list changed
        if (Guild* guild = sGuildMgr.GetGuildById(itr->first))
            SendApplicantListUpdate(*guild);
    }

    CharacterDatabase.CommitTransaction();
}
Beispiel #4
0
void GuildFinderMgr::RemoveMembershipRequest(uint32 playerId, uint32 guildId)
{
    std::vector<MembershipRequest>::iterator itr = m_membershipRequests[guildId].begin();
    for(; itr != m_membershipRequests[guildId].end(); ++itr)
        if (itr->GetPlayerGuid() == playerId)
            break;

    if (itr == m_membershipRequests[guildId].end())
        return;

    static SqlStatementID deleteFinderApplicant;
    SqlStatement stmt = CharacterDatabase.CreateStatement(deleteFinderApplicant, "DELETE FROM guild_finder_applicant WHERE guildId = ? AND playerGuid = ?");
    stmt.addUInt32(itr->GetGuildId());
    stmt.addUInt32(itr->GetPlayerGuid());
    stmt.Execute();

    m_membershipRequests[guildId].erase(itr);

    // Notify the applicant his submittion has been removed
    if (Player* player = sObjectAccessor.FindPlayer(ObjectGuid(HIGHGUID_PLAYER, playerId)))
        SendMembershipRequestListUpdate(*player);

    // Notify the guild master and officers the list changed
    if (Guild* guild = sGuildMgr.GetGuildById(guildId))
        SendApplicantListUpdate(*guild);
}
Beispiel #5
0
void GuildFinderMgr::AddMembershipRequest(uint32 guildGuid, MembershipRequest const& request)
{
    m_membershipRequests[guildGuid].push_back(request);

    static SqlStatementID insertFinderApplicant;
    CharacterDatabase.BeginTransaction();
    SqlStatement stmt = CharacterDatabase.CreateStatement(insertFinderApplicant, "REPLACE INTO guild_finder_applicant (guildId, playerGuid, availability, classRole, interests, comment, submitTime) VALUES(?, ?, ?, ?, ?, ?, ?)");
    stmt.addUInt32(request.GetGuildId());
    stmt.addUInt32(request.GetPlayerGuid());
    stmt.addUInt8(request.GetAvailability());
    stmt.addUInt8(request.GetClassRoles());
    stmt.addUInt8(request.GetInterests());
    stmt.addString(request.GetComment());
    stmt.addUInt32(request.GetSubmitTime());
    stmt.Execute();
    CharacterDatabase.CommitTransaction();

    // Notify the applicant his submittion has been added
    if (Player* player = sObjectAccessor.FindPlayer(ObjectGuid(HIGHGUID_PLAYER, request.GetPlayerGuid())))
        SendMembershipRequestListUpdate(*player);

    // Notify the guild master and officers the list changed
    if (Guild* guild = sGuildMgr.GetGuildById(guildGuid))
        SendApplicantListUpdate(*guild);
}
Beispiel #6
0
void InstanceData::SaveToDB()
{
    std::string data = GetSaveData();
    if (data.empty())
        return;

    static SqlStatementID updateInstance;

    SqlStatement stmt = RealmDataDatabase.CreateStatement(updateInstance, "UPDATE instance SET data = ? WHERE id = ?");
    stmt.addString(data);
    stmt.addUInt32(instance->GetInstanceId());
    stmt.Execute();
}
Beispiel #7
0
void Antispam::logSpam(MessageBlock& messageBlock, std::string const& reason)
{
    if (!LogsDatabase || !sWorld.getConfig(CONFIG_BOOL_LOGSDB_CHAT))
        return;

    static SqlStatementID insLogSpam;
    SqlStatement logStmt = LogsDatabase.CreateStatement(insLogSpam,
        "INSERT INTO logs_spamdetect SET accountId=?, guid=?, message=?, reason=?");
    logStmt.addUInt32(messageBlock.fromAccount);
    logStmt.addUInt32(messageBlock.fromGuid.GetCounter());
    logStmt.addString(messageBlock.msg);
    logStmt.addString(reason);
    logStmt.Execute();
}
Beispiel #8
0
void GuildFinderMgr::SetGuildSettings(uint32 guildGuid, LFGuildSettings const& settings)
{
    m_guildSettings[guildGuid] = settings;

    static SqlStatementID replaceGuildFinderSettings;
    SqlStatement stmt = CharacterDatabase.CreateStatement(replaceGuildFinderSettings, "REPLACE INTO guild_finder_guild_settings (guildId, availability, classRoles, interests, level, listed, comment) VALUES(?, ?, ?, ?, ?, ?, ?)");
    stmt.addUInt32(settings.GetGuid());
    stmt.addUInt8(settings.GetAvailability());
    stmt.addUInt8(settings.GetClassRoles());
    stmt.addUInt8(settings.GetInterests());
    stmt.addUInt8(settings.GetLevel());
    stmt.addUInt8(settings.IsListed());
    stmt.addString(settings.GetComment());
    stmt.Execute();
}
Beispiel #9
0
void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResultAutoPtr result, uint32 accountId, std::string newname)
{
    WorldSession * session = sWorld.FindSession(accountId);
    if (!session)
        return;

    if (!result)
    {
        WorldPacket data(SMSG_CHAR_RENAME, 1);
        data << uint8(CHAR_CREATE_ERROR);
        session->SendPacket(&data);
        return;
    }

    uint32 guidLow = result->Fetch()[0].GetUInt32();
    uint64 guid = MAKE_NEW_GUID(guidLow, 0, HIGHGUID_PLAYER);
    std::string oldname = result->Fetch()[1].GetCppString();

    static SqlStatementID changeCharName;
    static SqlStatementID deleteDeclinedName;

    RealmDataDatabase.BeginTransaction();

    SqlStatement stmt = RealmDataDatabase.CreateStatement(changeCharName, "UPDATE characters set name = ?, at_login = at_login & ~ ? WHERE guid = ?");
    stmt.addString(newname);
    stmt.addUInt32(uint32(AT_LOGIN_RENAME));
    stmt.addUInt32(guidLow);
    stmt.Execute();

    stmt = RealmDataDatabase.CreateStatement(deleteDeclinedName, "DELETE FROM character_declinedname WHERE guid = ?");
    stmt.PExecute(guidLow);

    RealmDataDatabase.CommitTransaction();

    sLog.outLog(LOG_CHAR, "Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", session->GetAccountId(), session->GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str());

    WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newname.size()+1));
    data << uint8(RESPONSE_SUCCESS);
    data << uint64(guid);
    data << newname;
    session->SendPacket(&data);
}
Beispiel #10
0
void GuildFinderMgr::DeleteGuild(uint32 guildId)
{
    std::vector<MembershipRequest>::iterator itr = m_membershipRequests[guildId].begin();
    while (itr != m_membershipRequests[guildId].end())
    {
        uint32 applicant = itr->GetPlayerGuid();

        CharacterDatabase.BeginTransaction();

        static SqlStatementID deleteFinderApplicant;
        static SqlStatementID deleteGuildFinderSettings;
        SqlStatement stmt = CharacterDatabase.CreateStatement(deleteFinderApplicant, "DELETE FROM guild_finder_applicant WHERE guildId = ? AND playerGuid = ?");
        stmt.addUInt32(itr->GetGuildId());
        stmt.addUInt32(itr->GetPlayerGuid());
        stmt.Execute();

        SqlStatement stmt2 = CharacterDatabase.CreateStatement(deleteGuildFinderSettings, "DELETE FROM guild_finder_guild_settings WHERE guildId = ?");
        stmt2.addUInt32(itr->GetGuildId());
        stmt2.Execute();

        CharacterDatabase.CommitTransaction();

        m_membershipRequests[guildId].erase(itr);

        // Notify the applicant his submition has been removed
        if (Player* player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, applicant)))
            SendMembershipRequestListUpdate(*player);
    }

    m_membershipRequests.erase(guildId);
    m_guildSettings.erase(guildId);

    // Notify the guild master the list changed (even if he's not a GM any more, not sure if needed)
    if (Guild* guild = sGuildMgr.GetGuildById(guildId))
        SendApplicantListUpdate(*guild);
}
Beispiel #11
0
bool Item::LoadFromDB(uint32 guidLow, Field *fields, ObjectGuid ownerGuid)
{
    // create item before any checks for store correct guid
    // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB
    Object::_Create(ObjectGuid(HIGHGUID_ITEM, guidLow));

    if (!LoadValues(fields[0].GetString()))
    {
        sLog.outError("Item #%d have broken data in `data` field. Can't be loaded.", guidLow);
        return false;
    }

    SetText(fields[1].GetCppString());

    bool need_save = false;                                 // need explicit save data at load fixes

    // overwrite possible wrong/corrupted guid
    ObjectGuid new_item_guid = ObjectGuid(HIGHGUID_ITEM, guidLow);
    if (GetGuidValue(OBJECT_FIELD_GUID) != new_item_guid)
    {
        SetGuidValue(OBJECT_FIELD_GUID, new_item_guid);
        need_save = true;
    }

    ItemPrototype const* proto = GetProto();
    if(!proto)
        return false;

    // update max durability (and durability) if need
    if(proto->MaxDurability!= GetUInt32Value(ITEM_FIELD_MAXDURABILITY))
    {
        SetUInt32Value(ITEM_FIELD_MAXDURABILITY,proto->MaxDurability);
        if(GetUInt32Value(ITEM_FIELD_DURABILITY) > proto->MaxDurability)
            SetUInt32Value(ITEM_FIELD_DURABILITY,proto->MaxDurability);

        need_save = true;
    }

    // recalculate suffix factor
    if(GetItemRandomPropertyId() < 0)
    {
        if(UpdateItemSuffixFactor())
            need_save = true;
    }

    // Remove bind flag for items vs NO_BIND set
    if (IsSoulBound() && proto->Bonding == NO_BIND)
    {
        ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_BINDED, false);
        need_save = true;
    }

    // update duration if need, and remove if not need
    if ((proto->Duration == 0) != (GetUInt32Value(ITEM_FIELD_DURATION) == 0))
    {
        SetUInt32Value(ITEM_FIELD_DURATION, proto->Duration);
        need_save = true;
    }

    // set correct owner
    if (!ownerGuid.IsEmpty() && GetOwnerGuid() != ownerGuid)
    {
        SetOwnerGuid(ownerGuid);
        need_save = true;
    }

    // set correct wrapped state
    if (HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED))
    {
        // wrapped item must be wrapper (used version that not stackable)
        if (!(proto->Flags & ITEM_FLAG_WRAPPER) || GetMaxStackCount() > 1)
        {
            RemoveFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED);
            need_save = true;

            static SqlStatementID delGifts ;

            // also cleanup for sure gift table
            SqlStatement stmt = CharacterDatabase.CreateStatement(delGifts, "DELETE FROM character_gifts WHERE item_guid = ?");
            stmt.PExecute(GetGUIDLow());
        }
    }

    if (need_save)                                          // normal item changed state set not work at loading
    {
        static SqlStatementID updItem ;

        SqlStatement stmt = CharacterDatabase.CreateStatement(updItem, "UPDATE item_instance SET data = ?, owner_guid = ? WHERE guid = ?");

        std::ostringstream ss;
        for(uint16 i = 0; i < m_valuesCount; ++i )
            ss << GetUInt32Value(i) << " ";

        stmt.addString(ss);
        stmt.addUInt32(GetOwnerGuid().GetCounter());
        stmt.addUInt32(guidLow);
        stmt.Execute();
    }

    return true;
}
Beispiel #12
0
void Item::SaveToDB()
{
    uint32 guid = GetGUIDLow();
    switch (uState)
    {
        case ITEM_NEW:
        {
            static SqlStatementID delItem ;
            static SqlStatementID insItem ;

            SqlStatement stmt = CharacterDatabase.CreateStatement(delItem, "DELETE FROM item_instance WHERE guid = ?");
            stmt.PExecute(guid);

            std::ostringstream ss;
            for (uint16 i = 0; i < m_valuesCount; ++i)
                ss << GetUInt32Value(i) << " ";

            stmt = CharacterDatabase.CreateStatement(insItem, "INSERT INTO item_instance (guid,owner_guid,data) VALUES (?, ?, ?)");
            stmt.PExecute(guid, GetOwnerGuid().GetCounter(), ss.str().c_str());
        } break;
        case ITEM_CHANGED:
        {
            static SqlStatementID updInstance ;
            static SqlStatementID updGifts ;

            SqlStatement stmt = CharacterDatabase.CreateStatement(updInstance, "UPDATE item_instance SET data = ?, owner_guid = ? WHERE guid = ?");

            std::ostringstream ss;
            for (uint16 i = 0; i < m_valuesCount; ++i)
                ss << GetUInt32Value(i) << " ";

            stmt.PExecute(ss.str().c_str(), GetOwnerGuid().GetCounter(), guid);

            if (HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED))
            {
                stmt = CharacterDatabase.CreateStatement(updGifts, "UPDATE character_gifts SET guid = ? WHERE item_guid = ?");
                stmt.PExecute(GetOwnerGuid().GetCounter(), GetGUIDLow());
            }
        } break;
        case ITEM_REMOVED:
        {
            static SqlStatementID delItemText;
            static SqlStatementID delInst ;
            static SqlStatementID delGifts ;
            static SqlStatementID delLoot ;

            if (uint32 item_text_id = GetUInt32Value(ITEM_FIELD_ITEM_TEXT_ID))
            {
                SqlStatement stmt = CharacterDatabase.CreateStatement(delItemText, "DELETE FROM item_text WHERE id = ?");
                stmt.PExecute(item_text_id);
            }

            SqlStatement stmt = CharacterDatabase.CreateStatement(delInst, "DELETE FROM item_instance WHERE guid = ?");
            stmt.PExecute(guid);

            if (HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED))
            {
                stmt = CharacterDatabase.CreateStatement(delGifts, "DELETE FROM character_gifts WHERE item_guid = ?");
                stmt.PExecute(GetGUIDLow());
            }

            if (HasSavedLoot())
            {
                stmt = CharacterDatabase.CreateStatement(delLoot, "DELETE FROM item_loot WHERE guid = ?");
                stmt.PExecute(GetGUIDLow());
            }

            delete this;
            return;
        }
        case ITEM_UNCHANGED:
            return;
    }

    if (m_lootState == ITEM_LOOT_CHANGED || m_lootState == ITEM_LOOT_REMOVED)
    {
        static SqlStatementID delLoot ;

        SqlStatement stmt = CharacterDatabase.CreateStatement(delLoot, "DELETE FROM item_loot WHERE guid = ?");
        stmt.PExecute(GetGUIDLow());
    }

    if (loot && (m_lootState == ITEM_LOOT_NEW || m_lootState == ITEM_LOOT_CHANGED))
    {
        if (Player* owner = GetOwner())
        {
            static SqlStatementID saveGold ;
            static SqlStatementID saveLoot ;

            // save money as 0 itemid data
            if (loot->GetGoldAmount())
            {
                SqlStatement stmt = CharacterDatabase.CreateStatement(saveGold, "INSERT INTO item_loot (guid,owner_guid,itemid,amount,property) VALUES (?, ?, 0, ?, 0)");
                stmt.PExecute(GetGUIDLow(), owner->GetGUIDLow(), loot->GetGoldAmount());
            }

            SqlStatement stmt = CharacterDatabase.CreateStatement(saveLoot, "INSERT INTO item_loot (guid,owner_guid,itemid,amount,property) VALUES (?, ?, ?, ?, ?)");

            // save items and quest items (at load its all will added as normal, but this not important for item loot case)
            LootItemList lootList;
            loot->GetLootItemsListFor(owner, lootList);
            for (LootItemList::const_iterator lootItr = lootList.begin(); lootItr != lootList.end(); ++lootItr)
            {
                LootItem* lootItem = *lootItr;
                stmt.addUInt32(GetGUIDLow());
                stmt.addUInt32(owner->GetGUIDLow());
                stmt.addUInt32(lootItem->itemId);
                stmt.addUInt8(lootItem->count);
                stmt.addInt32(lootItem->randomPropertyId);

                stmt.Execute();
            }
        }
    }

    if (m_lootState != ITEM_LOOT_NONE && m_lootState != ITEM_LOOT_TEMPORARY)
        SetLootState(ITEM_LOOT_UNCHANGED);

    SetState(ITEM_UNCHANGED);
}
Beispiel #13
0
bool PlayerLogger::SaveToDB(PlayerLogMask mask, bool removeSaved, bool insideTransaction)
{
    bool written = false;
    uint64 serverStart = uint64(sWorld.GetStartTime());
    for (uint8 i = 0; i < MAX_PLAYER_LOG_ENTITIES; ++i)
    {
        if ((mask & CalcLogMask(PlayerLogEntity(i))) == 0 || data[i] == NULL)
            continue;

        if (!insideTransaction)
            CharacterDatabase.BeginTransaction();
        written = true;
        for (uint8 id = 0; id < data[i]->size(); ++id)
        {
            switch (PlayerLogEntity(i))
            {
            case PLAYER_LOG_DAMAGE_GET:
                {
                PlayerLogDamage info = *(PlayerLogDamage*)(&data[i]->at(id));
                static SqlStatementID dmgGetStmt;
                SqlStatement stmt = CharacterDatabase.CreateStatement(dmgGetStmt, "INSERT INTO playerlog_damage_get SET guid = ?, `time` = ?, aggressor = ?, isPlayer = ?, damage = ?, spell = ?");
                stmt.addUInt32(playerGuid);
                stmt.addUInt64(info.timestamp + serverStart);
                stmt.addUInt32(info.GetId());
                stmt.addBool(info.IsPlayer());
                stmt.addInt32(info.damage);
                stmt.addUInt16(info.spell);
                stmt.Execute();
                }
                break;
            case PLAYER_LOG_DAMAGE_DONE:
                {
                PlayerLogDamage info = *(PlayerLogDamage*)(&data[i]->at(id));
                static SqlStatementID dmgDoneStmt;
                SqlStatement stmt = CharacterDatabase.CreateStatement(dmgDoneStmt, "INSERT INTO playerlog_damage_done SET guid = ?, `time` = ?, victim = ?, isPlayer = ?, damage = ?, spell = ?");
                stmt.addUInt32(playerGuid);
                stmt.addUInt64(info.timestamp + serverStart);
                stmt.addUInt32(info.GetId());
                stmt.addBool(info.IsPlayer());
                stmt.addInt32(info.damage);
                stmt.addUInt16(info.spell);
                stmt.Execute();
                }
                break;
            case PLAYER_LOG_LOOTING:
                {
                PlayerLogLooting info = *(PlayerLogLooting*)(&data[i]->at(id));
                static SqlStatementID lootStmt;
                SqlStatement stmt = CharacterDatabase.CreateStatement(lootStmt, "INSERT INTO playerlog_looting SET guid = ?, `time`= ?, item = ?, sourceType = ?, sourceEntry = ?");
                stmt.addUInt32(playerGuid);
                stmt.addUInt64(info.timestamp + serverStart);
                stmt.addUInt32(info.GetItemEntry());
                stmt.addUInt8(uint8(info.GetLootSourceType()));
                stmt.addUInt32(info.droppedBy);
                stmt.Execute();
                }
                break;
            case PLAYER_LOG_TRADE:
                {
                PlayerLogTrading info = *(PlayerLogTrading*)(&data[i]->at(id));
                static SqlStatementID tradeStmt;
                SqlStatement stmt = CharacterDatabase.CreateStatement(tradeStmt, "INSERT INTO playerlog_trading SET guid = ?, `time`= ?, itemEntry = ?, itemGuid = ?, aquired = ?, partner = ?");
                stmt.addUInt32(playerGuid);
                stmt.addUInt64(info.timestamp + serverStart);
                stmt.addUInt32(info.GetItemEntry());
                stmt.addUInt32(info.itemGuid);
                stmt.addBool(info.IsItemAquired());
                stmt.addUInt16(info.partner);
                stmt.Execute();
                }
                break;
            case PLAYER_LOG_KILL:
                {
                PlayerLogKilling info = *(PlayerLogKilling*)(&data[i]->at(id));
                static SqlStatementID killStmt;
                SqlStatement stmt = CharacterDatabase.CreateStatement(killStmt, "INSERT INTO playerlog_killing SET guid = ?, `time`= ?, iskill = ?, entry = ?, victimGuid = ?");
                stmt.addUInt32(playerGuid);
                stmt.addUInt64(info.timestamp + serverStart);
                stmt.addBool(info.IsKill());
                stmt.addUInt32(info.GetUnitEntry());
                stmt.addUInt32(info.unitGuid);
                stmt.Execute();
                }
                break;
            case PLAYER_LOG_POSITION:
                {
                PlayerLogPosition info = *(PlayerLogPosition*)(&data[i]->at(id));
                static SqlStatementID posStmt;
                SqlStatement stmt = CharacterDatabase.CreateStatement(posStmt, "INSERT INTO playerlog_position SET guid = ?, `time`= ?, map = ?, posx = ?, posy = ?, posz = ?");
                stmt.addUInt32(playerGuid);
                stmt.addUInt64(info.timestamp + serverStart);
                stmt.addUInt16(info.map);
                stmt.addFloat(info.x);
                stmt.addFloat(info.y);
                stmt.addFloat(info.z);
                stmt.Execute();
                }
                break;
            case PLAYER_LOG_PROGRESS:
                {
                PlayerLogProgress info = *(PlayerLogProgress*)(&data[i]->at(id));
                static SqlStatementID progStmt;
                SqlStatement stmt = CharacterDatabase.CreateStatement(progStmt, "INSERT INTO playerlog_progress SET guid = ?, `time` = ?, type = ?, level = ?, data = ?, map = ?, posx = ?, posy = ?, posz = ?");
                stmt.addUInt32(playerGuid);
                stmt.addUInt64(info.timestamp + serverStart);
                stmt.addUInt8(info.progressType);
                stmt.addUInt8(info.level);
                stmt.addUInt16(info.data);
                stmt.addUInt16(info.map);
                stmt.addFloat(info.x);
                stmt.addFloat(info.y);
                stmt.addFloat(info.z);
                stmt.Execute();
                }
            }
        }
        Stop(PlayerLogEntity(i));
        if (removeSaved)
            data[i]->clear();
    }
    if (written && !insideTransaction)
        CharacterDatabase.CommitTransaction();

    return written;
}
Beispiel #14
0
void WorldSession::HandleDeclinedPlayerNameOpcode(WorldPacket& recv_data)
{
    uint64 guid;

    CHECK_PACKET_SIZE(recv_data, 8);
    recv_data >> guid;

    // not accept declined names for unsupported languages
    std::string name;
    if (!sObjectMgr.GetPlayerNameByGUID(guid, name))
    {
        WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);
        data << uint32(1);
        data << uint64(guid);
        SendPacket(&data);
        return;
    }

    std::wstring wname;
    if (!Utf8toWStr(name, wname))
    {
        WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);
        data << uint32(1);
        data << uint64(guid);
        SendPacket(&data);
        return;
    }

    if (!isCyrillicCharacter(wname[0]))                      // name already stored as only single alphabet using
    {
        WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);
        data << uint32(1);
        data << uint64(guid);
        SendPacket(&data);
        return;
    }

    std::string name2;
    DeclinedName declinedname;

    CHECK_PACKET_SIZE(recv_data, recv_data.rpos() + 1);
    recv_data >> name2;

    if (name2 != name)                                       // character have different name
    {
        WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);
        data << uint32(1);
        data << uint64(guid);
        SendPacket(&data);
        return;
    }

    for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
    {
        CHECK_PACKET_SIZE(recv_data, recv_data.rpos() + 1);
        recv_data >> declinedname.name[i];
        if (!normalizePlayerName(declinedname.name[i]))
        {
            WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);
            data << uint32(1);
            data << uint64(guid);
            SendPacket(&data);
            return;
        }
    }

    if (!ObjectMgr::CheckDeclinedNames(GetMainPartOfName(wname, 0), declinedname))
    {
        WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);
        data << uint32(1);
        data << uint64(guid);
        SendPacket(&data);
        return;
    }

    static SqlStatementID deleteDeclinedName;
    static SqlStatementID insertDeclinedName;

    RealmDataDatabase.BeginTransaction();

    SqlStatement stmt = RealmDataDatabase.CreateStatement(deleteDeclinedName, "DELETE FROM character_declinedname WHERE guid = ?");
    stmt.PExecute(GUID_LOPART(guid));

    stmt = RealmDataDatabase.CreateStatement(insertDeclinedName, "INSERT INTO character_declinedname (guid, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?)");
    stmt.addUInt32(GUID_LOPART(guid));
    stmt.addString(declinedname.name[0]);
    stmt.addString(declinedname.name[1]);
    stmt.addString(declinedname.name[2]);
    stmt.addString(declinedname.name[3]);
    stmt.addString(declinedname.name[4]);
    stmt.Execute();

    RealmDataDatabase.CommitTransaction();

    WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);
    data << uint32(0);                                      // OK
    data << uint64(guid);
    SendPacket(&data);
}
Beispiel #15
0
void WorldSession::HandleCharCreateOpcode(WorldPacket & recv_data)
{
    CHECK_PACKET_SIZE(recv_data, 1+1+1+1+1+1+1+1+1+1);

    std::string name;
    uint8 race_, class_;

    recv_data >> name;

    // recheck with known string size
    CHECK_PACKET_SIZE(recv_data, (name.size()+1)+1+1+1+1+1+1+1+1+1);

    recv_data >> race_;
    recv_data >> class_;

    WorldPacket data(SMSG_CHAR_CREATE, 1);                  // returned with diff.values in all cases

    if (!HasPermissions(PERM_GMT))
    {
        if (uint32 mask = sWorld.getConfig(CONFIG_CHARACTERS_CREATING_DISABLED))
        {
            bool disabled = false;

            uint32 team = Player::TeamForRace(race_);
            switch (team)
            {
                case ALLIANCE: disabled = mask & (1<<0); break;
                case HORDE:    disabled = mask & (1<<1); break;
            }

            if (disabled)
            {
                data << uint8(CHAR_CREATE_DISABLED);
                SendPacket(&data);
                return;
            }
        }
    }

    ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_);
    ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race_);

    if (!classEntry || !raceEntry)
    {
        data << uint8(CHAR_CREATE_FAILED);
        SendPacket(&data);
        sLog.outLog(LOG_DEFAULT, "ERROR: Class: %u or Race %u not found in DBC (Wrong DBC files?) or Cheater?", class_, race_);
        return;
    }

    // prevent character creating Expansion race without Expansion account
    if (raceEntry->addon > Expansion())
    {
        data << uint8(CHAR_CREATE_EXPANSION);
        sLog.outLog(LOG_DEFAULT, "ERROR: Expansion %u account:[%d] tried to Create character with expansion %u race (%u)",Expansion(),GetAccountId(),raceEntry->addon,race_);
        SendPacket(&data);
        return;
    }

    // prevent character creating Expansion class without Expansion account
    // TODO: use possible addon field in ChrClassesEntry in next dbc version
    if (Expansion() < 2 && class_ == CLASS_DEATH_KNIGHT)
    {
        data << uint8(CHAR_CREATE_EXPANSION);
        sLog.outLog(LOG_DEFAULT, "ERROR: Not Expansion 2 account:[%d] but tried to Create character with expansion 2 class (%u)",GetAccountId(),class_);
        SendPacket(&data);
        return;
    }

    // prevent character creating with invalid name
    if (!normalizePlayerName(name))
    {
        data << uint8(CHAR_NAME_INVALID_CHARACTER);
        SendPacket(&data);
        sLog.outLog(LOG_DEFAULT, "ERROR: Account:[%d] but tried to Create character with empty [name] ",GetAccountId());
        return;
    }

    // check name limitations
    if (!ObjectMgr::IsValidName(name,true))
    {
        data << uint8(CHAR_NAME_INVALID_CHARACTER);
        SendPacket(&data);
        return;
    }

    if (!HasPermissions(PERM_GMT) && sObjectMgr.IsReservedName(name))
    {
        data << uint8(CHAR_NAME_RESERVED);
        SendPacket(&data);
        return;
    }

    if (sObjectMgr.GetPlayerGUIDByName(name))
    {
        data << uint8(CHAR_CREATE_NAME_IN_USE);
        SendPacket(&data);
        return;
    }

    QueryResultAutoPtr resultacct = AccountsDatabase.PQuery("SELECT SUM(characters_count) FROM realm_characters WHERE account_id = '%u'", GetAccountId());
    if (resultacct)
    {
        Field *fields=resultacct->Fetch();
        uint32 acctcharcount = fields[0].GetUInt32();

        if (acctcharcount >= sWorld.getConfig(CONFIG_CHARACTERS_PER_ACCOUNT))
        {
            data << uint8(CHAR_CREATE_ACCOUNT_LIMIT);
            SendPacket(&data);
            return;
        }
    }

    QueryResultAutoPtr result = RealmDataDatabase.PQuery("SELECT COUNT(guid) FROM characters WHERE account = '%u'", GetAccountId());
    uint8 charcount = 0;
    if (result)
    {
        Field *fields=result->Fetch();
        charcount = fields[0].GetUInt8();

        if (charcount >= sWorld.getConfig(CONFIG_CHARACTERS_PER_REALM))
        {
            data << uint8(CHAR_CREATE_SERVER_LIMIT);
            SendPacket(&data);
            return;
        }
    }

    bool AllowTwoSideAccounts = !sWorld.IsPvPRealm() || sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || HasPermissions(PERM_GMT);
    uint32 skipCinematics = sWorld.getConfig(CONFIG_SKIP_CINEMATICS);

    bool have_same_race = false;
    if (!AllowTwoSideAccounts || skipCinematics == 1)
    {
        QueryResultAutoPtr result2 = RealmDataDatabase.PQuery("SELECT DISTINCT race FROM characters WHERE account = '%u' %s", GetAccountId(),skipCinematics == 1 ? "" : "LIMIT 1");
        if (result2)
        {
            uint32 team_= Player::TeamForRace(race_);

            Field* field = result2->Fetch();
            uint8 race = field[0].GetUInt32();

            // need to check team only for first character
            // TODO: what to if account already has characters of both races?
            if (!AllowTwoSideAccounts)
            {
                uint32 team=0;
                if (race > 0)
                    team = Player::TeamForRace(race);

                if (team != team_)
                {
                    data << uint8(CHAR_CREATE_PVP_TEAMS_VIOLATION);
                    SendPacket(&data);
                    return;
                }
            }

            if (skipCinematics == 1)
            {
                // TODO: check if cinematic already shown? (already logged in?; cinematic field)
                while (race_ != race && result2->NextRow())
                {
                    field = result2->Fetch();
                    race = field[0].GetUInt32();
                }
                have_same_race = race_ == race;
            }
        }
    }

    // extract other data required for player creating
    uint8 gender, skin, face, hairStyle, hairColor, facialHair, outfitId;
    recv_data >> gender >> skin >> face;
    recv_data >> hairStyle >> hairColor >> facialHair >> outfitId;

    Player * pNewChar = new Player(this);
    if (!pNewChar->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_PLAYER), name, race_, class_, gender, skin, face, hairStyle, hairColor, facialHair, outfitId))
    {
        // Player not create (race/class problem?)
        delete pNewChar;

        data << uint8(CHAR_CREATE_ERROR);
        SendPacket(&data);

        return;
    }

    if ((have_same_race && skipCinematics == 1) || skipCinematics == 2)
        pNewChar->setCinematic(true);                       // not show intro

    // Player created, save it now
    pNewChar->SaveToDB();
    charcount += 1;

    // direct to be sure that character count has proper value (also should fix possible multi char create in some cases)
    static SqlStatementID updateRealmChars;
    SqlStatement stmt = AccountsDatabase.CreateStatement(updateRealmChars, "UPDATE realm_characters SET characters_count = ? WHERE account_id = ? AND realm_id = ?");
    stmt.addUInt8(charcount);
    stmt.addUInt32(GetAccountId());
    stmt.addUInt32(realmID);
    stmt.Execute();

    delete pNewChar;                                        // created only to call SaveToDB()

    data << uint8(CHAR_CREATE_SUCCESS);
    SendPacket(&data);

    std::string IP_str = GetRemoteAddress();
    sLog.outDetail("Account: %d (IP: %s) Create Character:[%s]",GetAccountId(),IP_str.c_str(),name.c_str());
    sLog.outLog(LOG_CHAR, "Account: %d (IP: %s) Create Character:[%s]",GetAccountId(),IP_str.c_str(),name.c_str());
}
Beispiel #16
0
void Item::SaveToDB()
{
    uint32 guid = GetGUIDLow();

    switch(m_state)
    {
        case ITEM_NEW:
        {
            DeleteFromDB(guid);

            std::ostringstream ss;
            for (uint16 i = 0; i < m_valuesCount; ++i)
                ss << GetUInt32Value(i) << " ";

            static SqlStatementID insItem;
            SqlStatement stmt = CharacterDatabase.CreateStatement(insItem, "INSERT INTO item_instance (guid, owner_guid, data, text) VALUES (?, ?, ?, ?)");
            stmt.PExecute(guid, GetOwnerGuid().GetCounter(), ss.str().c_str(), m_text.c_str());

            break;
        }
        case ITEM_CHANGED:
        {
            std::ostringstream ss;
            for (uint16 i = 0; i < m_valuesCount; ++i)
                ss << GetUInt32Value(i) << " ";

            static SqlStatementID updInstance;
            SqlStatement stmt = CharacterDatabase.CreateStatement(updInstance, "UPDATE item_instance SET data = ?, owner_guid = ?, text = ? WHERE guid = ?");
            stmt.PExecute(ss.str().c_str(), GetOwnerGuid().GetCounter(), m_text.c_str(), guid);

            if (HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED))
            {
                static SqlStatementID updGifts;
                stmt = CharacterDatabase.CreateStatement(updGifts, "UPDATE character_gifts SET guid = ? WHERE item_guid = ?");
                stmt.PExecute(GetOwnerGuid().GetCounter(), GetGUIDLow());
            }

            break;
        }
        case ITEM_REMOVED:
        {
            DeleteFromDB(guid);

            if (HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED))
                DeleteGiftsFromDB();

            if (HasSavedLoot())
                DeleteLootFromDB();

            if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE))
                DeleteRefundDataFromDB();

            if (HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_BOP_TRADEABLE))
                DeleteSoulboundTradeableFromDB();

            delete this;
            return;
        }
        case ITEM_UNCHANGED:
            return;
    }

    if (m_lootState == ITEM_LOOT_CHANGED || m_lootState == ITEM_LOOT_REMOVED)
        DeleteLootFromDB();

    if (m_lootState == ITEM_LOOT_NEW || m_lootState == ITEM_LOOT_CHANGED)
    {
        if (Player* owner = GetOwner())
        {
            // save money as 0 itemid data
            if (loot.gold)
            {
                static SqlStatementID saveGold;
                SqlStatement stmt = CharacterDatabase.CreateStatement(saveGold, "INSERT INTO item_loot (guid, owner_guid, itemid, amount, suffix, property) VALUES (?, ?, 0, ?, 0, 0)");
                stmt.PExecute(GetGUIDLow(), owner->GetGUIDLow(), loot.gold);
            }

            static SqlStatementID saveLoot;
            SqlStatement stmt = CharacterDatabase.CreateStatement(saveLoot, "INSERT INTO item_loot (guid, owner_guid, itemid, amount, suffix, property) VALUES (?, ?, ?, ?, ?, ?)");

            // save items and quest items (at load its all will added as normal, but this not important for item loot case)
            for (size_t i = 0; i < loot.GetMaxSlotInLootFor(owner); ++i)
            {
                QuestItem* qitem = NULL;

                LootItem* item = loot.LootItemInSlot(i, owner, &qitem);
                if (!item)
                    continue;

                // questitems use the blocked field for other purposes
                if (!qitem && item->is_blocked)
                    continue;

                stmt.addUInt32(GetGUIDLow());
                stmt.addUInt32(owner->GetGUIDLow());
                stmt.addUInt32(item->itemid);
                stmt.addUInt8(item->count);
                stmt.addUInt32(item->randomSuffix);
                stmt.addInt32(item->randomPropertyId);
                stmt.Execute();
            }
        }
    }

    if (m_lootState != ITEM_LOOT_NONE && m_lootState != ITEM_LOOT_TEMPORARY)
        SetLootState(ITEM_LOOT_UNCHANGED);

    SetState(ITEM_UNCHANGED);
}
/// Logon Proof command handler
bool AuthSocket::_HandleLogonProof()
{
    DEBUG_LOG("Entering _HandleLogonProof");
    ///- Read the packet
    sAuthLogonProof_C lp;
    if(!recv((char *)&lp, sizeof(sAuthLogonProof_C)))
        return false;

    ///- Check if the client has one of the expected version numbers
    bool valid_version = FindBuildInfo(_build) != NULL;

    /// <ul><li> If the client has no valid version
    if(!valid_version)
    {
        if (this->patch_ != ACE_INVALID_HANDLE)
            return false;

        ///- Check if we have the apropriate patch on the disk
        // file looks like: 65535enGB.mpq
        char tmp[64];

        snprintf(tmp, 24, "./patches/%d%s.mpq", _build, _localizationName.c_str());

        char filename[PATH_MAX];
        if (ACE_OS::realpath(tmp, filename) != NULL)
        {
            patch_ = ACE_OS::open(filename, GENERIC_READ | FILE_FLAG_SEQUENTIAL_SCAN);
        }

        if (patch_ == ACE_INVALID_HANDLE)
        {
            // no patch found
            ByteBuffer pkt;
            pkt << (uint8) CMD_AUTH_LOGON_CHALLENGE;
            pkt << (uint8) 0x00;
            pkt << (uint8) WOW_FAIL_VERSION_INVALID;
            DEBUG_LOG("[AuthChallenge] %u is not a valid client version!", _build);
            DEBUG_LOG("[AuthChallenge] Patch %s not found", tmp);
            send((char const*)pkt.contents(), pkt.size());
            return true;
        }

        XFER_INIT xferh;

        ACE_OFF_T file_size = ACE_OS::filesize(this->patch_);

        if (file_size == -1)
        {
            close_connection();
            return false;
        }

        if (!PatchCache::instance()->GetHash(tmp, (uint8*)&xferh.md5))
        {
            // calculate patch md5, happens if patch was added while realmd was running
            PatchCache::instance()->LoadPatchMD5(tmp);
            PatchCache::instance()->GetHash(tmp, (uint8*)&xferh.md5);
        }

        uint8 data[2] = { CMD_AUTH_LOGON_PROOF, WOW_FAIL_VERSION_UPDATE};
        send((const char*)data, sizeof(data));

        memcpy(&xferh, "0\x05Patch", 7);
        xferh.cmd = CMD_XFER_INITIATE;
        xferh.file_size = file_size;

        send((const char*)&xferh, sizeof(xferh));
        return true;
    }
    /// </ul>

    ///- Continue the SRP6 calculation based on data received from the client
    BigNumber A;

    A.SetBinary(lp.A, 32);

    // SRP safeguard: abort if A==0
    if (A.isZero())
        return false;

    Sha1Hash sha;
    sha.UpdateBigNumbers(&A, &B, NULL);
    sha.Finalize();
    BigNumber u;
    u.SetBinary(sha.GetDigest(), 20);
    BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N);

    uint8 t[32];
    uint8 t1[16];
    uint8 vK[40];
    memcpy(t, S.AsByteArray(32), 32);
    for (int i = 0; i < 16; ++i)
    {
        t1[i] = t[i * 2];
    }
    sha.Initialize();
    sha.UpdateData(t1, 16);
    sha.Finalize();
    for (int i = 0; i < 20; ++i)
    {
        vK[i * 2] = sha.GetDigest()[i];
    }
    for (int i = 0; i < 16; ++i)
    {
        t1[i] = t[i * 2 + 1];
    }
    sha.Initialize();
    sha.UpdateData(t1, 16);
    sha.Finalize();
    for (int i = 0; i < 20; ++i)
    {
        vK[i * 2 + 1] = sha.GetDigest()[i];
    }
    K.SetBinary(vK, 40);

    uint8 hash[20];

    sha.Initialize();
    sha.UpdateBigNumbers(&N, NULL);
    sha.Finalize();
    memcpy(hash, sha.GetDigest(), 20);
    sha.Initialize();
    sha.UpdateBigNumbers(&g, NULL);
    sha.Finalize();
    for (int i = 0; i < 20; ++i)
    {
        hash[i] ^= sha.GetDigest()[i];
    }
    BigNumber t3;
    t3.SetBinary(hash, 20);

    sha.Initialize();
    sha.UpdateData(_login);
    sha.Finalize();
    uint8 t4[SHA_DIGEST_LENGTH];
    memcpy(t4, sha.GetDigest(), SHA_DIGEST_LENGTH);

    sha.Initialize();
    sha.UpdateBigNumbers(&t3, NULL);
    sha.UpdateData(t4, SHA_DIGEST_LENGTH);
    sha.UpdateBigNumbers(&s, &A, &B, &K, NULL);
    sha.Finalize();
    BigNumber M;
    M.SetBinary(sha.GetDigest(), 20);

    ///- Check if SRP6 results match (password is correct), else send an error
    if (!memcmp(M.AsByteArray(), lp.M1, 20))
    {
        sLog.outBasic("User '%s' successfully authenticated", _login.c_str());

        uint8 OS;

        if (!strcmp(operatingSystem_.c_str(), "Win"))
            OS = CLIENT_OS_WIN;
        else if (!strcmp(operatingSystem_.c_str(), "OSX"))
            OS = CLIENT_OS_OSX;
        else if (!strcmp(operatingSystem_.c_str(), "CHA") ||
                 !strcmp(operatingSystem_.c_str(), "CHAT"))
            OS = CLIENT_OS_CHAT;
        else
        {
            OS = CLIENT_OS_UNKNOWN;
            AccountsDatabase.escape_string(operatingSystem_);
            sLog.outLog(LOG_WARDEN, "Client %s got unsupported operating system (%s)", _safelogin.c_str(), operatingSystem_.c_str());
        }

        ///- 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();

        QueryResultAutoPtr result = AccountsDatabase.PQuery("SELECT account_id FROM account WHERE username = '******'", _safelogin.c_str());

        if (!result)
        {
            if (_build > 6005)                                  // > 1.12.2
            {
                char data[4] = { CMD_AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT, 3, 0};
                send(data, sizeof(data));
            }
            else
            {
                // 1.x not react incorrectly at 4-byte message use 3 as real error
                char data[2] = { CMD_AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT};
                send(data, sizeof(data));
            }
            return true;
        }

        uint32 accId = result->Fetch()->GetUInt32();

        // direct to be sure that values will be set before character choose, this will slow down logging in a bit ;p
        AccountsDatabase.DirectPExecute("UPDATE account_session SET session_key = '%s' WHERE account_id = '%u'", K_hex, accId);

        static SqlStatementID updateAccount;
        SqlStatement stmt = AccountsDatabase.CreateStatement(updateAccount, "UPDATE account SET last_ip = ?, last_local_ip = ?, last_login = NOW(), locale_id = ?, failed_logins = 0, client_os_version_id = ? WHERE account_id = ?");
        std::string tmpIp = get_remote_address();
        stmt.addString(tmpIp.c_str());
        stmt.addString(localIp_.c_str());
        stmt.addUInt8(uint8(GetLocaleByName(_localizationName)));
        stmt.addUInt8(OS);
        stmt.addUInt32(accId);
        stmt.DirectExecute();

        OPENSSL_free((void*)K_hex);

        ///- Finish SRP6 and send the final result to the client
        sha.Initialize();
        sha.UpdateBigNumbers(&A, &M, &K, NULL);
        sha.Finalize();

        SendProof(sha);

        ///- Set _authed to true!
        _authed = true;
    }
    else
    {
        if (_build > 6005)                                  // > 1.12.2
        {
            char data[4] = { CMD_AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT, 3, 0};
            send(data, sizeof(data));
        }
        else
        {
            // 1.x not react incorrectly at 4-byte message use 3 as real error
            char data[2] = { CMD_AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT};
            send(data, sizeof(data));
        }
        sLog.outBasic("[AuthChallenge] account %s tried to login with wrong password!",_login.c_str ());

        uint32 MaxWrongPassCount = sConfig.GetIntDefault("WrongPass.MaxCount", 0);
        if (MaxWrongPassCount > 0)
        {
            static SqlStatementID updateAccountFailedLogins;
            //Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP
            SqlStatement stmt = AccountsDatabase.CreateStatement(updateAccountFailedLogins, "UPDATE account SET failed_logins = failed_logins + 1 WHERE username = ?");
            stmt.addString(_login);
            stmt.Execute();

            if (QueryResultAutoPtr loginfail = AccountsDatabase.PQuery("SELECT account_id, failed_logins FROM account WHERE username = '******'", _safelogin.c_str()))
            {
                Field* fields = loginfail->Fetch();
                uint32 failed_logins = fields[1].GetUInt32();

                if (failed_logins >= MaxWrongPassCount)
                {
                    uint32 WrongPassBanTime = sConfig.GetIntDefault("WrongPass.BanTime", 600);
                    bool WrongPassBanType = sConfig.GetBoolDefault("WrongPass.BanType", false);

                    if (WrongPassBanType)
                    {
                        uint32 acc_id = fields[0].GetUInt32();
                        AccountsDatabase.PExecute("INSERT INTO account_punishment VALUES ('%u', '%u', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+%u, 'Realm', 'Incorrect password for: %u times. Ban for: %u seconds')",
                                                acc_id, PUNISHMENT_BAN, WrongPassBanTime, failed_logins, WrongPassBanTime);
                        sLog.outBasic("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times",
                            _login.c_str(), WrongPassBanTime, failed_logins);
                    }
                    else
                    {
                        std::string current_ip = get_remote_address();
                        AccountsDatabase.escape_string(current_ip);
                        AccountsDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Realm','Incorrect password for: %u times. Ban for: %u seconds')",
                            current_ip.c_str(), WrongPassBanTime, failed_logins, 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);
                    }
                }
            }
        }
    }
    return true;
}