Пример #1
0
void WorldSession::SendAuthResponse(uint8 code, bool queued, uint32 queuePos)
{
    WorldPacket packet(SMSG_AUTH_RESPONSE, 1 /*bits*/ + 4 + 1 + 4 + 1 + 4 + 1 + 1 + (queued ? 4 : 0));
    packet.WriteBit(queued);
    if (queued)
        packet.WriteBit(0);

    packet.WriteBit(1);                                    // has account info

    packet.FlushBits();

    // account info
    packet << uint32(0);                                   // BillingTimeRemaining
    packet << uint8(Expansion());                          // 0 - normal, 1 - TBC, 2 - WOTLK, 3 - CATA; must be set in database manually for each account
    packet << uint32(0);
    packet << uint8(Expansion());                          // Unknown, these two show the same
    packet << uint32(0);                                   // BillingTimeRested
    packet << uint8(0);                                    // BillingPlanFlags

    packet << uint8(code);
    if (queued)
        packet << uint32(queuePos);                             // Queue position

    SendPacket(&packet);
}
Пример #2
0
void WorldSession::SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos)
{
    WorldPacket packet(SMSG_AUTH_RESPONSE,16);
   
	packet.WriteBit(false); //isQueued
    packet.WriteBit(true); //hasAccountInfo
	
	packet << uint32(0);                                   // BillingTimeRemaining
	packet << uint8(Expansion());                          // 0 - normal, 1 - TBC, 2 - WOTLK, 3 - CATA; must be set in database manually for each account
    packet << uint32(0);                                   // Unk 4.3.2
	packet << uint8(Expansion());                          // Unknown, these two show the same
	packet << uint32(0);                                   // BillingTimeRested
	packet << uint8(0);                                    // BillingPlanFlags
   
	/*
	
	if (!shortForm)
    {
        packet << uint32(queuePos);                             // Queue position
        packet << uint8(0);                                     // Unk 3.3.0
    }
	*/
	packet << uint8(code);

    SendPacket(&packet);
}
Пример #3
0
void WorldSession::SendAuthResponse(uint8 code, bool queued, uint32 queuePos)
{
    QueryResult result = LoginDatabase.PQuery("SELECT class, expansion FROM realm_classes WHERE realmId = %u", realmID);
    QueryResult result2 = LoginDatabase.PQuery("SELECT race, expansion FROM realm_races WHERE realmId = %u", realmID);

    if (!result || !result2)
    {
        TC_LOG_ERROR(LOG_FILTER_GENERAL, "Unable to retrieve class or race data.");
        return;
    }
    
    
    WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1 + 4 + 1 + 1 + 1 + (queued ? 4 : 0));
    packet.WriteBit(0);                                        // Is in queue ?
    packet.WriteBit(0);                                        // Has account data ?

    packet.WriteBits(0, 21);                                   // Activate character template button
    packet.WriteBit(0);                                        // Unknown
    packet.WriteBits(result2->GetRowCount(), 23);              // Activation count for races
    packet.WriteBit(0);                                        // Unknown
    packet.WriteBit(0);                                        // Unknown

    packet.WriteBits(0, 21);                                   // Unknown
    packet.WriteBit(0);                                        // Unknown
    packet.WriteBits(result->GetRowCount(), 23);               // Activation count for races
    packet.WriteBit(0);                                        // Unknown

    packet.FlushBits();

    packet << uint32(1);                                       // Auth response ?

    do
    {
        Field* fields = result->Fetch();

        packet << fields[1].GetUInt8();
        packet << fields[0].GetUInt8();
    }while(result->NextRow());

    packet << uint32(0);                                        // Unknown
    packet << uint32(0);                                        // Unknown

    do
    {
        Field* fields = result2->Fetch();

        packet << fields[1].GetUInt8();
        packet << fields[0].GetUInt8();
    }while(result2->NextRow());

    packet << uint32(0);
    packet << uint32(0);
    packet << uint8(Expansion());
    packet << uint8(Expansion());
    packet << uint32(0);
    packet << uint32(0);
    
    SendPacket(&packet);
}
Пример #4
0
void WorldSession::SendAuthResponse(uint8 code, bool queued, uint32 queuePos)
{
    bool hasAccountData = true;

    WorldPacket packet(SMSG_AUTH_RESPONSE, 80);

    packet.WriteBit(hasAccountData);

    if (hasAccountData)
    {
        packet.WriteBits(MAX_CLASSES - 1, 23);
        packet.WriteBits(0, 21);
        packet.WriteBit(0);
        packet.WriteBit(0);
        packet.WriteBit(0);
        packet.WriteBit(0);
        packet.WriteBits(MAX_PLAYABLE_RACES, 23);
        packet.WriteBit(0);

        packet.WriteBit(queued);

        if (queued)
            packet.WriteBit(1);

        if (queued)
            packet << uint32(queuePos);

        for (uint8 i = 0; i < MAX_PLAYABLE_RACES; ++i)
        {
            packet << uint8(raceExpansionInfo[i].expansion);
            packet << uint8(raceExpansionInfo[i].raceOrClass);
        }

        for (uint8 i = 0; i < MAX_CLASSES - 1; ++i)
        {
            packet << uint8(classExpansionInfo[i].raceOrClass);
            packet << uint8(classExpansionInfo[i].expansion);
        }

        packet << uint32(0);
        packet << uint8(Expansion());
        packet << uint32(Expansion());
        packet << uint32(0);
        packet << uint8(Expansion());
        packet << uint32(0);
        packet << uint32(0);
        packet << uint32(0);
    }

    packet << uint8(code);

    SendPacket(&packet);
}
Пример #5
0
void WorldSession::SendAuthResponse(uint8 code, bool queued, uint32 queuePos)
{
    QueryResult classresult = LoginDatabase.PQuery("SELECT class, expansion FROM realm_classes WHERE realmId = %u", realmID);
    QueryResult raceresult = LoginDatabase.PQuery("SELECT race, expansion FROM realm_races WHERE realmId = %u", realmID);
    if (!classresult || !raceresult)
    {
        sLog->outError(LOG_FILTER_GENERAL, "AuthHandler SendAuthResponse could not get db realm_classes and realm_races");
        return;
    }
    WorldPacket packet(SMSG_AUTH_RESPONSE, 1 /*bits*/ + 4 + 1 + 4 + 1 + 4 + 1 + 1 + (queued ? 4 : 0));
    packet << uint8(code);
    packet.WriteBit(queued);                                     // IsInQueue
    packet.WriteBit(1);                                    // has account info

    // account info
	packet.WriteBits(0, 21);                                // Activate character template windows/button
    packet.WriteBits(raceresult->GetRowCount(), 23);            // Activation count for races

    packet.WriteBit(0);
    packet.WriteBits(classresult->GetRowCount(), 23);           // Activation count for classes
    packet.WriteBit(0);

    packet.FlushBits();

    do
    {
        Field* fields = classresult->Fetch();

        packet << fields[0].GetUInt8();
        packet << fields[1].GetUInt8();
    } while (classresult->NextRow());

    do
    {
        Field* fields = raceresult->Fetch();

        packet << fields[1].GetUInt8();
        packet << fields[0].GetUInt8();
    } while (raceresult->NextRow());

    packet << uint8(Expansion());                          // Unknown, these two show the same
    packet << uint8(Expansion());                          // Unknown, these two show the same
    packet << uint8(0);
    packet << uint32(0);
    packet << uint32(0);    
    packet << uint32(0);


    SendPacket(&packet);
}
Пример #6
0
void RA_PWMClass::ExpansionWrite()
{
	for ( byte a = 0; a < PWM_EXPANSION_CHANNELS; a++ )
	{
		Expansion(a,ExpansionChannel[a]);
	}	
}
Пример #7
0
// Initialize a CFontDescription object with the attributes that
// make a font unique.
BOOL CTextStyle::GetFontDescription(CFontDescription* pFontDescription)
{
	BOOL fResult = FALSE;

	// Get the typeface number.
	int nTypeface = ((PMGFontServer*)(Database()->get_font_server()))->font_record_to_face(Font());
	if (nTypeface != -1)
	{
		// Compute the style (bold, italic) of the typeface.
		int nFontStyle = 0;
		if (Bold())
		{
			nFontStyle |= FONT_STYLE_Bold;
		}
		if (Italic())
		{
			nFontStyle |= FONT_STYLE_Italic;
		}

		// Initialize the font description.
		pFontDescription->m_nTypeface = typeface_for_fstyle(nTypeface, (FONT_STYLE)nFontStyle);
		pFontDescription->m_lPointSize = Size();
		pFontDescription->m_lHorizontalExpansion = Expansion();
		pFontDescription->m_Fill = Fill();
		pFontDescription->m_Outline = Outline();
		pFontDescription->m_Shadow = Shadow();

		fResult = TRUE;
	}

	return fResult;
}
Пример #8
0
void WorldSession::SendAuthResponse(uint8 code, bool queued, uint32 queuePos)
{
	// Should be done at server's start
	QueryResult classResult = WorldDatabase.Query("SELECT class, expansion FROM aa_classes");
	QueryResult raceResult = WorldDatabase.Query("SELECT race, expansion FROM aa_races");

    WorldPacket packet(SMSG_AUTH_RESPONSE);

    // BitPack
    packet.WriteBit(1); // HasAccountData
	packet.WriteBit(0); // Unknown, 5.0.4
    packet.WriteBits(classResult->GetRowCount(), 25); // Activation count for races
	packet.WriteBits(0, 22); // Activate character template windows/button
    packet.WriteBits(raceResult->GetRowCount(), 25); // Activation count for classes
    packet.WriteBit(0); // IsInQueue

	packet.FlushBits();

	packet << uint8(0);                          // 0 - normal, 1 - TBC, 2 - WOTLK, 3 - CATA, 4 - MoP; must be set in database manually for each account
    packet << uint8(Expansion());

	do
	{
		Field* fields = classResult->Fetch();
		packet << uint8(fields[0].GetUInt8());
		packet << uint8(fields[1].GetUInt8());
	}
	while(classResult->NextRow());

	packet << uint32(0);
	packet << uint32(0);                                   // BillingTimeRemaining
	packet << uint32(0);                                   // BillingTimeRested

	do
	{
		Field* fields = raceResult->Fetch();
		packet << uint8(fields[0].GetUInt8());
		packet << uint8(fields[1].GetUInt8());
	}
	while(raceResult->NextRow());


	packet << uint8(Expansion());                          // Unknown, these two show the same
    packet << uint8(code);                                  // Unknown - 4.3.2

    SendPacket(&packet);
}
Пример #9
0
void RA_PWMClass::ExpansionSetPercent(byte p)
{
	// loop through all 6 channels and send the value
	for ( byte a = 0; a < PWM_EXPANSION_CHANNELS; a++ )
	{
		Expansion(a, p);
	}
}
Пример #10
0
void WorldSession::SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos)
{
    WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 2 + 1);
    packet << uint8(code);
    packet << uint32(0);                                   // BillingTimeRemaining
    packet << uint8(0);                                    // BillingPlanFlags
    packet << uint32(0);                                   // BillingTimeRested
	packet << uint8(Expansion());                          // | 0 - normal | 1 - TBC | 2 - WOTLK | 3 - CATA |
	packet << uint8(Expansion());                          // Server Expansion

    if (!shortForm)
    {
		packet << uint32(queuePos);                        // Queue position
		packet << uint8(0);                                // Unk 3.3.0
    }

    SendPacket(&packet);
}
Пример #11
0
void WorldSession::SendAuthResponse(uint8 AuthCode, bool shortForm, uint32 queuePos)
{
    WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1 + (shortForm ? 0 : (4 + 1)));
    packet << uint8(AuthCode);
    packet << uint32(0);                                   // BillingTimeRemaining
    packet << uint8(0);                                    // BillingPlanFlags
    packet << uint32(0);                                   // BillingTimeRested
    packet << uint8(Expansion());                          // payed expansion
    packet << uint8(Expansion());                          // server expansion

    if (!shortForm)
    {
        packet << uint32(queuePos);                             // Queue position
        packet << uint8(0);                                     // Unk 3.3.0
    }

    SendPacket(&packet);
}
Пример #12
0
void WorldSession::SendAuthOk() const
{
    WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1);
    packet << uint8(AUTH_OK);
    packet << uint32(0);                                    // BillingTimeRemaining
    packet << uint8(0);                                     // BillingPlanFlags
    packet << uint32(0);                                    // BillingTimeRested
    packet << uint8(Expansion());                        // 0 - normal, 1 - TBC. Must be set in database manually for each account.
    SendPacket(packet, true);
}
Пример #13
0
void WorldSession::SendAuthResponse(uint8 code, bool queued, uint32 queuePos)
{
    WorldPacket packet(SMSG_AUTH_RESPONSE, 1 /*bits*/ + 4 + 1 + 4 + 1 + 4 + 1 + 1 + (queued ? 4 : 0));
    packet.WriteBit(1);                                     // has account data
    packet.WriteBits(MAX_CLASSES - 1, 25);                  // Activation count for classes
    packet.WriteBit(0);
    packet.WriteBit(0);
    packet.WriteBits(0, 22);                                // Activate character template windows/button
    packet.WriteBits(MAX_PLAYABLE_RACES, 25);               // Activation count for races

    packet.WriteBit(queued);                                // IsInQueue
    if (queued)
    {
        packet.WriteBit(false);                             // unk
        packet << uint32(queuePos);
    }

    // account info
    for (int i = 0; i < MAX_PLAYABLE_RACES; ++i)
    {
        packet << uint8(raceExpansionInfo[i].expansion);
        packet << uint8(raceExpansionInfo[i].raceOrClass);
    }

    packet << uint32(0);                                    // billing time remaining
    packet << uint32(0);                                    // unk
    packet << uint8(0);                                     // unk
    packet << uint8(Expansion());                           // Unknown, these two show the same
    packet << uint8(Expansion());                           // Unknown, these two show the same

    for (int i = 0; i < MAX_CLASSES - 1; ++i)
    {
        packet << uint8(classExpansionInfo[i].raceOrClass);
        packet << uint8(classExpansionInfo[i].expansion);
    }

    packet << uint32(0);
    packet << uint8(code);

    SendPacket(&packet);
}
Пример #14
0
void WorldSession::SendAuthQueued() const
{
    // The 1st SMSG_AUTH_RESPONSE needs to contain other info too.
    WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1 + 4);
    packet << uint8(AUTH_WAIT_QUEUE);
    packet << uint32(0);                                    // BillingTimeRemaining
    packet << uint8(0);                                     // BillingPlanFlags
    packet << uint32(0);                                    // BillingTimeRested
    packet << uint8(Expansion());                     // 0 - normal, 1 - TBC, must be set in database manually for each account
    packet << uint32(sWorld.GetQueuedSessionPos(this));            // position in queue
    SendPacket(packet, true);
}
Пример #15
0
void WorldSession::SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos)
{
    WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1 + (shortForm ? 0 : (4 + 1)));
    packet << uint8(code);
    packet << uint32(0);                                   // BillingTimeRemaining
    packet << uint8(0);                                    // BillingPlanFlags
    packet << uint32(0);                                   // BillingTimeRested
    packet << uint8(Expansion());                          // 0 - normal, 1 - TBC, 2 - WOTLK, must be set in database manually for each account

    if (!shortForm)
    {
        packet << uint32(queuePos);                             // Queue position
        packet << uint8(0);                                     // Unk 3.3.0
    }

    SendPacket(&packet);
}
Пример #16
0
void CTextStyle::FromOldStyle(const TextStyle& style)
{
	// Set some defaults.
	SetDefault();

	// Copy the style information over.
	Font(style.get_face());
	Size(MakeFixed(style.get_size(), style.get_size_fraction()));
	BaseSize(MakeFixed(style.get_base_size(), style.get_base_size_fraction()));
	Expansion(DivFixed(MakeFixed(style.get_base_size(), style.get_base_size_fraction()),
							 MakeFixed(FONT_EXPANSION_UNIT)));
	Fill(style.get_pattern(), style.get_color());
	Outline(style.get_outline(), style.get_color());
	Shadow(style.get_shadow(), style.get_color());
	m_Character.m_nEffectsVersion = 1;
	XFlipped(style.get_xflipped());
	YFlipped(style.get_yflipped());
//	Color(style.get_color());

	Alignment(style.get_line_alignment());
	VerticalAlignment(style.get_vertical_alignment());
	// Left and right margin should be zero (default) unless set by user.
	// This fixes a problem converting old warp text boxes - they should
	// always have zero margins!
	LeftMargin(0);
	RightMargin(0);
//	LeftMargin(PageToInches(style.get_left_margin()));
//	RightMargin(PageToInches(style.get_right_margin()));
	LeadingType(LEADING_lines);
	Leading(MakeFixed(0.875));

	Underline(style.UnderlineStyle());

	// Update our metrics.
	UpdateFontMetrics();
}
Пример #17
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(GetSecurity() == SEC_PLAYER)
    {
        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.outError("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.outError("Not Expansion 1 account:[%d] but tried to Create character with expansion 1 race (%u)",GetAccountId(),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.outError("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.outError("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(GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(name))
    {
        data << (uint8)CHAR_NAME_RESERVED;
        SendPacket( &data );
        return;
    }

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

    QueryResult *resultacct = loginDatabase.PQuery("SELECT SUM(numchars) FROM realmcharacters WHERE acctid = '%d'", GetAccountId());
    if ( resultacct )
    {
        Field *fields=resultacct->Fetch();
        uint32 acctcharcount = fields[0].GetUInt32();
        delete resultacct;

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

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

        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) || GetSecurity() > SEC_PLAYER;
    uint32 skipCinematics = sWorld.getConfig(CONFIG_SKIP_CINEMATICS);

    bool have_same_race = false;
    if(!AllowTwoSideAccounts || skipCinematics == 1)
    {
        QueryResult *result2 = CharacterDatabase.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 );
                    delete result2;
                    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;
            }
            delete result2;
        }
    }

    // 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( objmgr.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(1);                          // not show intro

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

    loginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid= '%d' AND realmid = '%d'", GetAccountId(), realmID);
    loginDatabase.PExecute("INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (%u, %u, %u)",  charcount, GetAccountId(), realmID);

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

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

    std::string IP_str = GetRemoteAddress();
    sLog.outBasic("Account: %d (IP: %s) Create Character:[%s]",GetAccountId(),IP_str.c_str(),name.c_str());
    sLog.outChar("Account: %d (IP: %s) Create Character:[%s]",GetAccountId(),IP_str.c_str(),name.c_str());
}
Пример #18
0
void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
{
    std::string name;
    uint8 race_, class_;

    recv_data >> name;

    recv_data >> race_;
    recv_data >> class_;

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

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

    if(GetSecurity() == SEC_PLAYER)
    {
        if(uint32 mask = sWorld.getConfig(CONFIG_UINT32_CHARACTERS_CREATING_DISABLED))
        {
            bool disabled = false;

            Team 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.outError("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->expansion > Expansion())
    {
        data << (uint8)CHAR_CREATE_EXPANSION;
        sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u race (%u)", Expansion(), GetAccountId(), raceEntry->expansion, race_);
        SendPacket( &data );
        return;
    }

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

    // check name limitations
    uint8 res = ObjectMgr::CheckPlayerName(name, true);
    if (res != CHAR_NAME_SUCCESS)
    {
        data << uint8(res);
        SendPacket( &data );
        return;
    }

    if (GetSecurity() == SEC_PLAYER && 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;
    }

    QueryResult *resultacct = LoginDatabase.PQuery("SELECT SUM(numchars) FROM realmcharacters WHERE acctid = '%u'", GetAccountId());
    if (resultacct)
    {
        Field *fields=resultacct->Fetch();
        uint32 acctcharcount = fields[0].GetUInt32();
        delete resultacct;

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

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

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

    bool AllowTwoSideAccounts = !sWorld.IsPvPRealm() || sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_ACCOUNTS) || GetSecurity() > SEC_PLAYER;
    CinematicsSkipMode skipCinematics = CinematicsSkipMode(sWorld.getConfig(CONFIG_UINT32_SKIP_CINEMATICS));

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

            Field* field = result2->Fetch();
            uint8 acc_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)
            {
                if (acc_race == 0 || Player::TeamForRace(acc_race) != team_)
                {
                    data << (uint8)CHAR_CREATE_PVP_TEAMS_VIOLATION;
                    SendPacket( &data );
                    delete result2;
                    return;
                }
            }

            // search same race for cinematic or same class if need
            // TODO: check if cinematic already shown? (already logged in?; cinematic field)
            while (skipCinematics == CINEMATICS_SKIP_SAME_RACE && !have_same_race)
            {
                if(!result2->NextRow())
                    break;

                field = result2->Fetch();
                acc_race = field[0].GetUInt32();

                have_same_race = race_ == acc_race;
            }
            delete result2;
        }
    }

    Player *pNewChar = new Player(this);
    if (!pNewChar->Create(sObjectMgr.GeneratePlayerLowGuid(), 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 == CINEMATICS_SKIP_SAME_RACE) || skipCinematics == CINEMATICS_SKIP_ALL)
        pNewChar->setCinematic(1);                          // not show intro

    pNewChar->SetAtLoginFlag(AT_LOGIN_FIRST);               // First login

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

    LoginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid= '%u' AND realmid = '%u'", GetAccountId(), realmID);
    LoginDatabase.PExecute("INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (%u, %u, %u)",  charcount, GetAccountId(), realmID);

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

    std::string IP_str = GetRemoteAddress();
    BASIC_LOG("Account: %d (IP: %s) Create Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), name.c_str(), pNewChar->GetGUIDLow());
    sLog.outChar("Account: %d (IP: %s) Create Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), name.c_str(), pNewChar->GetGUIDLow());

    delete pNewChar;                                        // created only to call SaveToDB()
}
Пример #19
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());
}
void Simplex::OneCall()
{
    // calcola l,h e centroide
    Initialize();

    Reflection();

    double ystar = EvalFunction(m_Pstar);
    double y_l = EvalFunction(m_P[m_l]);
    double y_h = EvalFunction(m_P[m_h]);

    // il punto riflesso sta sotto y_l
    if (ystar < y_l)
    {
        Expansion();

        // espansione riuscita
        if (EvalFunction(m_Pstarstar) < y_l)
        {
            m_P[m_h]->SetPoint(m_Pstarstar);
            return;
        }

        // espansione fallita
        else
        {
            m_P[m_h]->SetPoint(m_Pstar);
            return;
        }
     }

    // il punto riflesso non sta sotto y_l
    else
    {
        // calcola se il punto riflesso è maggiore di tutti gli altri
        int counter = 0;
        for (int i = 0; i < 3; i++)
        {
            if ( ystar > EvalFunction(m_P[i]) )
            {counter++;}
        }

        // il punto non è maggiore di tutti gli i != h
        if (counter < 2)
        {
            m_P[m_h]->SetPoint(m_Pstar);
            return;
        }

        // il punto è maggiore di tutti gli i (!)= h
        else
        {
            // se non è maggiore di h, sostituisco h
            if (counter < 3)
            {
                m_P[m_h]->SetPoint(m_Pstar);
                y_h = EvalFunction(m_P[m_h]);
            }

            Contraction();

            // il punto contratto non è maggiore di y_h
            if (EvalFunction(m_Pstarstar) <= y_h)
            {
                m_P[m_h]->SetPoint(m_Pstarstar);
                return;
            }
            // il punto contratto è maggiore di y_h
            else
            {
                double x_point_l = m_P[m_l]->GetX();
                double y_point_l = m_P[m_l]->GetY();
                for (int i = 0; i < 3; i++)
                {
                    m_P[i]->SetX(0.5*(m_P[i]->GetX() + x_point_l));
                    m_P[i]->SetY(0.5*(m_P[i]->GetY() + y_point_l));
                }
                return;
            }
        }
   }

}
Пример #21
0
void WorldSession::SendAuthResponse(uint8 code, bool queued, uint32 queuePos)
{   
    QueryResult result = LoginDatabase.PQuery("SELECT class, expansion FROM realm_classes WHERE realmId = %u", realmID);
    QueryResult result2 = LoginDatabase.PQuery("SELECT race, expansion FROM realm_races WHERE realmId = %u", realmID);

    if (!result || !result2)
    {
        TC_LOG_ERROR(LOG_FILTER_GENERAL, "Unable to retrieve class or race data.");
        return;
    }
    
    WorldPacket packet(SMSG_AUTH_RESPONSE, 80);
    packet.WriteBit(queued);
    packet.WriteBit(code == AUTH_OK);

    if (code == AUTH_OK)
    {
        packet.WriteBits(0, 21);
        packet.WriteBit(0);
        packet.WriteBits(result->GetRowCount(), 23);
        packet.WriteBit(0);
        packet.WriteBit(0);

        packet.WriteBits(0, 21);
        packet.WriteBit(0);
        packet.WriteBits(result2->GetRowCount(), 23);
        packet.WriteBit(0);

        packet.FlushBits();
    }

    if (queued)
    {
        packet.WriteBit(0);
        packet << uint32(queuePos);                             // Queue position

        packet.FlushBits();
    }
    
    if (code == AUTH_OK)
    {
        do
        {
            Field* fields = result->Fetch();

            packet << fields[0].GetUInt8();
            packet << fields[1].GetUInt8();
        } 
        while (result->NextRow());        

        packet << uint32(0);

        do
        {
            Field* fields = result2->Fetch();

            packet << fields[1].GetUInt8();
            packet << fields[0].GetUInt8();
        } 
        while (result2->NextRow());


        packet << uint32(0);                                   // BillingTimeRemaining
        packet << uint32(0);                                   // BillingTimeRested

        packet << uint8(Expansion());                          // 0 - normal, 1 - TBC, 2 - WOTLK, 3 - CATA; must be set in database manually for each account
        packet << uint8(Expansion());                          // Unknown, these two show the same

        packet << uint32(0);
        packet << uint32(0);
    }

    packet << uint8(code);

    SendPacket(&packet);
}
Пример #22
0
void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
{
    std::string name;
    uint8 race_, class_;

    recv_data >> name;

    recv_data >> race_;
    recv_data >> class_;

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

    if(GetSecurity() == SEC_PLAYER)
    {
        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.outError("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->expansion > Expansion())
    {
        data << (uint8)CHAR_CREATE_EXPANSION;
        sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u race (%u)", Expansion(), GetAccountId(), raceEntry->expansion, race_);
        SendPacket( &data );
        return;
    }

    // prevent character creating Expansion class without Expansion account
    if (classEntry->expansion > Expansion())
    {
        data << (uint8)CHAR_CREATE_EXPANSION_CLASS;
        sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u class (%u)", Expansion(), GetAccountId(), classEntry->expansion, class_);
        SendPacket( &data );
        return;
    }

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

    // check name limitations
    uint8 res = ObjectMgr::CheckPlayerName(name, true);
    if (res != CHAR_NAME_SUCCESS)
    {
        data << uint8(res);
        SendPacket( &data );
        return;
    }

    if (GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(name))
    {
        data << (uint8)CHAR_NAME_RESERVED;
        SendPacket( &data );
        return;
    }

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

    QueryResult *resultacct = loginDatabase.PQuery("SELECT SUM(numchars) FROM realmcharacters WHERE acctid = '%d'", GetAccountId());
    if (resultacct)
    {
        Field *fields=resultacct->Fetch();
        uint32 acctcharcount = fields[0].GetUInt32();
        delete resultacct;

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

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

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

    // speedup check for heroic class disabled case
    uint32 heroic_free_slots = sWorld.getConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
    if(heroic_free_slots == 0 && GetSecurity() == SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT)
    {
        data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT;
        SendPacket( &data );
        return;
    }

    // speedup check for heroic class disabled case
    uint32 req_level_for_heroic = sWorld.getConfig(CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING);
    if(GetSecurity() == SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
    {
        data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT;
        SendPacket( &data );
        return;
    }

    bool AllowTwoSideAccounts = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || GetSecurity() > SEC_PLAYER;
    uint32 skipCinematics = sWorld.getConfig(CONFIG_SKIP_CINEMATICS);

    bool have_same_race = false;

    // if 0 then allowed creating without any characters
    bool have_req_level_for_heroic = (req_level_for_heroic==0);

    if(!AllowTwoSideAccounts || skipCinematics == 1 || class_ == CLASS_DEATH_KNIGHT)
    {
        QueryResult *result2 = CharacterDatabase.PQuery("SELECT level,race,class FROM characters WHERE account = '%u' %s",
            GetAccountId(), (skipCinematics == 1 || class_ == CLASS_DEATH_KNIGHT) ? "" : "LIMIT 1");
        if(result2)
        {
            uint32 team_= Player::TeamForRace(race_);

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

            if(GetSecurity() == SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT)
            {
                uint8 acc_class = field[2].GetUInt32();
                if(acc_class == CLASS_DEATH_KNIGHT)
                {
                    if(heroic_free_slots > 0)
                        --heroic_free_slots;

                    if(heroic_free_slots == 0)
                    {
                        data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT;
                        SendPacket( &data );
                        return;
                    }
                }

                if(!have_req_level_for_heroic)
                {
                    uint32 acc_level = field[0].GetUInt32();
                    if(acc_level >= req_level_for_heroic)
                        have_req_level_for_heroic = true;
                }
            }

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

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

            // search same race for cinematic or same class if need
            // TODO: check if cinematic already shown? (already logged in?; cinematic field)
            while ((skipCinematics == 1 && !have_same_race) || class_ == CLASS_DEATH_KNIGHT)
            {
                if(!result2->NextRow())
                    break;

                field = result2->Fetch();
                acc_race = field[1].GetUInt32();

                if(!have_same_race)
                    have_same_race = race_ == acc_race;

                if(GetSecurity() == SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT)
                {
                    uint8 acc_class = field[2].GetUInt32();
                    if(acc_class == CLASS_DEATH_KNIGHT)
                    {
                        if(heroic_free_slots > 0)
                            --heroic_free_slots;

                        if(heroic_free_slots == 0)
                        {
                            data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT;
                            SendPacket( &data );
                            return;
                        }
                    }

                    if(!have_req_level_for_heroic)
                    {
                        uint32 acc_level = field[0].GetUInt32();
                        if(acc_level >= req_level_for_heroic)
                            have_req_level_for_heroic = true;
                    }
                }
            }
            delete result2;
        }
    }

    if(GetSecurity() == SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && !have_req_level_for_heroic)
    {
        data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT;
        SendPacket( &data );
        return;
    }

    // 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( objmgr.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(1);                          // not show intro

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

    loginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid= '%d' AND realmid = '%d'", GetAccountId(), realmID);
    loginDatabase.PExecute("INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (%u, %u, %u)",  charcount, GetAccountId(), realmID);

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

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

    std::string IP_str = GetRemoteAddress();
    sLog.outBasic("Account: %d (IP: %s) Create Character:[%s]", GetAccountId(), IP_str.c_str(), name.c_str());
    sLog.outChar("Account: %d (IP: %s) Create Character:[%s]", GetAccountId(), IP_str.c_str(), name.c_str());
}
Пример #23
0
void WorldSession::SendAuthResponse(uint8 code, bool queued, uint32 queuePos)
{   
    QueryResult classResult = LoginDatabase.PQuery("SELECT class, expansion FROM realm_classes WHERE realmId = %u", realmID);
    QueryResult raceResult = LoginDatabase.PQuery("SELECT race, expansion FROM realm_races WHERE realmId = %u", realmID);

    if (!classResult || !raceResult)
    {
        TC_LOG_ERROR("network", "Unable to retrieve class or race data.");
        return;
    }

    TC_LOG_ERROR("network", "SMSG_AUTH_RESPONSE");
    WorldPacket packet(SMSG_AUTH_RESPONSE, 80);
    
    packet << uint8(code);                             // Auth response ?
    packet.WriteBit(code == AUTH_OK);

    if (code == AUTH_OK)
    {
        packet.WriteBits(0, 21);
        packet.WriteBit(0);
        packet.WriteBit(0);
        packet.WriteBit(0);
        packet.WriteBits(classResult->GetRowCount(), 23);
        packet.WriteBits(raceResult->GetRowCount(), 23);
        packet.WriteBit(0);
        packet.WriteBit(0);
        packet.WriteBits(0, 21);
    }

    packet.WriteBit(queued);

    if (queued)
        packet.WriteBit(1);                             // Unknown

    packet.FlushBits();

    if (queued)
        packet << uint32(0);                            // Unknown

    if (code == AUTH_OK)
    {
        packet << uint32(0);
        packet << uint8(Expansion());
        packet << uint8(Expansion());
        
        do
        {
            Field* fields = raceResult->Fetch();
            
            packet << fields[0].GetUInt8();
            packet << fields[1].GetUInt8();
        } 
        while (raceResult->NextRow());
        
        packet << uint32(0);
        packet << uint32(0);
        packet << uint32(0);

        do
        {
            Field* fields = classResult->Fetch();
            
            packet << fields[0].GetUInt8();
            packet << fields[1].GetUInt8();
        } 
        while (classResult->NextRow());

        packet << uint32(0);
    }

    SendPacket(&packet);
}