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