int NFCDataBaseModule::CreateRole(const std::string& strAccount, const std::string& strRoleName)
{
    if (HasRole(strRoleName) <= 0)
    {
        NFCValueList valueRoleList;
        QueryAccountRoleList(strAccount, valueRoleList);

        if (valueRoleList.GetCount() < 4)
        {
            char szExecRole[MAX_PATH] = { 0 };
            sprintf(szExecRole, "insert into %s ( Account, RoleName ) values ( '%s', '%s' )", mstrPlayerTableName.c_str(), strAccount.c_str(), strRoleName.c_str());
            m_pDataBaseDriver->OTLExec(szExecRole, motlConnect);

            //////////////////////////////////////////////////////////////////////////
            //Ìí¼Ó½ÇÉ«Ô´
            valueRoleList.AddString(strRoleName.c_str());

            std::string strInfo;
            for (int i = 0; i < valueRoleList.GetCount(); i++)
            {
                strInfo.append(valueRoleList.StringVal(i));
                strInfo.append(";");
            }

            char szExecHead[MAX_PATH] = { 0 };
            sprintf(szExecHead, "UPDATE %s		SET RoleList = ", mstrAccountTableName.c_str());

            char szExecEnd[MAX_PATH] = { 0 };
            sprintf(szExecEnd, " WHERE Account = '%s'", strAccount.c_str());

            std::string strExec;
            strExec.append(szExecHead);
            strExec.append("'");
            strExec.append(strInfo);
            strExec.append("' ");
            strExec.append(szExecEnd);

            return m_pDataBaseDriver->OTLExec(strExec.c_str(), motlConnect);
        }
    }

    return 0;
}
int NFCDataBaseModule::DeleteRole(const std::string& strAccount, const std::string& strRoleName)
{
    if (HasRole(strRoleName) > 0)
    {
        NFCValueList valueRoleList;
        QueryAccountRoleList(strAccount, valueRoleList);

        //if ( valueRoleList.GetCount() < 5 )
        {
            std::string strInfo;
            for (int i = 0; i < valueRoleList.GetCount(); i++)
            {
                std::string strName = valueRoleList.StringVal(i);
                if (strRoleName != strName)
                {
                    strInfo.append(valueRoleList.StringVal(i));
                    strInfo.append(";");
                }
            }

            char szExecHead[MAX_PATH] = { 0 };
            sprintf(szExecHead, "UPDATE %s		SET RoleList = ", mstrAccountTableName.c_str());

            char szExecEnd[MAX_PATH] = { 0 };
            sprintf(szExecEnd, " WHERE Account = '%s'", strAccount.c_str());

            std::string strExec;
            strExec.append(szExecHead);
            strExec.append("'");
            strExec.append(strInfo);
            strExec.append("' ");
            strExec.append(szExecEnd);

            return m_pDataBaseDriver->OTLExec(strExec.c_str(), motlConnect);
        }
    }
    return 0;
}
        void DoNormalAttack(uint32 diff)
        {
            opponent = me->GetVictim();
            if (opponent)
            {
                if (!IsCasting())
                    StartAttack(opponent);
            }
            else
                return;

            //TODO: add more damage spells

            if (feartimer <= diff && GC_Timer <= diff)
            { CheckFear(); feartimer = 2000; }

            if (IsSpellReady(RAIN_OF_FIRE_1, diff) && !me->isMoving() && HasRole(BOT_ROLE_DPS) && Rand() < 25)
            {
                Unit* blizztarget = FindAOETarget(30, true);
                if (blizztarget && doCast(blizztarget, GetSpell(RAIN_OF_FIRE_1)))
                    return;
                SetSpellCooldown(RAIN_OF_FIRE_1, 2000);//fail
            }

            float dist = me->GetExactDist(opponent);

            if (IsSpellReady(CURSE_OF_THE_ELEMENTS_1, diff) && dist < 30 && Rand() < 15 &&
                !HasAuraName(opponent, CURSE_OF_THE_ELEMENTS_1) &&
                doCast(opponent, GetSpell(CURSE_OF_THE_ELEMENTS_1)))
            {
                GC_Timer = 800;
                return;
            }

            if (IsSpellReady(CORRUPTION_1, diff) && HasRole(BOT_ROLE_DPS) && dist < 30 && Rand() < 25 &&
                !opponent->HasAura(GetSpell(CORRUPTION_1), me->GetGUID()) &&
                doCast(opponent, GetSpell(CORRUPTION_1)))
                return;

            if (IsSpellReady(HAUNT_1, diff) && HasRole(BOT_ROLE_DPS) && dist < 30 && Rand() < 25 &&
                !opponent->HasAura(GetSpell(HAUNT_1), me->GetGUID()) &&
                doCast(opponent, GetSpell(HAUNT_1)))
                return;

            if (GC_Timer <= diff && HasRole(BOT_ROLE_DPS) && dist < 30 && Rand() < 15 && !Afflicted(opponent))
            {
                if (GetSpellCooldown(CONFLAGRATE_1) <= 8000 && doCast(opponent, GetSpell(IMMOLATE_1)))
                    return;
                else if (doCast(opponent, GetSpell(UNSTABLE_AFFLICTION_1)))
                    return;
            }

            if (IsSpellReady(CONFLAGRATE_1, diff) && HasRole(BOT_ROLE_DPS) && dist < 30 && Rand() < 35 &&
                HasAuraName(opponent, IMMOLATE_1) &&
                doCast(opponent, GetSpell(CONFLAGRATE_1)))
                return;

            if (IsSpellReady(CHAOS_BOLT_1, diff) && HasRole(BOT_ROLE_DPS) && dist < 30 && Rand() < 50 &&
                doCast(opponent, GetSpell(CHAOS_BOLT_1)))
                return;

            if (IsSpellReady(SHADOW_BOLT_1, diff) && HasRole(BOT_ROLE_DPS) && dist < 30 &&
                doCast(opponent, GetSpell(SHADOW_BOLT_1)))
                return;
        }