Exemple #1
0
AccountOpResult AccountMgr::DeleteAccount(uint32 accountId)
{
    // Check if accounts exists
    PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BY_ID);
    stmt->setUInt32(0, accountId);
    PreparedQueryResult result = LoginDatabase.Query(stmt);

    if (!result)
        return AOR_NAME_NOT_EXIST;

    // Obtain accounts characters
    stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARS_BY_ACCOUNT_ID);

    stmt->setUInt32(0, accountId);

    result = CharacterDatabase.Query(stmt);

    if (result)
    {
        do
        {
            uint32 guidLow = (*result)[0].GetUInt32();
            uint64 guid = MAKE_NEW_GUID(guidLow, 0, HIGHGUID_PLAYER);

            // Kick if player is online
            if (Player* p = ObjectAccessor::FindPlayer(guid))
            {
                WorldSession* s = p->GetSession();
                s->KickPlayer();                            // mark session to remove at next session list update
                s->LogoutPlayer(false);                     // logout player without waiting next session list update
            }

            Player::DeleteFromDB(guid, accountId, false);       // no need to update realm characters
        } while (result->NextRow());
    }

    // table realm specific but common for all characters of account for realm
    stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_TUTORIALS);
    stmt->setUInt32(0, accountId);
    CharacterDatabase.Execute(stmt);

    stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ACCOUNT_DATA);
    stmt->setUInt32(0, accountId);
    CharacterDatabase.Execute(stmt);

    stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_BAN);
    stmt->setUInt32(0, accountId);
    CharacterDatabase.Execute(stmt);

    SQLTransaction trans = LoginDatabase.BeginTransaction();

    stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT);
    stmt->setUInt32(0, accountId);
    trans->Append(stmt);

    stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS);
    stmt->setUInt32(0, accountId);
    trans->Append(stmt);

    stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS);
    stmt->setUInt32(0, accountId);
    trans->Append(stmt);

    stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_BANNED);
    stmt->setUInt32(0, accountId);
    trans->Append(stmt);

    LoginDatabase.CommitTransaction(trans);

    return AOR_OK;
}
void WorldSocket::InformationRetreiveCallback(WorldPacket & recvData, uint32 requestid)
{
    if(requestid != mRequestID)
        return;

    uint32 error;
    recvData >> error;

    if(error != 0 || pAuthenticationPacket == NULL)
    {
        // something happened wrong @ the logon server
        OutPacket(SMSG_AUTH_RESPONSE, 1, "\x0D");
        return;
    }

    // Extract account information from the packet.
    string AccountName;
    const string * ForcedPermissions;
    uint32 AccountID;
    string GMFlags;
    uint8 AccountFlags;
    string lang = "enUS";
    uint32 i;

    recvData >> AccountID >> AccountName >> GMFlags >> AccountFlags;
    ForcedPermissions = sLogonCommHandler.GetForcedPermissions(AccountName);
    if( ForcedPermissions != NULL )
        GMFlags.assign(ForcedPermissions->c_str());

    sLog.outDebug( " >> got information packet from logon: `%s` ID %u (request %u)", AccountName.c_str(), AccountID, mRequestID);
//	sLog.outColor(TNORMAL, "\n");

    mRequestID = 0;
    // Pull the session key.
    uint8 K[40];
    recvData.read(K, 40);

    BigNumber BNK;
    BNK.SetBinary(K, 40);

    uint8 *key = new uint8[20];
    WowCrypt::GenerateKey(key, K);

    // Initialize crypto.
    _crypt.SetKey(key, 20);
    _crypt.Init();
    delete [] key;

    //checking if player is already connected
    //disconnect corrent player and login this one(blizzlike)

    if(recvData.rpos() != recvData.wpos())
        recvData.read((uint8*)lang.data(), 4);

    WorldSession *session = sWorld.FindSession( AccountID );
    if( session)
    {
        // AUTH_FAILED = 0x0D
        session->Disconnect();

        // clear the logout timer so he times out straight away
        session->SetLogoutTimer(1);

        // we must send authentication failed here.
        // the stupid newb can relog his client.
        // otherwise accounts dupe up and disasters happen.
        OutPacket(SMSG_AUTH_RESPONSE, 1, "\x15");
        return;
    }

    Sha1Hash sha;

    uint8 digest[20];
    pAuthenticationPacket->read(digest, 20);

    uint32 t = 0;
    if( m_fullAccountName == NULL )				// should never happen !
        sha.UpdateData(AccountName);
    else
    {
        sha.UpdateData(*m_fullAccountName);

        // this is unused now. we may as well free up the memory.
        delete m_fullAccountName;
        m_fullAccountName = NULL;
    }

    sha.UpdateData((uint8 *)&t, 4);
    sha.UpdateData((uint8 *)&mClientSeed, 4);
    sha.UpdateData((uint8 *)&mSeed, 4);
    sha.UpdateBigNumbers(&BNK, NULL);
    sha.Finalize();

    if (memcmp(sha.GetDigest(), digest, 20))
    {
        // AUTH_UNKNOWN_ACCOUNT = 21
        OutPacket(SMSG_AUTH_RESPONSE, 1, "\x15");
        return;
    }

    // Allocate session
    WorldSession * pSession = new WorldSession(AccountID, AccountName, this);
    mSession = pSession;
    ASSERT(mSession);
    pSession->deleteMutex.Acquire();

    // Set session properties
    pSession->SetClientBuild(mClientBuild);
    pSession->LoadSecurity(GMFlags);
    pSession->SetAccountFlags(AccountFlags);
    pSession->m_lastPing = (uint32)UNIXTIME;
    pSession->language = sLocalizationMgr.GetLanguageId(lang);

    if(recvData.rpos() != recvData.wpos())
        recvData >> pSession->m_muted;

    for(uint32 i = 0; i < 8; ++i)
        pSession->SetAccountData(i, NULL, true, 0);

    // queue the account loading
    /*AsyncQuery * aq = new AsyncQuery( new SQLClassCallbackP1<World, uint32>(World::getSingletonPtr(), &World::LoadAccountDataProc, AccountID) );
    aq->AddQuery("SELECT * FROM account_data WHERE acct = %u", AccountID);
    CharacterDatabase.QueueAsyncQuery(aq);*/
    if(sWorld.m_useAccountData)
    {
        QueryResult * pResult = CharacterDatabase.Query("SELECT * FROM account_data WHERE acct = %u", AccountID);
        if( pResult == NULL )
            CharacterDatabase.Execute("INSERT INTO account_data VALUES(%u, '', '', '', '', '', '', '', '', '')", AccountID);
        else
        {
            size_t len;
            const char * data;
            char * d;
            for(i = 0; i < 8; ++i)
            {
                data = pResult->Fetch()[1+i].GetString();
                len = data ? strlen(data) : 0;
                if(len > 1)
                {
                    d = new char[len+1];
                    memcpy(d, data, len+1);
                    pSession->SetAccountData(i, d, true, (uint32)len);
                }
            }

            delete pResult;
        }
    }

    Log.Debug("Auth", "%s from %s:%u [%ums]", AccountName.c_str(), GetRemoteIP().c_str(), GetRemotePort(), _latency);
#ifdef SESSION_CAP
    if( sWorld.GetSessionCount() >= SESSION_CAP )
    {
        OutPacket(SMSG_AUTH_RESPONSE, 1, "\x0D");
        Disconnect();
        return;
    }
#endif

    // Check for queue.
    if( (sWorld.GetSessionCount() < sWorld.GetPlayerLimit()) || pSession->HasGMPermissions() ) {
        Authenticate();
    } else {
        // Queued, sucker.
        uint32 Position = sWorld.AddQueuedSocket(this);
        mQueued = true;
        Log.Debug("Queue", "%s added to queue in position %u", AccountName.c_str(), Position);

        // Send packet so we know what we're doing
        UpdateQueuePosition(Position);
    }

    pSession->deleteMutex.Release();
}
void SceneCharSelection::OnUpdate(s32 timepassed)
{
    // treat doubleclick on listboxes as OK button click
    if(eventrecv->HasGUIEvent())
    {
        const SEvent::SGUIEvent& ev = eventrecv->NextGUIEvent();
        if(ev.EventType == EGET_LISTBOX_SELECTED_AGAIN)
        {
            if(ev.Caller == realmlistbox)
            {
                eventrecv->buttons |= BUTTON_REALMWIN_OK;
            }
            else if(ev.Caller == charlistbox)
            {
                eventrecv->buttons |= BUTTON_ENTER_WORLD;
            }
        }
        if(ev.EventType == EGET_ELEMENT_CLOSED)
        {
            if(ev.Caller == realmwin)//realmwin got closed via the close button, remove pointer
            {
                realmwin = NULL;
            }
            if(ev.Caller == newcharwin)//got closed via the close button, remove pointer
            {
                newcharwin = NULL;
            }
        }
        if(ev.EventType == EGET_COMBO_BOX_CHANGED)
        {
            if(ev.Caller == raceselect)
            {
                classselect->clear();
                u32 class_name = classdb->GetFieldId("name");
                u32 race_classmask = racedb->GetFieldId("classmask");
                u32 classmask = racedb->GetInt(racemap[raceselect->getSelected()],race_classmask);
                for(u32 i=1;i<=classdb->GetRowsCount();i++)
                {
                    if(classmask & 1<<i)//if class is in classmask, put it into the list
                    {
                        core::stringw name = classdb->GetString(i,class_name);
                        classmap[classselect->addItem(name.c_str())]=i;
                    }
                }

                
            }
        }
    }

    if(eventrecv->buttons & BUTTON_ENTER_WORLD && !realmwin && !newcharwin)
    {
        logdebug("GUI: SceneCharSelect: Entering world");
        WorldSession *ws = instance->GetWSession();
        if(ws)
        {
            u32 selected = charlistbox->getSelected();
            if(selected < ws->GetCharsCount())
            {
                ws->EnterWorldWithCharacter(ws->GetCharFromList(selected).p._name);
            }
            else
                logerror("Character selection out of bounds! (%u)",selected);
        }
        else
            logerror("GUI: BUTTON_ENTER_ WORLD pressed, but no WorldSession exists!");
    }
    if(eventrecv->buttons & BUTTON_BACK && !realmwin && !newcharwin) // cant cancel with any window open (important for ESC key handling)
    {
        logdebug("GUI: SceneCharSelect: Back to Loginscreen");
        gui->SetSceneState(SCENESTATE_LOGINSCREEN);
        // disconnect from realm server if connected
        if(RealmSession *rs = instance->GetRSession())
            rs->SetMustDie();
        if(WorldSession *ws = instance->GetWSession())
            ws->SetMustDie();
    }

    if(eventrecv->buttons & BUTTON_DELETE_CHARACTER)
    {
        guienv->addMessageBox(L"Not yet implemented!", L"Deleting a character does not yet work!");
    }
    if(eventrecv->buttons & BUTTON_NEW_CHARACTER && !newcharwin)
    {
        dimension2d<s32> dim;
        rect<s32> pos;
        msgbox_textid = 0;
        newcharwin = guienv->addWindow(CalcRelativeScreenPos(driver, 0.2f, 0.2f, 0.6f, 0.6f), true,
            GetStringFromDB(ISCENE_CHARSEL_LABELS, DSCENE_CHARSEL_LABEL_NEWCHARWIN).c_str());
        pos = newcharwin->getAbsolutePosition(); // get absolute position and transform <dim> to absolute in-window position
        dim.Width = pos.LowerRightCorner.X - pos.UpperLeftCorner.X;
        dim.Height = pos.LowerRightCorner.Y - pos.UpperLeftCorner.Y;
        newcharwin->addChild(guienv->addButton(CalcRelativeScreenPos(dim, 0.7f, 0.93f, 0.12f, 0.05f), newcharwin, BUTTON_NEWCHARWIN_OK,
            GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_NEWCHARWIN_OK).c_str()));
        newcharwin->addChild(guienv->addButton(CalcRelativeScreenPos(dim, 0.85f, 0.93f, 0.12f, 0.05f), newcharwin, BUTTON_NEWCHARWIN_CANCEL,
            GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_NEWCHARWIN_CANCEL).c_str()));
        raceselect = guienv->addComboBox(CalcRelativeScreenPos(dim, 0.1f,0.1f,0.8f,0.05f), newcharwin);
        u32 race_name = racedb->GetFieldId("name");
        u32 race_classmask = racedb->GetFieldId("classmask");
        for(u32 i=1;i<=racedb->GetRowsCount();i++)
        {
            if(racedb->GetUint32(i,race_classmask)) //If the race has a classmask, it is playable
            {
                core::stringw name = racedb->GetString(i,race_name);
                racemap[raceselect->addItem(name.c_str())] = i;
            }
        }


        newcharwin->addChild(raceselect);
        classselect = guienv->addComboBox(CalcRelativeScreenPos(dim, 0.1f,0.2f,0.8f,0.05f), newcharwin);
        //newcharwin->addChild(classselect);
        guienv->addStaticText(L"Char Name", CalcRelativeScreenPos(dim,0.1f,0.3f,0.8f,0.05f),false,true,newcharwin);
        charname = guienv->addEditBox(L"", CalcRelativeScreenPos(dim,0.1f,0.35f,0.8f,0.05f),true, newcharwin);
        charname->setMax(12);
        msgbox = guienv->addStaticText(L"",CalcRelativeScreenPos(dim,0.2f,0.6f,0.6f,0.1f), true, true, newcharwin);
    }
    if(eventrecv->buttons & BUTTON_SELECT_REALM || scenedata[ISCENE_CHARSEL_REALMFIRST])
    {
        scenedata[ISCENE_CHARSEL_REALMFIRST] = 0;
        if(instance->GetRSession())
        {
            dimension2d<s32> dim;
            rect<s32> pos;
            realmwin = guienv->addWindow(CalcRelativeScreenPos(driver, 0.2f, 0.2f, 0.6f, 0.6f), true,
                GetStringFromDB(ISCENE_CHARSEL_LABELS, DSCENE_CHARSEL_LABEL_REALMWIN).c_str());
            pos = realmwin->getAbsolutePosition(); // get absolute position and transform <dim> to absolute in-window position
            dim.Width = pos.LowerRightCorner.X - pos.UpperLeftCorner.X;
            dim.Height = pos.LowerRightCorner.Y - pos.UpperLeftCorner.Y;
            realmwin->addChild(guienv->addButton(CalcRelativeScreenPos(dim, 0.7f, 0.93f, 0.12f, 0.05f), realmwin, BUTTON_REALMWIN_OK,
                GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_REALMWIN_OK).c_str()));
            realmwin->addChild(guienv->addButton(CalcRelativeScreenPos(dim, 0.85f, 0.93f, 0.12f, 0.05f), realmwin, BUTTON_REALMWIN_CANCEL,
                GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_REALMWIN_CANCEL).c_str()));
            realmlistbox = guienv->addListBox(CalcRelativeScreenPos(dim, 0.1f, 0.1f, 0.8f, 0.8f), realmwin);
            realmwin->addChild(realmlistbox);
            mutex.acquire();
            RealmSession *rs = instance->GetRSession();

            for(uint32 i = 0; i < rs->GetRealmCount(); i++)
            {
                SRealmInfo& r = rs->GetRealm(i);
                core::stringw entry;
                entry += r.name.c_str();
                entry += L", ";
                switch(r.icon) // icon means here RealmType
                {
                    case 0: entry += "Normal"; break;
                    case 1: entry += "PvP"; break;
                    case 4: entry += "Normal(4)"; break;
                    case 6: entry += "RP"; break;
                    case 8: entry += "RP-PvP"; break;
                    case 16: entry += "FFA-PvP"; break; // MaNGOS custom realm type
                    default: entry += "Unknown"; break;
                }
                entry += L", (";
                entry += r.chars_here;
                entry += L") Chars";
                entry += L"      [";
                entry += r.addr_port.c_str();
                entry += L"]";
                realmlistbox->addItem(entry.c_str(), -1);
                SColor col;
                switch(r.flags)
                {
                    case 0: col.set(0xFF, 0x00, 0xFF, 0x00); break;
                    case 1: col.set(0xFF, 0xFF, 0x00, 0x00); break;
                    case 2: col.set(0xFF, 0x7F, 0x7F, 0x7F); break;
                    case 3: col.set(0xFF, 0xB0, 0xB0, 0x00); break;
                    default: col.set(0xFFFFFFFF);
                }
                realmlistbox->setItemOverrideColor(i,EGUI_LBC_TEXT,col);
                realmlistbox->setItemOverrideColor(i,EGUI_LBC_TEXT_HIGHLIGHT,col);
            }
            if(realmlistbox->getItemCount())
                realmlistbox->setSelected(0);
            mutex.release();
        }
        else
        {
            guienv->addMessageBox(L"Not yet implemented!", L"This action is not yet supported.\nYou can change the realm only while still connected to the realm server.");
        }
    }    
    if(eventrecv->buttons & BUTTON_REALMWIN_OK && realmwin)
    {
        RealmSession *rs = instance->GetRSession();
        if(rs)
        {
            u32 selected = realmlistbox->getSelected();
            if(selected < rs->GetRealmCount())
            {
                rs->SetRealmAddr(rs->GetRealm(selected).addr_port);
                instance->CreateWorldSession();
                eventrecv->buttons |= BUTTON_REALMWIN_CANCEL; // easiest way to close the window without much additional code
            }
            else
                logerror("Realmlist selection out of bounds! (%u)",selected);
        }
    }

    if(eventrecv->buttons & BUTTON_NEWCHARWIN_OK && newcharwin)
    {
        core::stringc chname = charname->getText();
        u8 race = racemap[raceselect->getSelected()];
        u8 cclass = classmap[classselect->getSelected()];
        if(chname.size() && race && cclass)
        {
            WorldSession *ws=instance->GetWSession();
            if(ws)
            {
                ws->SendCharCreate(chname.c_str(), race, cclass);

                msgbox->setText(GetStringFromDB(3,0).c_str());
                msgbox_textid = 0;

                // do not close window until character created (will when getting response code 0)
            }
            else
                logerror("Trying to create new Character, but no WorldSession exists.");
        }
        else
            logerror("Race, Class or Name not set!");
    }

    // realmlist window
    if(eventrecv->buttons & BUTTON_REALMWIN_CANCEL && realmwin)
    {
        realmwin->remove();
        realmwin = NULL;
    }

    // new character window
    if(eventrecv->buttons & BUTTON_NEWCHARWIN_CANCEL && newcharwin)
    {
        newcharwin->remove();
        newcharwin = NULL;
    }
    
    if(newcharwin && msgbox_textid != scenedata[ISCENE_CHARSEL_ERRMSG])
    {
        msgbox_textid = scenedata[ISCENE_CHARSEL_ERRMSG];
        if(SCPDatabase *generictext = instance->dbmgr.GetDB("generic_text"))
        {
            msgbox->setText(GetStringFromDB(0, msgbox_textid, generictext).c_str());
        }
        if(scenedata[ISCENE_CHARSEL_ERRMSG] == CHAR_CREATE_SUCCESS)
        {
            newcharwin->remove();
            newcharwin = NULL;
        }
    }

    eventrecv->buttons = 0;
}
void ClusterInterface::HandleTeleportResult(WorldPacket & pck)
{
	uint32 sessionid;
	uint8 result;
	uint32 mapid, instanceid;
	LocationVector vec;
	float o;

	pck >> sessionid;

	WorldSession* s = GetSession(sessionid);

	if (!s)
	{
		//tell the realm-server we have no session
		WorldPacket data(ICMSG_ERROR_HANDLER, 5);
		data << uint8(1); //1 = no session
		data << sessionid;
		sClusterInterface.SendPacket(&data);
		return;
	}

	pck >> result >> mapid >> instanceid >> vec >> o;

	//the destination is on the same server
	if (result == 1)
	{
		if (s->GetPlayer() != NULL)
			sEventMgr.AddEvent(s->GetPlayer(), &Player::EventClusterMapChange, mapid, instanceid, vec, EVENT_UNK, 1, 1, EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT);
	}
	else
	{
		//make this non-async, needs redone to support packing the player
		//since were saving it HAS TO BE HERE so the new server has the correct data
		WorldPacket nw(SMSG_NEW_WORLD);
		nw << mapid << vec << o;
		s->SendPacket(&nw);

		uint32 oldmapid = s->GetPlayer()->GetMapId();
		uint32 oldinstanceid = s->GetPlayer()->GetInstanceID();
		uint32 playerlowguid = s->GetPlayer()->GetLowGUID();
		s->GetPlayer()->SetMapId(mapid);
		s->GetPlayer()->SetInstanceID(instanceid);
		s->GetPlayer()->SetPosition(vec.x, vec.y, vec.z, o);
		s->GetPlayer()->SaveToDB(true);

		//need to shift back to old ones for removing from world :)
		s->GetPlayer()->SetMapId(oldmapid);
		s->GetPlayer()->SetInstanceID(oldinstanceid);

		WorldPacket data(ICMSG_SWITCH_SERVER, 100);
		data << sessionid << playerlowguid << mapid << instanceid << vec << o;
		sClusterInterface.SendPacket(&data);

		RPlayerInfo * pRPlayer = GetPlayer(playerlowguid);
		bool newRplr = false;
		if(pRPlayer == NULL)
		{
			pRPlayer = new RPlayerInfo;
			newRplr = true;
		}
		s->GetPlayer()->UpdateRPlayerInfo(pRPlayer, newRplr);
		pRPlayer->MapId = mapid;
		pRPlayer->InstanceId = instanceid;
		data.Initialize(ICMSG_PLAYER_INFO);
		pRPlayer->Pack(data);
		sClusterInterface.SendPacket(&data);

		sEventMgr.AddEvent(s->GetPlayer(), &Player::HandleClusterRemove, EVENT_UNK, 1, 1, EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT);
	}
}
		bool OnGossipSelect(Player* Player, Creature* creature, uint32 /*uiSender*/, uint32 uiAction)
		{
			WorldSession* ws = Player->GetSession();

			switch (uiAction)
			{
				case ACTION_TITLE_PRIVATE:
					{
					    if (GetTotalKill(Player) >= 10)
					        Player->SetTitle(sCharTitlesStore.LookupEntry(1));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_CORPORAL:
					{
						if (GetTotalKill(Player) >= 50)
							Player->SetTitle(sCharTitlesStore.LookupEntry(2));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_SERGEANT:
					{
						if (GetTotalKill(Player) >= 100)
							Player->SetTitle(sCharTitlesStore.LookupEntry(3));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_MASTER_SERGEANT:
					{
						if (GetTotalKill(Player) >= 200)
							Player->SetTitle(sCharTitlesStore.LookupEntry(4));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_SERGEANT_MAJOR:
					{
						if (GetTotalKill(Player) >= 400)
							Player->SetTitle(sCharTitlesStore.LookupEntry(5));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_KNIGHT:
					{
						if (GetTotalKill(Player) >= 500)
							Player->SetTitle(sCharTitlesStore.LookupEntry(6));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_KNIGHT_LIEUTENANT:
					{
						if (GetTotalKill(Player) >= 600)
							Player->SetTitle(sCharTitlesStore.LookupEntry(7));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_KNIGHT_CAPTAIN:
					{
						if (GetTotalKill(Player) >= 800)
							Player->SetTitle(sCharTitlesStore.LookupEntry(8));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_KNIGHT_CHAMPION:
					{
						if (GetTotalKill(Player) >= 1000)
							Player->SetTitle(sCharTitlesStore.LookupEntry(9));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_LIEUTENANT_COMMANDER:
					{
						if (GetTotalKill(Player) >= 1500)
							Player->SetTitle(sCharTitlesStore.LookupEntry(10));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_COMMANDER:
					{
						if (GetTotalKill(Player) >= 2500)
							Player->SetTitle(sCharTitlesStore.LookupEntry(11));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_MARSHAL:
					{
						if (GetTotalKill(Player) >= 4000)
							Player->SetTitle(sCharTitlesStore.LookupEntry(12));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_FIELD_MARSHAL:
					{
						if (GetTotalKill(Player) >= 4500)
							Player->SetTitle(sCharTitlesStore.LookupEntry(13));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_GRAND_MARSHAL:
					{
						if (GetTotalKill(Player) >= 5500)
							Player->SetTitle(sCharTitlesStore.LookupEntry(14));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_SCOUT:
					{
						if (GetTotalKill(Player) >= 10)
							Player->SetTitle(sCharTitlesStore.LookupEntry(15));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_GRUNT:
					{
						if (GetTotalKill(Player) >= 50)
							Player->SetTitle(sCharTitlesStore.LookupEntry(16));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_SERGEANT_H:
					{
						if (GetTotalKill(Player) >= 100)
							Player->SetTitle(sCharTitlesStore.LookupEntry(17));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_SENIOR_SERGEANT:
					{
						if (GetTotalKill(Player) >= 200)
							Player->SetTitle(sCharTitlesStore.LookupEntry(18));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_FIRST_SERGEANT:
					{
						if (GetTotalKill(Player) >= 400)
							Player->SetTitle(sCharTitlesStore.LookupEntry(19));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_STONE_GUARD:
					{
						if (GetTotalKill(Player) >= 500)
							Player->SetTitle(sCharTitlesStore.LookupEntry(20));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_BLOOD_GUARD:
					{
						if (GetTotalKill(Player) >= 600)
							Player->SetTitle(sCharTitlesStore.LookupEntry(21));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_LEGIONNAIRE:
					{
						if (GetTotalKill(Player) >= 800)
							Player->SetTitle(sCharTitlesStore.LookupEntry(22));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_CENTURION:
					{
						if (GetTotalKill(Player) >= 1000)
							Player->SetTitle(sCharTitlesStore.LookupEntry(23));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_CHAMPION:
					{
						if (GetTotalKill(Player) >= 1500)
							Player->SetTitle(sCharTitlesStore.LookupEntry(24));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_LIEUTENANT_GENERAL:
					{
						if (GetTotalKill(Player) >= 2500)
							Player->SetTitle(sCharTitlesStore.LookupEntry(25));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_GENERAL:
					{
						if (GetTotalKill(Player) >= 4000)
							Player->SetTitle(sCharTitlesStore.LookupEntry(26));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_WARLORD:
					{
						if (GetTotalKill(Player) >= 4500)
							Player->SetTitle(sCharTitlesStore.LookupEntry(27));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				case ACTION_TITLE_HIGH_WARLORD:
					{
						if (GetTotalKill(Player) >= 5500)
							Player->SetTitle(sCharTitlesStore.LookupEntry(28));
						else
							ws->SendNotification("You dont have enough kills");
					}
				break;
				Player->PlayerTalkClass->SendCloseGossip();
			}
			    return true;
		}
Exemple #6
0
void MapMgr::_PerformObjectDuties()
{
	++mLoopCounter;
	uint32 mstime = getMSTime();
	uint32 difftime = mstime - lastUnitUpdate;
	if(difftime > 500)
		difftime = 500;

	// Update creatures.
	{
		CreatureSet::iterator itr = activeCreatures.begin();
		PetStorageMap::iterator it2 = m_PetStorage.begin();
		Creature * ptr;
		Pet * ptr2;

		for(; itr != activeCreatures.end();)
		{
			ptr = *itr;
			++itr;
			ptr->Update(difftime);
		}

		for(; it2 != m_PetStorage.end();)
		{
			ptr2 = it2->second;
			++it2;

			ptr2->Update(difftime);
		}		
	}

	// Update any events.
	eventHolder.Update(difftime);

	// Update players.
	{
		PlayerStorageMap::iterator itr = m_PlayerStorage.begin();
		Player* ptr;
		for(; itr != m_PlayerStorage.end(); )
		{
			ptr = static_cast< Player* >( (itr->second) );
			++itr;
			if( ptr != NULL )
				ptr->Update( difftime );
		}

		lastUnitUpdate = mstime;
	}

	// Update gameobjects (not on every loop, however)
	if( mLoopCounter % 2 )
	{
		difftime = mstime - lastGameobjectUpdate;

		GameObjectSet::iterator itr = activeGameObjects.begin();
		GameObject * ptr;
		for(; itr != activeGameObjects.end(); )
		{
			ptr = *itr;
			++itr;
			ptr->Update( difftime );
		}

		lastGameobjectUpdate = mstime;
	}	

	// Sessions are updated every loop.
	{
		int result;
		WorldSession * session;
		SessionSet::iterator itr = Sessions.begin();
		SessionSet::iterator it2;

		for(; itr != Sessions.end();)
		{
			session = (*itr);
			it2 = itr;
			++itr;

			if(session->GetInstance() != m_instanceID)
			{
				Sessions.erase(it2);
				continue;
			}

			// Don't update players not on our map.
			// If we abort in the handler, it means we will "lose" packets, or not process this.
			// .. and that could be diasterous to our client :P
			if(session->GetPlayer() && (session->GetPlayer()->GetMapMgr() != this && session->GetPlayer()->GetMapMgr() != 0))
			{
				continue;
			}

			if((result = session->Update(m_instanceID)))
			{
				if(result == 1)
				{
					// complete deletion
					sWorld.DeleteSession(session);
				}
				Sessions.erase(it2);
			}
		}
	}

	// Finally, A9 Building/Distribution
	_UpdateObjects();
}
Exemple #7
0
void AnticheatMgr::SpeedHackDetection(Player* player,MovementInfo movementInfo)
{
    if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & SPEED_HACK_DETECTION) == 0)
        return;

    uint32 key = player->GetGUIDLow();
		
    // We also must check the map because the movementFlag can be modified by the client.
    // If we just check the flag, they could always add that flag and always skip the speed hacking detection.
    // 369 == DEEPRUN TRAM
	// 607 == Strand of The Ancients
    if (m_Players[key].GetLastMovementInfo().HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY) && (player->GetMapId() == 369 || player->GetMapId() == 607))
        return;

	if (player->GetSession()->GetSecurity() > 0)
	    return;

	if (!player->isAlive())
	    return;

    uint32 distance2D = (uint32)movementInfo.pos.GetExactDist2d(&m_Players[key].GetLastMovementInfo().pos);

	if (distance2D > 500)
	    return;

	if (distance2D < 100 && player->getClass() == CLASS_PRIEST && player->isInCombat())
	    return;

	if (player->GetAreaId() == 4281 || player->GetAreaId() == 4342 || player->GetAreaId() == 5154 || player->GetAreaId() == 4395 ||
	player->GetAreaId() == 5926 || player->GetAreaId() == 5738 || player->GetAreaId() == 5535 || player->GetAreaId() == 5004 ||
	player->GetAreaId() == 5088 || player->GetAreaId() == 5303 || player->GetAreaId() == 4753 || player->GetAreaId() == 4752)
	    return;

	if (player->HasAura(66601))
	    return;

	if (player->HasAura(66602))
	{
	    player->RemoveAura(66602);
	}

	if (player->HasAura(605))
	    return;

	if (player->HasAura(51690))
	{
	    player->CastSpell(player, 66601, true);
	    return;
	}

    float x, y, z;
    player->GetPosition(x, y, z);
    float ground_Z = player->GetMap()->GetHeight(x, y, z);
    float z_diff = fabs(ground_Z - z);	
	WorldSession* s = player->GetSession();
	if ( player->GetMap()->IsDungeon() || player->GetMap()->IsRaid() || player->GetMap()->IsBattlegroundOrArena())
	    if ((distance2D > 50 && player->GetMapId() == 566) || (distance2D > 40 && player->GetMapId() != 566))
	        if (z_diff > 1.0f && !player->isGameMaster())
	            if (!player->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) && player->isAlive())
		            s->KickPlayer("Player::Update");			

	if ((player->GetMap()->IsDungeon() || player->GetMap()->IsRaid() || player->GetMap()->IsBattlegroundOrArena() || player->GetMapId() == 732 || player->GetMapId() == 861) && (player->HasAura(33943) || player->HasAura(40120)))
	{
	    player->RemoveAura(33943);
		player->RemoveAura(40120);
	}

    uint8 moveType = 0;
	uint32 maxSpeed = 0;

    // we need to know HOW is the player moving
    // TO-DO: Should we check the incoming movement flags?
    if (player->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING))
    {
        moveType = MOVE_SWIM;
        maxSpeed = 11;
        if (player->HasAura(8326) || player->HasAura(20584)) //Ghost
            maxSpeed += 5;

        if (player->HasAura(86510)) //Epic Swimming Mount
            maxSpeed += 20;

        if (player->HasAura(95664)) //Advanced Swimming Mount
            maxSpeed += 15;

        if (player->HasAura(73701)) //Sea Legs
            maxSpeed += 5;

        if (player->HasAura(98718)) //Subdued Seahorse
            maxSpeed = 41;

        if (player->HasAura(75207)) //Abyssal Seahorse
            maxSpeed = 56;
    }
    else if (player->IsFlying() && player->HasAuraType(SPELL_AURA_MOUNTED))
    {
        moveType = MOVE_FLIGHT;

        if (player->HasSpell(90265)) //master riding
            maxSpeed = 40;
        else if (player->HasSpell(34091)) //artisan riding
            maxSpeed = 33;
        else if (player->HasSpell(34090))
            maxSpeed = 20;

        //extra checks
        if (maxSpeed < 25)
        {
            if (player->HasAura(86459)) //Mount Speed Mod: Standard Flying Mount
                maxSpeed = 36;

            if (player->HasAura(86460)) //Mount Speed Mod: Epic Flying Mount
                maxSpeed = 49;
        }

        if (player->HasAura(32223)) //Crusader Aura
            maxSpeed += 9;

        if (player->HasAura(51983)) //On a Pale Horse Rank 1
            maxSpeed += 5;
        if (player->HasAura(51986)) //On a Pale Horse Rank 2
            maxSpeed += 9;
        
        if (player->HasAura(26023) || player->HasAura(26022)) //Pursuit of Justice
            maxSpeed += 19;
    }
 	else if (player->IsFlying() && !player->HasAuraType(SPELL_AURA_MOUNTED))
	{
	    maxSpeed = 1;

        if (player->HasAura(98619)) //Wings of Flame
            maxSpeed += 11;

        if (player->HasAura(33943)) //Flight Form
            maxSpeed += 20;

        if (player->HasAura(40120)) //Swift Flight Form
            maxSpeed += 35;
			
        if (player->HasAura(59640)) //Underbelly Elixir
            maxSpeed += 20;			
	}
    else if (player->HasAuraType(SPELL_AURA_MOUNTED))
    {
        if (player->HasSpell(33391)) //journeyman riding
            maxSpeed = 25;
        else if (player->HasSpell(33388)) //apprentice riding
            maxSpeed = 21;

        //extra checks
        if (maxSpeed < 17)
        {
            if (player->HasAura(86458)) //Mount Speed Mod: Epic Ground Mount
                maxSpeed = 21;

            if (player->HasAura(86457)) //Mount Speed Mod: Standard Ground Mount
                maxSpeed = 17;
        }

        if (player->HasAura(32223)) //Crusader Aura
            maxSpeed += 5;

        if (player->HasAura(51983)) //On a Pale Horse Rank 1
            maxSpeed += 3;
        if (player->HasAura(51986)) //On a Pale Horse Rank 2
            maxSpeed += 5;
        
        if (player->HasAura(26023) || player->HasAura(26022)) //Pursuit of Justice
            maxSpeed += 5;			
    }
    else if (player->HasUnitMovementFlag(MOVEMENTFLAG_WALKING))
    {
        moveType = MOVE_WALK;
        maxSpeed = 6;
    }
    else
    {
        moveType = MOVE_RUN;
        maxSpeed = 16;
			
		if (z_diff > 1.0f)
		    maxSpeed = 40;
		
        if (player->HasAura(33943)) //Flight Form
            maxSpeed += 20;

        if (player->HasAura(40120)) //Swift Flight Form
            maxSpeed += 33;

        if (player->HasAura(8326) || player->HasAura(20584)) //Ghost
            maxSpeed += 5;

        if (player->HasAura(26023) || player->HasAura(26022)) //Pursuit of Justice
            maxSpeed += 5;

        if (player->HasAura(51721) || player->HasAura(54055)) //Dominion over Acherus
            maxSpeed += 8;

        if (player->HasAura(48265)) //Unholy Presence
            maxSpeed += 2;

        if (player->HasAura(23451) || player->HasAura(23978)) //Speed
            maxSpeed += 10;

        if (player->HasAura(68992)) //Dark flight
            maxSpeed += 4;

        if (player->HasAura(2983) || player->HasAura(1850)) //Sprint, Dash
            maxSpeed += 7;
			
        if (player->HasAura(36554)) //Shadowstep
            maxSpeed += 8;			
    }
    
    if (player->HasUnitMovementFlag(MOVEMENTFLAG_FALLING))
    {
        maxSpeed = 60;
    }
			
    // how many yards the player can do in one sec.

    // how long the player took to move to here.
    uint32 timeDiff = getMSTimeDiff(m_Players[key].GetLastMovementInfo().time,movementInfo.time);
			
    if (!timeDiff)
        timeDiff = 1;
		
    // this is the distance doable by the player in 1 sec, using the time done to move to this point.
    uint32 clientSpeedRate = distance2D * 1000 / timeDiff;

    // we did the (uint32) cast to accept a margin of tolerance
    if (clientSpeedRate > maxSpeed)
    {
		WorldSession* s = player->GetSession();
	    s->KickPlayer("AnticheatMgr::SpeedHackDetection");
        //BuildReport(player,SPEED_HACK_REPORT);
        sLog->outInfo(LOG_FILTER_CHARACTER, "AnticheatMgr:: Speed-Hack detected player GUID (low) %u",player->GetGUIDLow());
    }				
}
Exemple #8
0
    static bool GOMove_Command(ChatHandler* handler, const char* args)
    {
        if (!args)
            return false;

        char* ID_t = strtok((char*)args, " ");
        if (!ID_t)
            return false;
        uint32 ID = (uint32)atol(ID_t);

        char* GObjectID_C = strtok(NULL, " ");
        uint32 GObjectID = 0;
        bool isHex = false;
        if (GObjectID_C)
        {
            GObjectID = strtoul(GObjectID_C, NULL, 0); // can take in hex as well as dec
            isHex = (std::string(GObjectID_C).find("0x") != std::string::npos);
        }

        char* ARG_t = strtok(NULL, " ");
        uint32 ARG = 0;
        if (ARG_t)
            ARG = (uint32)atol(ARG_t);

        WorldSession* session = handler->GetSession();
        Player* player = session->GetPlayer();
        uint64 playerGUID = player->GetGUID();

        if (ID < SPAWN) // no args
        {
            if (ID >= DELET && ID <= GOTO) // has target (needs retrieve gameobject)
            {
                GameObject* target = GetObjectByGObjectID(player, GObjectID, isHex);
                if (!target)
                    ChatHandler(player->GetSession()).PSendSysMessage("Object GUID: %u not found. Temp(%u)", GObjectID, isHex ? 1 : 0);
                else
                {
                    float x,y,z,o;
                    target->GetPosition(x,y,z,o);
                    uint32 p = target->GetPhaseMask();
                    switch(ID)
                    {
                    case DELET: DeleteObject(target/*, isHex ? GObjectID : 0*/); SendSelectionInfo(player, GObjectID, isHex, false); break;
                    case X: SpawnObject(player,player->GetPositionX(),y,z,o,p,true,GObjectID, isHex);      break;
                    case Y: SpawnObject(player,x,player->GetPositionY(),z,o,p,true,GObjectID, isHex);      break;
                    case Z: SpawnObject(player,x,y,player->GetPositionZ(),o,p,true,GObjectID, isHex);      break;
                    case O: SpawnObject(player,x,y,z,player->GetOrientation(),p,true,GObjectID, isHex);    break;
                    case GOTO: player->TeleportTo(target->GetMapId(), x,y,z,o);                     break;
                    case RESPAWN: SpawnObject(player,x,y,z,o,p,false,target->GetEntry(), isHex);           break;
                    case GROUND:
                        {
                            float ground = target->GetMap()->GetHeight(target->GetPhaseMask(), x, y, MAX_HEIGHT);
                            if(ground != INVALID_HEIGHT)
                                SpawnObject(player,x,y,ground,o,p,true,GObjectID, isHex);
                        } break;
                    }
                }
            }
            else
            {
                switch(ID)
                {
                case TEST: session->SendAreaTriggerMessage(player->GetName().c_str());      break;
                case FACE: { float piper2 = M_PI/2; float multi = player->GetOrientation()/piper2; float multi_int = floor(multi); float new_ori = (multi-multi_int > 0.5f) ? (multi_int+1)*piper2 : multi_int*piper2; player->SetFacingTo(new_ori); } break;
                case SAVE: SaveObject(player, GObjectID, isHex);                                   break;
                case SELECTNEAR:
                    {
                        GameObject* object = handler->GetNearbyGameObject();
                        object = GetClosestGObjectID(player, object);
                        if (!object)
                            ChatHandler(player->GetSession()).PSendSysMessage("No objects found");
                        else
                        {
                            bool isHex = (object->GetGUIDHigh() != HIGHGUID_GAMEOBJECT);
                            SendSelectionInfo(player, isHex ? object->GetGUIDHigh() : object->GetDBTableGUIDLow() ? object->GetDBTableGUIDLow() : object->GetGUIDLow(), isHex, true);
                            session->SendAreaTriggerMessage("Selected %s", object->GetName().c_str());
                        }
                    } break;
                }
            }
        }
        else if (ARG && ID >= SPAWN)
        {
            if (ID >= NORTH && ID <= PHASE)
            {
                GameObject* target = GetObjectByGObjectID(player, GObjectID, isHex);
                if (!target)
                    ChatHandler(player->GetSession()).PSendSysMessage("Object GUID: %u not found. Temporary: %s", GObjectID, isHex ? "true" : "false");
                else
                {
                    float x,y,z,o;
                    target->GetPosition(x,y,z,o);
                    uint32 p = target->GetPhaseMask();
                    switch(ID)
                    {
                    case NORTH: SpawnObject(player,x+((float)ARG/100),y,z,o,p,true,GObjectID, isHex);                        break;
                    case EAST: SpawnObject(player,x,y-((float)ARG/100),z,o,p,true,GObjectID, isHex);                         break;
                    case SOUTH: SpawnObject(player,x-((float)ARG/100),y,z,o,p,true,GObjectID, isHex);                        break;
                    case WEST: SpawnObject(player,x,y+((float)ARG/100),z,o,p,true,GObjectID, isHex);                         break;
                    case NORTHEAST: SpawnObject(player,x+((float)ARG/100),y-((float)ARG/100),z,o,p,true,GObjectID, isHex);   break;
                    case SOUTHEAST: SpawnObject(player,x-((float)ARG/100),y-((float)ARG/100),z,o,p,true,GObjectID, isHex);   break;
                    case SOUTHWEST: SpawnObject(player,x-((float)ARG/100),y+((float)ARG/100),z,o,p,true,GObjectID, isHex);   break;
                    case NORTHWEST: SpawnObject(player,x+((float)ARG/100),y+((float)ARG/100),z,o,p,true,GObjectID, isHex);   break;
                    case UP: SpawnObject(player,x,y,z+((float)ARG/100),o,p,true,GObjectID, isHex);                           break;
                    case DOWN: SpawnObject(player,x,y,z-((float)ARG/100),o,p,true,GObjectID, isHex);                         break;
                    case RIGHT: SpawnObject(player,x,y,z,o-((float)ARG/100),p,true,GObjectID, isHex);                        break;
                    case LEFT: SpawnObject(player,x,y,z,o+((float)ARG/100),p,true,GObjectID, isHex);                         break;
                    case PHASE: SpawnObject(player,x,y,z,o,ARG,true,GObjectID, isHex);                                       break;
                    }
                }
            }
            else
            {
                switch(ID)
                {
                case SPAWN:
                    {
                        if (SpawnObject(player, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),  player->GetOrientation(), player->GetPhaseMaskForSpawn(), false, ARG, false, true))
                            SpawnQue[player->GetGUID()] = ARG;
                    } break;
                case SPAWNSPELL:
                    {
                        SpawnQue[player->GetGUID()] = ARG;
                    } break;
                case SELECTALLNEAR:
                    { 
                        if (ARG > 5000)
                            ARG = 5000;

                        QueryResult result = WorldDatabase.PQuery("SELECT guid, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%u' AND position_x BETWEEN '%f'-'%u' AND '%f'+'%u' AND position_y BETWEEN '%f'-'%u' AND '%f'+'%u' AND position_z BETWEEN '%f'-'%u' AND '%f'+'%u' ORDER BY order_ ASC LIMIT 100",
                            player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetPositionX(), ARG, player->GetPositionX(), ARG, player->GetPositionY(), ARG, player->GetPositionY(), ARG, player->GetPositionZ(), ARG, player->GetPositionZ(), ARG);

                        if (result)
                        {
                            do
                            {
                                Field* fields   = result->Fetch();
                                uint32 guidLow  = fields[0].GetUInt32();

                                if (GameObject* object = GetObjectByGObjectID(player, guidLow, false))
                                    SendSelectionInfo(player, guidLow, false, true);
                            }
                            while (result->NextRow());
                        }
                        for(std::set<uint32>::const_iterator it = GObjects.begin(); it != GObjects.end();)
                        {
                            GameObject* temp = player->GetGameObject(*it);
                            if(!temp)
                            {
                                GObjects.erase(*it++);
                                continue;
                            }
                            if(temp->IsWithinDistInMap(player, ARG))
                                SendSelectionInfo(player, (*it), true, true);
                            ++it;
                        }
                    } break;
                }
            }
        }
        else
            return false;
        return true;
    }
    bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 uiAction)
    {
        WorldSession* session = player->GetSession();
        player->PlayerTalkClass->ClearMenus();
        switch(sender)
        {
        case EQUIPMENT_SLOT_END: // Show items you can use
            {
                if (Item* oldItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, uiAction))
                {
                    uint32 lowGUID = player->GetGUIDLow();
                    _items[lowGUID].clear();
                    uint32 limit = 0;
                    uint32 price = 0;
                    switch (sTransmogrification->GetRequireGold())
                    {
                    case 1: { price = (unsigned int)(GetFakePrice(oldItem)*sTransmogrification->GetGoldModifier()); } break;
                    case 2: { price = (unsigned int)sTransmogrification->GetGoldCost(); } break;
                    }
                    char tokenCost[250] = "\n";
                    if(sTransmogrification->GetRequireToken())
                        snprintf(tokenCost, 250, "\n\n%u x %s", sTransmogrification->GetTokenAmount(), GetItemName(sObjectMgr->GetItemTemplate(sTransmogrification->GetTokenEntry()), session).c_str());

                    for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
                    {
                        if (limit > 30)
                            break;
                        if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
                        {
                            uint32 display = newItem->GetTemplate()->DisplayInfoID;
                            if (player->SuitableForTransmogrification(oldItem, newItem) == ERR_FAKE_OK)
                            {
                                if (_items[lowGUID].find(display) == _items[lowGUID].end())
                                {
                                    limit++;
                                    _items[lowGUID][display] = newItem;
                                    player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_INTERACT_1, GetItemName(newItem->GetTemplate(), session), uiAction, display, session->GetTrinityString(LANG_POPUP_TRANSMOGRIFY)+GetItemName(newItem->GetTemplate(), session)+tokenCost, price, false);
                                }
                            }
                        }
                    }

                    for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
                    {
                        if (Bag* bag = player->GetBagByPos(i))
                        {
                            for (uint32 j = 0; j < bag->GetBagSize(); j++)
                            {
                                if (limit > 30)
                                    break;
                                if (Item* newItem = player->GetItemByPos(i, j))
                                {
                                    uint32 display = newItem->GetTemplate()->DisplayInfoID;
                                    if (player->SuitableForTransmogrification(oldItem, newItem) == ERR_FAKE_OK)
                                    {
                                        if (_items[lowGUID].find(display) == _items[lowGUID].end())
                                        {
                                            limit++;
                                            _items[lowGUID][display] = newItem;
                                            player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_INTERACT_1, GetItemName(newItem->GetTemplate(), session), uiAction, display, session->GetTrinityString(LANG_POPUP_TRANSMOGRIFY)+GetItemName(newItem->GetTemplate(), session)+tokenCost, price, false);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    char removeOnePopup[250];
                    snprintf(removeOnePopup, 250, session->GetTrinityString(LANG_POPUP_REMOVE_ONE), GetSlotName(uiAction, session));
                    player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_INTERACT_1, session->GetTrinityString(LANG_OPTION_REMOVE_ONE), EQUIPMENT_SLOT_END+3, uiAction, removeOnePopup, 0, false);
                    player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TALK, session->GetTrinityString(LANG_OPTION_BACK), EQUIPMENT_SLOT_END+1, 0);
                    player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
                }
                else
                    OnGossipHello(player, creature);
            } break;
        case EQUIPMENT_SLOT_END+1: // Back
            {
                OnGossipHello(player, creature);
            } break;
        case EQUIPMENT_SLOT_END+2: // Remove Transmogrifications
            {
                bool removed = false;
                for (uint8 Slot = EQUIPMENT_SLOT_START; Slot < EQUIPMENT_SLOT_END; Slot++)
                {
                    if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, Slot))
                    {
                        if (newItem->DeleteFakeEntry() && !removed)
                            removed = true;
                    }
                }
                if (removed)
                {
                    session->SendAreaTriggerMessage(session->GetTrinityString(LANG_REM_TRANSMOGRIFICATIONS_ITEMS));
                    player->PlayDirectSound(3337);
                }
                else
                    session->SendNotification(session->GetTrinityString(LANG_ERR_NO_TRANSMOGRIFICATIONS));
                OnGossipHello(player, creature);
            } break;
        case EQUIPMENT_SLOT_END+3: // Remove Transmogrification from single item
            {
                if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, uiAction))
                {
                    if (newItem->DeleteFakeEntry())
                    {
                        session->SendAreaTriggerMessage(session->GetTrinityString(LANG_REM_TRANSMOGRIFICATION_ITEM), GetSlotName(uiAction, session));
                        player->PlayDirectSound(3337);
                    }
                    else
                        session->SendNotification(session->GetTrinityString(LANG_ERR_NO_TRANSMOGRIFICATION), GetSlotName(uiAction, session));
                }
                OnGossipSelect(player, creature, EQUIPMENT_SLOT_END, uiAction);
            } break;
        default: // Transmogrify
            {
                uint32 lowGUID = player->GetGUIDLow();
                if(!sTransmogrification->GetRequireToken() || player->GetItemCount(sTransmogrification->GetTokenEntry()) >= sTransmogrification->GetTokenAmount())
                {
                    if (Item* oldItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, sender))
                    {
                        if (_items[lowGUID].find(uiAction) != _items[lowGUID].end() && _items[lowGUID][uiAction]->IsInWorld())
                        {
                            Item* newItem = _items[lowGUID][uiAction];
                            if (newItem->GetOwnerGUID() == player->GetGUIDLow() && (newItem->IsInBag() || newItem->GetBagSlot() == INVENTORY_SLOT_BAG_0) && player->SuitableForTransmogrification(oldItem, newItem) == ERR_FAKE_OK)
                            {
                                switch(sTransmogrification->GetRequireGold())
                                {
                                case 1: { player->ModifyMoney(-1*(uint32)(GetFakePrice(oldItem)*sTransmogrification->GetGoldModifier())); } break;
                                case 2: { player->ModifyMoney(-1*(unsigned int)sTransmogrification->GetGoldCost()); } break;
                                }
                                if(sTransmogrification->GetRequireToken())
                                    player->DestroyItemCount(sTransmogrification->GetTokenEntry(), sTransmogrification->GetTokenAmount(), true);
                                oldItem->SetFakeEntry(newItem->GetEntry());
                                newItem->SetNotRefundable(player);
                                newItem->SetBinding(true);
                                player->PlayDirectSound(3337);
                                session->SendAreaTriggerMessage(session->GetTrinityString(LANG_ITEM_TRANSMOGRIFIED), GetSlotName(sender, session));
                            }
                            else
                                session->SendNotification(session->GetTrinityString(LANG_ERR_NO_ITEM_SUITABLE));
                        }
                        else
                            session->SendNotification(session->GetTrinityString(LANG_ERR_NO_ITEM_EXISTS));
                    }
                    else
                        session->SendNotification(session->GetTrinityString(LANG_ERR_EQUIP_SLOT_EMPTY));
                }
                else
                    session->SendNotification(session->GetTrinityString(LANG_ERR_NO_TOKEN), GetItemName(sObjectMgr->GetItemTemplate(sTransmogrification->GetTokenEntry()), session).c_str());
                _items[lowGUID].clear();
                OnGossipSelect(player, creature, EQUIPMENT_SLOT_END, sender);
            } break;
        }
        return true;
    }
Exemple #10
0
    bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action)
    {
        player->PlayerTalkClass->ClearMenus();
        WorldSession* session = player->GetSession();
        switch(sender)
        {
        case EQUIPMENT_SLOT_END: // Show items you can use
            ShowTransmogItems(player, creature, action);
            break;
        case EQUIPMENT_SLOT_END+1: // Main menu
            OnGossipHello(player, creature);
            break;
        case EQUIPMENT_SLOT_END+2: // Remove Transmogrifications
            {
                bool removed = false;
                SQLTransaction trans = CharacterDatabase.BeginTransaction();
                for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot)
                {
                    if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
                    {
                        if (!sT->GetFakeEntry(newItem->GetGUID()))
                            continue;
                        sT->DeleteFakeEntry(player, slot, newItem, &trans);
                        removed = true;
                    }
                }
                if (removed)
                {
                    session->SendAreaTriggerMessage(GTS(LANG_ERR_UNTRANSMOG_OK));
                    CharacterDatabase.CommitTransaction(trans);
                }
                else
                    session->SendNotification(LANG_ERR_UNTRANSMOG_NO_TRANSMOGS);
                OnGossipHello(player, creature);
            } break;
        case EQUIPMENT_SLOT_END+3: // Remove Transmogrification from single item
            {
                if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, action))
                {
                    if (sT->GetFakeEntry(newItem->GetGUID()))
                    {
                        sT->DeleteFakeEntry(player, action, newItem);
                        session->SendAreaTriggerMessage(GTS(LANG_ERR_UNTRANSMOG_OK));
                    }
                    else
                        session->SendNotification(LANG_ERR_UNTRANSMOG_NO_TRANSMOGS);
                }
                OnGossipSelect(player, creature, EQUIPMENT_SLOT_END, action);
            } break;
#ifdef PRESETS
        case EQUIPMENT_SLOT_END+4: // Presets menu
            {
                if (!sT->GetEnableSets())
                {
                    OnGossipHello(player, creature);
                    return true;
                }
                if (sT->GetEnableSetInfo())
                    player->ADD_GOSSIP_ITEM(GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/INV_Misc_Book_11:30:30:-18:0|tHow sets work", EQUIPMENT_SLOT_END+10, 0);
                for (Transmogrification::presetIdMap::const_iterator it = sT->presetByName[player->GetGUID()].begin(); it != sT->presetByName[player->GetGUID()].end(); ++it)
                    player->ADD_GOSSIP_ITEM(GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/INV_Misc_Statue_02:30:30:-18:0|t"+it->second, EQUIPMENT_SLOT_END+6, it->first);

                if (sT->presetByName[player->GetGUID()].size() < sT->GetMaxSets())
                    player->ADD_GOSSIP_ITEM(GOSSIP_ICON_MONEY_BAG, "|TInterface/GuildBankFrame/UI-GuildBankFrame-NewTab:30:30:-18:0|tSave set", EQUIPMENT_SLOT_END+8, 0);
                player->ADD_GOSSIP_ITEM(GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", EQUIPMENT_SLOT_END+1, 0);
                player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
            } break;
        case EQUIPMENT_SLOT_END+5: // Use preset
            {
                if (!sT->GetEnableSets())
                {
                    OnGossipHello(player, creature);
                    return true;
                }
                // action = presetID
                for (Transmogrification::slotMap::const_iterator it = sT->presetById[player->GetGUID()][action].begin(); it != sT->presetById[player->GetGUID()][action].end(); ++it)
                {
                    if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, it->first))
                        sT->PresetTransmog(player, item, it->second, it->first);
                }
                OnGossipSelect(player, creature, EQUIPMENT_SLOT_END+6, action);
            } break;
        case EQUIPMENT_SLOT_END+6: // view preset
            {
                if (!sT->GetEnableSets())
                {
                    OnGossipHello(player, creature);
                    return true;
                }
                // action = presetID
                for (Transmogrification::slotMap::const_iterator it = sT->presetById[player->GetGUID()][action].begin(); it != sT->presetById[player->GetGUID()][action].end(); ++it)
                    player->ADD_GOSSIP_ITEM(GOSSIP_ICON_MONEY_BAG, sT->GetItemIcon(it->second, 30, 30, -18, 0)+sT->GetItemLink(it->second, session), sender, action);

                player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/INV_Misc_Statue_02:30:30:-18:0|tUse set", EQUIPMENT_SLOT_END+5, action, "Using this set for transmogrify will bind transmogrified items to you and make them non-refundable and non-tradeable.\nDo you wish to continue?\n\n"+sT->presetByName[player->GetGUID()][action], 0, false);
                player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_MONEY_BAG, "|TInterface/PaperDollInfoFrame/UI-GearManager-LeaveItem-Opaque:30:30:-18:0|tDelete set", EQUIPMENT_SLOT_END+7, action, "Are you sure you want to delete "+sT->presetByName[player->GetGUID()][action]+"?", 0, false);
                player->ADD_GOSSIP_ITEM(GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", EQUIPMENT_SLOT_END+4, 0);
                player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
            } break;
        case EQUIPMENT_SLOT_END+7: // Delete preset
            {
                if (!sT->GetEnableSets())
                {
                    OnGossipHello(player, creature);
                    return true;
                }
                // action = presetID
                CharacterDatabase.PExecute("DELETE FROM `custom_transmogrification_sets` WHERE Owner = %u AND PresetID = %u",  player->GetGUIDLow(), action);
                sT->presetById[player->GetGUID()][action].clear();
                sT->presetById[player->GetGUID()].erase(action);
                sT->presetByName[player->GetGUID()].erase(action);

                OnGossipSelect(player, creature, EQUIPMENT_SLOT_END+4, 0);
            } break;
        case EQUIPMENT_SLOT_END+8: // Save preset
            {
                if (!sT->GetEnableSets() || sT->presetByName[player->GetGUID()].size() >= sT->GetMaxSets())
                {
                    OnGossipHello(player, creature);
                    return true;
                }
                uint32 cost = 0;
                bool canSave = false;
                for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot)
                {
                    if (!sT->GetSlotName(slot, session))
                        continue;
                    if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
                    {
                        uint32 entry = sT->GetFakeEntry(newItem->GetGUID());
                        if (!entry)
                            continue;
                        const ItemTemplate* temp = sObjectMgr->GetItemTemplate(entry);
                        if (!temp)
                            continue;
                        if (!sT->SuitableForTransmogrification(player, temp)) // no need to check?
                            continue;
                        cost += sT->GetSpecialPrice(temp);
                        canSave = true;
                        player->ADD_GOSSIP_ITEM(GOSSIP_ICON_MONEY_BAG, sT->GetItemIcon(entry, 30, 30, -18, 0)+sT->GetItemLink(entry, session), EQUIPMENT_SLOT_END+8, 0);
                    }
                }
                if (canSave)
                    player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_MONEY_BAG, "|TInterface/GuildBankFrame/UI-GuildBankFrame-NewTab:30:30:-18:0|tSave set", 0, 0, "Insert set name", cost*sT->GetSetCostModifier()+sT->GetSetCopperCost(), true);
                player->ADD_GOSSIP_ITEM(GOSSIP_ICON_MONEY_BAG, "|TInterface/PaperDollInfoFrame/UI-GearManager-Undo:30:30:-18:0|tUpdate menu", sender, action);
                player->ADD_GOSSIP_ITEM(GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", EQUIPMENT_SLOT_END+4, 0);
                player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
            } break;
        case EQUIPMENT_SLOT_END+10: // Set info
            {
                player->ADD_GOSSIP_ITEM(GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", EQUIPMENT_SLOT_END+4, 0);
                player->SEND_GOSSIP_MENU(sT->GetSetNpcText(), creature->GetGUID());
            } break;
#endif
        case EQUIPMENT_SLOT_END+9: // Transmog info
            {
                player->ADD_GOSSIP_ITEM(GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", EQUIPMENT_SLOT_END+1, 0);
                player->SEND_GOSSIP_MENU(sT->GetTransmogNpcText(), creature->GetGUID());
            } break;
        default: // Transmogrify
            {
                if (!sender && !action)
                {
                    OnGossipHello(player, creature);
                    return true;
                }
                // sender = slot, action = display
                TransmogTrinityStrings res = sT->Transmogrify(player, MAKE_NEW_GUID(action, 0, HIGHGUID_ITEM), sender);
                if (res == LANG_ERR_TRANSMOG_OK)
                    session->SendAreaTriggerMessage(GTS(LANG_ERR_TRANSMOG_OK));
                else
                    session->SendNotification(res);
                // OnGossipSelect(player, creature, EQUIPMENT_SLOT_END, sender);
                // ShowTransmogItems(player, creature, sender);
                player->CLOSE_GOSSIP_MENU(); // Wait for SetMoney to get fixed, issue #10053
            } break;
        }
        return true;
    }
Exemple #11
0
void WorldSocket::InformationRetreiveCallback(WorldPacket & recvData, uint32 requestid)
{
	if(requestid != mRequestID)
		return;

	uint32 error;
	recvData >> error;

	if(error != 0 || pAuthenticationPacket == NULL)
	{
		// something happened wrong @ the logon server
		OutPacket(SMSG_AUTH_RESPONSE, 1, "\x0D");
		return;
	}

	// Extract account information from the packet.
	string AccountName;
	const string * ForcedPermissions;
	uint32 AccountID;
	string GMFlags;
	uint8 AccountFlags;
	string lang = "enUS";
	uint32 i;

	recvData >> AccountID >> AccountName >> GMFlags >> AccountFlags;
	ForcedPermissions = sLogonCommHandler.GetForcedPermissions(AccountName);
	if( ForcedPermissions != NULL )
		GMFlags.assign(ForcedPermissions->c_str());

	DEBUG_LOG( "WorldSocket","Received information packet from logon: `%s` ID %u (request %u)", AccountName.c_str(), AccountID, mRequestID);

	mRequestID = 0;
	// Pull the session key.

	BigNumber BNK;
	recvData.read(K, 40);
	_crypt.Init(K);
	BNK.SetBinary(K, 40);

	//checking if player is already connected
	//disconnect current player and login this one(blizzlike)

	if(recvData.rpos() != recvData.wpos())
		recvData.read((uint8*)lang.data(), 4);

	WorldSession *session = NULL;
	session = sWorld.FindSession( AccountID );
	if( session != NULL )
	{
		if(session->_player != NULL && session->_player->GetMapMgr() == NULL)
		{
			DEBUG_LOG("WorldSocket","_player found without m_mapmgr during logon, trying to remove him [player %s, map %d, instance %d].", session->_player->GetName(), session->_player->GetMapId(), session->_player->GetInstanceID() );
			if(objmgr.GetPlayer(session->_player->GetLowGUID()))
				objmgr.RemovePlayer(session->_player);
			session->LogoutPlayer(false);
		}
		// AUTH_FAILED = 0x0D
		session->Disconnect();

		// clear the logout timer so he times out straight away
		session->SetLogoutTimer(1);

		// we must send authentication failed here.
		// the stupid newb can relog his client.
		// otherwise accounts dupe up and disasters happen.
		OutPacket(SMSG_AUTH_RESPONSE, 1, "\x15");
		return;
	}

	Sha1Hash sha;

	uint8 digest[20];
	pAuthenticationPacket->read(digest, 20);

	uint32 t = 0;
	if( m_fullAccountName == NULL )				// should never happen !
		sha.UpdateData(AccountName);
	else
	{
		sha.UpdateData(*m_fullAccountName);
		
		// this is unused now. we may as well free up the memory.
		delete m_fullAccountName;
		m_fullAccountName = NULL;
	}

	sha.UpdateData((uint8 *)&t, 4);
	sha.UpdateData((uint8 *)&mClientSeed, 4);
	sha.UpdateData((uint8 *)&mSeed, 4);
	sha.UpdateBigNumbers(&BNK, NULL);
	sha.Finalize();

	if (memcmp(sha.GetDigest(), digest, 20))
	{
		// AUTH_UNKNOWN_ACCOUNT = 21
		OutPacket(SMSG_AUTH_RESPONSE, 1, "\x15");
		return;
	}

	// Allocate session
	WorldSession * pSession = new WorldSession(AccountID, AccountName, this);
	mSession = pSession;
	ASSERT(mSession);
	pSession->deleteMutex.Acquire();

	// Set session properties
	pSession->permissioncount = 0; // just to make sure it's 0
	pSession->SetClientBuild(mClientBuild);
	pSession->LoadSecurity(GMFlags);
	pSession->SetAccountFlags(AccountFlags);
	pSession->m_lastPing = (uint32)UNIXTIME;

	if(recvData.rpos() != recvData.wpos())
		recvData >> pSession->m_muted;

	for(uint32 i = 0; i < 8; i++)
		pSession->SetAccountData(i, NULL, true, 0);

	if(sWorld.m_useAccountData)
	{
		QueryResult * pResult = CharacterDatabase.Query("SELECT * FROM account_data WHERE acct = %u", AccountID);
		if( pResult == NULL )
			CharacterDatabase.Execute("INSERT INTO account_data VALUES(%u, '', '', '', '', '', '', '', '', '')", AccountID);
		else
		{
			char * d;
			size_t len;
			const char * data;
			for(i = 0; i < 8; i++)
			{
				data = pResult->Fetch()[1+i].GetString();
				len = data ? strlen(data) : 0;
				if(len > 1)
				{
					d = new char[len+1];
					memcpy(d, data, len+1);
					pSession->SetAccountData(i, d, true, (uint32)len);
				}
			}

			delete pResult;
		}
	}

	DEBUG_LOG("Auth", "%s from %s:%u [%ums]", AccountName.c_str(), GetRemoteIP().c_str(), GetRemotePort(), _latency);
#ifdef SESSION_CAP
	if( sWorld.GetSessionCount() >= SESSION_CAP )
	{
		OutPacket(SMSG_AUTH_RESPONSE, 1, "\x0D");
		Disconnect();
		return;
	}
#endif

	// Check for queue.
	if( (sWorld.GetSessionCount() < sWorld.GetPlayerLimit()) || pSession->HasGMPermissions() ) 
		Authenticate();
	else
	{
		// Queued, sucker.
		uint32 Position = sWorld.AddQueuedSocket(this);
		mQueued = true;
		DEBUG_LOG("Queue", "%s added to queue in position %u", AccountName.c_str(), Position);

		// Send packet so we know what we're doing
		UpdateQueuePosition(Position);
	}

	pSession->deleteMutex.Release();
}
Exemple #12
0
    bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action)
    {
        WorldSession* session = player->GetSession();
        player->PlayerTalkClass->ClearMenus();
        switch(sender)
        {
        case SENDER_SELECT_VENDOR: // action = slot
            {
                Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, action);
                if (!item)
                {
                    if (const char* slotname = getSlotName(action))
                        session->SendNotification("No item equipped in %s slot", slotname);
                    OnGossipHello(player, creature);
                    return true;
                }
                const ItemTemplate * itemTemplate = item->GetTemplate();
                optionData* oM = &optionMap[(itemTemplate->Class == ITEM_CLASS_WEAPON ? MAX_ITEM_SUBCLASS_WEAPON : 0)+itemTemplate->SubClass][getCorrectInvType(itemTemplate->InventoryType)];
                if (!oM->size())
                {
                    if (const char* slotname = getSlotName(action))
                        session->SendNotification("No transmogrifications available for %s", slotname);
                    OnGossipHello(player, creature);
                    return true;
                }
                player->ADD_GOSSIP_ITEM(GOSSIP_ICON_INTERACT_1, (std::string)"Update selected; "+getItemName(itemTemplate, session), sender, action);
                for(optionData::iterator it = oM->begin(); it != oM->end(); ++it)
                {
                    if (!TransmogDisplayVendorMgr::AllowedQuality(it->first)) // skip not allowed qualities
                        continue;
                    for(uint32 count = 0; count*MAX_VENDOR_ITEMS < it->second.size(); ++count)
                    {
                        std::ostringstream ss;
                        ss << getQualityName(it->first);
                        if (count)
                            ss << " [" << count << "]";
                        player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, ss.str().c_str(), it->first, count*MAX_VENDOR_ITEMS);
                    }
                }
                if (player->PlayerTalkClass->GetGossipMenu().GetMenuItemCount() <= 1)
                {
                    if (const char* slotname = getSlotName(action))
                        session->SendNotification("No transmogrifications available for %s", slotname);
                    player->PlayerTalkClass->ClearMenus();
                    OnGossipHello(player, creature);
                    return true;
                }
                selDataStruct temp = {action, 0, 0}; // slot, offset, quality
                selData[player->GetGUIDLow()] = temp;
                player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TALK, "Back..", SENDER_BACK, 0);
                player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
            } break;
        case SENDER_BACK: // Back
            {
                OnGossipHello(player, creature);
            } break;
        case SENDER_REMOVE_ALL: // Remove TransmogDisplayVendorMgrs
            {
                bool removed = false;
                for (uint8 Slot = EQUIPMENT_SLOT_START; Slot < EQUIPMENT_SLOT_END; Slot++)
                {
                    if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, Slot))
                    {
                        if (TransmogDisplayVendorMgr::DeleteFakeEntry(newItem) && !removed)
                            removed = true;
                    }
                }
                if (removed)
                {
                    session->SendAreaTriggerMessage("Transmogrifications removed from equipped items");
                    player->PlayDirectSound(3337);
                }
                else
                    session->SendNotification("You have no transmogrified items equipped");
                OnGossipSelect(player, creature, SENDER_REMOVE_MENU, 0);
            } break;
        case SENDER_REMOVE_ONE: // Remove TransmogDisplayVendorMgr from single item
            {
                const char* slotname = getSlotName(action);
                if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, action))
                {
                    if (TransmogDisplayVendorMgr::DeleteFakeEntry(newItem))
                    {
                        if (slotname)
                            session->SendAreaTriggerMessage("%s transmogrification removed", slotname);
                        player->PlayDirectSound(3337);
                    }
                    else if (slotname)
                        session->SendNotification("No transmogrification on %s slot", slotname);
                }
                else if (slotname)
                    session->SendNotification("No item equipped in %s slot", slotname);
                OnGossipSelect(player, creature, SENDER_REMOVE_MENU, 0);
            } break;
        case SENDER_REMOVE_MENU:
            {
                for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; slot++)
                {
                    const char* slotname = getSlotName(slot);
                    if (!slotname)
                        continue;
                    std::ostringstream ss;
                    ss << "Remove transmogrification from " << slotname << "?";
                    player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_INTERACT_1, (std::string)"Remove from "+slotname, SENDER_REMOVE_ONE, slot, ss.str().c_str(), 0, false);
                }
                player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_INTERACT_1, "Remove all transmogrifications", SENDER_REMOVE_ALL, 0, "Are you sure you want to remove all transmogrifications?", 0, false);
                player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TALK, "Back..", SENDER_BACK, 0);
                player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
            } break;
        default: // Show items you can use
            {
                if (sender >= MAX_ITEM_QUALITY) // sender = quality, action = iterator
                    return false; // cheat
                if (selData.find(player->GetGUIDLow()) == selData.end())
                    return false; // cheat
                if (selData[player->GetGUIDLow()].offset != 0 || selData[player->GetGUIDLow()].quality != 0)
                    return false; // cheat (something is off)
                selData[player->GetGUIDLow()].offset = action;
                selData[player->GetGUIDLow()].quality = sender;
                uint32 slot = selData[player->GetGUIDLow()].slot; // slot
                if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
                {
                    if (!TransmogDisplayVendorMgr::AllowedQuality(item->GetTemplate()->Quality))
                    {
                        session->SendNotification("Equipped item has wrong quality");
                        OnGossipSelect(player, creature, SENDER_SELECT_VENDOR, slot);
                        return true;
                    }
                    optionDataList oM = optionMap[(item->GetTemplate()->Class == ITEM_CLASS_WEAPON ? MAX_ITEM_SUBCLASS_WEAPON : 0)+item->GetTemplate()->SubClass][getCorrectInvType(item->GetTemplate()->InventoryType)][sender];
                    uint32 itemCount = (oM.size()-action);
                    if (itemCount > MAX_VENDOR_ITEMS)
                        itemCount = MAX_VENDOR_ITEMS;
                    if (!itemCount)
                    {
                        session->SendAreaTriggerMessage("No items found");
                        OnGossipSelect(player, creature, SENDER_SELECT_VENDOR, slot);
                        return true;
                    }
                    player->CLOSE_GOSSIP_MENU();

                    TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_LIST_INVENTORY");

                    Creature* vendor = player->GetNPCIfCanInteractWith(creature->GetGUID(), UNIT_NPC_FLAG_VENDOR);
                    if (!vendor)
                    {
                        TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: SendListInventory - Unit (GUID: %u) not found or you can not interact with him.", creature->GetGUIDLow());
                        player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, 0, 0);
                        return true;
                    }

                    if (player->HasUnitState(UNIT_STATE_DIED))
                        player->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);

                    if (vendor->HasUnitState(UNIT_STATE_MOVING))
                        vendor->StopMoving();
                    uint8 count = 0;

                    WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + itemCount * 8 * 4);
                    data << uint64(creature->GetGUID());

                    size_t countPos = data.wpos();
                    data << uint8(count);

                    bool added = false;
                    optionDataList::iterator it = oM.begin();
                    std::advance(it, action);
                    for (; it != oM.end() && count < itemCount; ++it, ++count)
                    {
                        if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(*it))
                        {
                            data << uint32(count + 1);
                            data << uint32(itemTemplate->ItemId);
                            data << uint32(itemTemplate->DisplayInfoID);
                            data << int32(0xFFFFFFFF);
                            data << uint32(0);
                            data << uint32(itemTemplate->MaxDurability);
                            data << uint32(itemTemplate->BuyCount);
                            data << uint32(0);
                            added = true;
                        }
                    }

                    if (!added)
                    {
                        data << uint8(0);
                        session->SendPacket(&data);
                    }
                    else
                    {
                        data.put<uint8>(countPos, count);
                        session->SendPacket(&data);
                    }
                }
                else
                {
                    session->SendNotification("No item equipped");
                    OnGossipSelect(player, creature, SENDER_SELECT_VENDOR, slot);
                    return true;
                }
            } break;
        }
        return true;
    }
Exemple #13
0
void TransmogDisplayVendorMgr::HandleTransmogrify(Player* player, Creature* creature, uint32 vendorslot, uint32 itemEntry)
{
    selDataType::iterator data = selData.find(player->GetGUIDLow());
    if (data == selData.end())
        return; // cheat, no slot selected

    const char* slotname = getSlotName(data->second.slot);
    if (!slotname)
        return;

    WorldSession* session = player->GetSession();
    Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, data->second.slot);
    if (!item)
    {
        session->SendNotification("Equipment slot is empty");
        return;
    }
    if (item->GetOwnerGUID() != player->GetGUID())
        return;

    ItemTemplate const * srcTemplate = sObjectMgr->GetItemTemplate(itemEntry);
    ItemTemplate const * tarTemplate = item->GetTemplate();

    optionDataList oM = optionMap[(tarTemplate->Class == ITEM_CLASS_WEAPON ? MAX_ITEM_SUBCLASS_WEAPON : 0)+tarTemplate->SubClass][getCorrectInvType(tarTemplate->InventoryType)][data->second.quality];
    optionDataList::iterator it = oM.begin();
    std::advance(it, data->second.offset + vendorslot);
    if (it == oM.end() || (*it) != itemEntry)
    {
        session->SendNotification("Items do not match");
        return; // either cheat or changed items (not found in correct place in transmog vendor view)
    }

    if (!TransmogDisplayVendorMgr::CanTransmogrify(tarTemplate, srcTemplate))
    {
        session->SendNotification("Items do not match");
        return;
    }

    if (uint32 fakeEntry = GetFakeEntry(item->GetGUIDLow()))
    {
        if (const ItemTemplate* fakeItemTemplate = sObjectMgr->GetItemTemplate(fakeEntry))
        {
            if (fakeItemTemplate->DisplayInfoID == srcTemplate->DisplayInfoID)
            {
                session->SendAreaTriggerMessage("%s already transmogrified with %s", slotname, getItemName(tarTemplate, session).c_str());
                return;
            }
        }
    }

    if (TransmogDisplayVendorMgr::RequireToken && player->GetItemCount(TransmogDisplayVendorMgr::TokenEntry) < TransmogDisplayVendorMgr::TokenAmount)
    {
        session->SendNotification("You don't have enough %ss", getItemName(sObjectMgr->GetItemTemplate(TransmogDisplayVendorMgr::TokenEntry), session).c_str());
        return;
    }
    int32 price = 0;
    if (TransmogDisplayVendorMgr::RequireGold)
        price = getFakePrice(tarTemplate);
    if (player->HasEnoughMoney(price))
        player->ModifyMoney(-price);
    else
    {
        session->SendNotification("You don't have enough money");
        return;
    }
    if (TransmogDisplayVendorMgr::RequireToken)
        player->DestroyItemCount(TransmogDisplayVendorMgr::TokenEntry, TransmogDisplayVendorMgr::TokenAmount, true);

    TransmogDisplayVendorMgr::SetFakeEntry(item, itemEntry);
    player->PlayDirectSound(3337);
    session->SendAreaTriggerMessage("%s transmogrified", slotname);
}
Exemple #14
0
void ObjectUpdaterThread::Do()
{
    uint32 last_time = getMSTime();
    uint32 last_cTime = getMSTime();
    uint32 last_gTime = getMSTime();
    uint32 diff = 0;
    uint32 mstime = getMSTime();
    uint32 cFlipper = 1;
    uint32 gFlipper = 3;
    uint32 mapid = m_MapMgr->GetMapId();
    Creature * pCreature;
    GameObject * pGameObject;

    int result;

    int objectUpdate = 1;
    UpdateableCreaturesSet::iterator citr, citr_end, citr_last;
    UpdateableGameobjectsSet::iterator gitr, gitr_end, gitr_last;
    PlayerSet::iterator pitr, pitr_end;
    Player * pPlayer;

    SessionSet::iterator itr, it2;
    WorldSession *session;

    while(ThreadState != WOWD_THREADSTATE_TERMINATE)
    {
        // Provision for pausing this thread.
        if(ThreadState == WOWD_THREADSTATE_PAUSED)
        {
            while(ThreadState == WOWD_THREADSTATE_PAUSED)
            {
                Sleep(200);
            }
        }

        mstime = getMSTime();
        last_time = mstime;

        if(cFlipper == 1)
        {
            citr_end = creatures.end();

            // possible uint32 overflow ~50days
            if(last_cTime > mstime)
                diff = 100;
            else
                diff = mstime - last_cTime;

            citr_end = creatures.end();
            for(citr = creatures.begin(); citr != citr_end;)
            {
                pCreature = (*citr);
                citr_last = citr;
                ++citr;
                if(!pCreature->IsInWorld() || !pCreature->GetMapCell()->IsActive())
                {
                    creatureLock.Acquire();
                    creatures.erase(citr_last);
                    creatureLock.Release();
                }
                else
                    pCreature->Update(diff);
            }
            cFlipper = 0;   // 2 loops away now. :)
            
            // update event holder
            eventholder->Update(diff);

            // update players
            pitr_end = m_MapMgr->_players.end();
            pitr = m_MapMgr->_players.begin();
            for(; pitr != pitr_end;)
            {
                pPlayer = (*pitr);
                ++pitr;
                pPlayer->Update(diff);                
            }

            last_cTime = mstime;
        } else {
            cFlipper = 1;   // Next loop we can have our cake. :)
        }

        if(gFlipper == 3)
        {
            if(last_gTime > mstime)
                diff = 300;
            else
                diff = mstime - last_gTime;

            gitr_end = gameobjects.end();
            for(gitr = gameobjects.begin(); gitr != gitr_end;)
            {
                pGameObject = (*gitr);
                gitr_last = gitr;
                ++gitr;
                if(!pGameObject->IsInWorld() || !pGameObject->GetMapCell()->IsActive())
                {
                    gameobjectLock.Acquire();
                    gameobjects.erase(gitr_last);
                    gameobjectLock.Release();
                }
                else
                    pGameObject->Update(diff);
            }
            gFlipper = 0;
            last_gTime = mstime;
        } else {
            ++gFlipper;
        }

        for(itr = m_MapMgr->Sessions.begin(); itr != m_MapMgr->Sessions.end();)
        {
            session = (*itr);
            it2 = itr;
            ++itr;

            if(result = session->Update(50, m_MapMgr->GetMapId()))
            {
                if(result == 1)
                {
                    // complete deletion
                    sWorld.DeleteSession(session);
                }
                m_MapMgr->Sessions.erase(it2);
            }
        }

        // instance thread object updates are done here
        if(mapid > 1 && mapid != 530)
            m_MapMgr->_UpdateObjects();        

        // Execution time compensation. :)
        mstime = getMSTime();
        if(last_time > mstime)
        {
            Sleep(MAPMGR_SESSION_UPDATE_DELAY);    // uint32 overflow
        }
        else
        {
            mstime = mstime - last_time;
            if(mstime < MAPMGR_SESSION_UPDATE_DELAY)
            {
                mstime = MAPMGR_SESSION_UPDATE_DELAY - mstime;
                if(mstime > 20)
                    Sleep(mstime);
            }
        }
    }
}
void WSClient::OnRecvData()
{
	for(;;)
	{
		if(!_cmd)
		{
			if(GetReadBuffer()->GetSize() < 6)
				break;

			Read((uint8*)&_cmd, 2);
			Read((uint8*)&_remaining, 4);
		}

		if(_remaining && GetReadBuffer()->GetSize() < _remaining)
			return;

		if(_cmd == SMSGR_WOW_PACKET)
		{
			uint32 sid = 0;
			uint16 op = 0;
			uint32 sz = 0;
			Read(&sid, 4);
			Read(&op, 2);
			Read(&sz, 4);

			WorldSession * session = sClusterInterface.GetSession(sid);
			if(session != NULL)
			{
				WorldPacket * pck = new WorldPacket(op, sz);
				if (sz > 0)
				{
					pck->resize(sz);
					Read((void*)pck->contents(), sz);
				}

				if(session)
					session->QueuePacket(pck);
				else
					delete pck;
			}
			_cmd = 0;
			continue;
		}

		WorldPacket * pck = new WorldPacket(_cmd, _remaining);
		_cmd = 0;
		if(_remaining)
		{
			pck->resize(_remaining);
			Read((uint8*)pck->contents(), _remaining);
		}

		/* we could handle auth here */
		switch(_cmd)
		{
		case SMSGR_AUTH_REQUEST:
			sClusterInterface.HandleAuthRequest(*pck);
			delete pck;
			break;
		default:
			sClusterInterface.QueuePacket(pck);
		}
	}
}
Exemple #16
0
void MapMgr::_PerformObjectDuties()
{
	++mLoopCounter;
	uint32 mstime = getMSTime();
	uint32 difftime = mstime - lastUnitUpdate;
	if(difftime > 500)
		difftime = 500;

	// Update any events.
	// we make update of events before objects so in case there are 0 timediff events they do not get deleted after update but on next server update loop
	eventHolder.Update(difftime);

	// Update creatures.
	{
		creature_iterator = activeCreatures.begin();
		Creature* ptr;
		Pet* ptr2;

		for(; creature_iterator != activeCreatures.end();)
		{
			ptr = *creature_iterator;
			++creature_iterator;
			ptr->Update(difftime);
		}

		pet_iterator = m_PetStorage.begin();
		for(; pet_iterator != m_PetStorage.end();)
		{
			ptr2 = pet_iterator->second;
			++pet_iterator;
			ptr2->Update(difftime);
		}
	}

	// Update players.
	{
		PlayerStorageMap::iterator itr = m_PlayerStorage.begin();
		Player* ptr;
		for(; itr != m_PlayerStorage.end();)
		{
			ptr = itr->second;
			++itr;
			ptr->Update(difftime);
		}

		lastUnitUpdate = mstime;
	}

	// Dynamic objects
	//
	// We take the pointer, increment, and update in this order because during the update the DynamicObject might get deleted,
	// rendering the iterator unincrementable. Which causes a crash!
	{
		for(DynamicObjectStorageMap::iterator itr = m_DynamicObjectStorage.begin(); itr != m_DynamicObjectStorage.end();)
		{

			DynamicObject* o = itr->second;
			++itr;

			o->UpdateTargets();
		}
	}

	// Update gameobjects (not on every loop, however)
	if(mLoopCounter % 2)
	{
		difftime = mstime - lastGameobjectUpdate;

		GameObjectSet::iterator itr = activeGameObjects.begin();
		GameObject* ptr;
		for(; itr != activeGameObjects.end();)
		{
			ptr = *itr;
			++itr;
			if(ptr != NULL)
				ptr->Update(difftime);
		}

		lastGameobjectUpdate = mstime;
	}

	// Sessions are updated every loop.
	{
		int result;
		WorldSession* session;
		SessionSet::iterator itr = Sessions.begin();
		SessionSet::iterator it2;

		for(; itr != Sessions.end();)
		{
			session = (*itr);
			it2 = itr;
			++itr;

			if(session->GetInstance() != m_instanceID)
			{
				Sessions.erase(it2);
				continue;
			}

			// Don't update players not on our map.
			// If we abort in the handler, it means we will "lose" packets, or not process this.
			// .. and that could be disastrous to our client :P
			if(session->GetPlayer() && (session->GetPlayer()->GetMapMgr() != this && session->GetPlayer()->GetMapMgr() != 0))
			{
				continue;
			}

			if((result = session->Update(m_instanceID)) != 0)
			{
				if(result == 1)
				{
					// complete deletion
					sWorld.DeleteSession(session);
				}
				Sessions.erase(it2);
			}
		}
	}

	// Finally, A9 Building/Distribution
	_UpdateObjects();
}