void HandleVoidStorageTransfer(VoidStorageTransfer voidStorageTransfer) { Player player = GetPlayer(); Creature unit = player.GetNPCIfCanInteractWith(voidStorageTransfer.Npc, NPCFlags.VaultKeeper, NPCFlags2.None); if (!unit) { Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageTransfer - {0} not found or player can't interact with it.", voidStorageTransfer.Npc.ToString()); return; } if (!player.IsVoidStorageUnlocked()) { Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageTransfer - Player ({0}, name: {1}) queried void storage without unlocking it.", player.GetGUID().ToString(), player.GetName()); return; } if (voidStorageTransfer.Deposits.Length > player.GetNumOfVoidStorageFreeSlots()) { SendVoidStorageTransferResult(VoidTransferError.Full); return; } uint freeBagSlots = 0; if (!voidStorageTransfer.Withdrawals.Empty()) { // make this a Player function for (byte i = InventorySlots.BagStart; i < InventorySlots.BagEnd; i++) { Bag bag = player.GetBagByPos(i); if (bag) { freeBagSlots += bag.GetFreeSlots(); } } int inventoryEnd = InventorySlots.ItemStart + _player.GetInventorySlotCount(); for (byte i = InventorySlots.ItemStart; i < inventoryEnd; i++) { if (!player.GetItemByPos(InventorySlots.Bag0, i)) { ++freeBagSlots; } } } if (voidStorageTransfer.Withdrawals.Length > freeBagSlots) { SendVoidStorageTransferResult(VoidTransferError.InventoryFull); return; } if (!player.HasEnoughMoney((voidStorageTransfer.Deposits.Length * SharedConst.VoidStorageStoreItemCost))) { SendVoidStorageTransferResult(VoidTransferError.NotEnoughMoney); return; } VoidStorageTransferChanges voidStorageTransferChanges = new VoidStorageTransferChanges(); byte depositCount = 0; for (int i = 0; i < voidStorageTransfer.Deposits.Length; ++i) { Item item = player.GetItemByGuid(voidStorageTransfer.Deposits[i]); if (!item) { Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageTransfer - {0} {1} wants to deposit an invalid item ({2}).", player.GetGUID().ToString(), player.GetName(), voidStorageTransfer.Deposits[i].ToString()); continue; } VoidStorageItem itemVS = new VoidStorageItem(Global.ObjectMgr.GenerateVoidStorageItemId(), item.GetEntry(), item.GetCreator(), item.GetItemRandomBonusListId(), item.GetModifier(ItemModifier.TimewalkerLevel), item.GetModifier(ItemModifier.ArtifactKnowledgeLevel), item.GetContext(), item.m_itemData.BonusListIDs); VoidItem voidItem; voidItem.Guid = ObjectGuid.Create(HighGuid.Item, itemVS.ItemId); voidItem.Creator = item.GetCreator(); voidItem.Item = new ItemInstance(itemVS); voidItem.Slot = _player.AddVoidStorageItem(itemVS); voidStorageTransferChanges.AddedItems.Add(voidItem); player.DestroyItem(item.GetBagSlot(), item.GetSlot(), true); ++depositCount; } long cost = depositCount * SharedConst.VoidStorageStoreItemCost; player.ModifyMoney(-cost); for (int i = 0; i < voidStorageTransfer.Withdrawals.Length; ++i) { byte slot; VoidStorageItem itemVS = player.GetVoidStorageItem(voidStorageTransfer.Withdrawals[i].GetCounter(), out slot); if (itemVS == null) { Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageTransfer - {0} {1} tried to withdraw an invalid item ({2})", player.GetGUID().ToString(), player.GetName(), voidStorageTransfer.Withdrawals[i].ToString()); continue; } List <ItemPosCount> dest = new List <ItemPosCount>(); InventoryResult msg = player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, itemVS.ItemEntry, 1); if (msg != InventoryResult.Ok) { SendVoidStorageTransferResult(VoidTransferError.InventoryFull); Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageTransfer - {0} {1} couldn't withdraw {2} because inventory was full.", player.GetGUID().ToString(), player.GetName(), voidStorageTransfer.Withdrawals[i].ToString()); return; } Item item = player.StoreNewItem(dest, itemVS.ItemEntry, true, itemVS.RandomBonusListId, null, itemVS.Context, itemVS.BonusListIDs); item.SetCreator(itemVS.CreatorGuid); item.SetBinding(true); GetCollectionMgr().AddItemAppearance(item); voidStorageTransferChanges.RemovedItems.Add(ObjectGuid.Create(HighGuid.Item, itemVS.ItemId)); player.DeleteVoidStorageItem(slot); } SendPacket(voidStorageTransferChanges); SendVoidStorageTransferResult(VoidTransferError.Ok); }
public void LoadRBAC() { ClearRBAC(); Log.outDebug(LogFilter.Rbac, "AccountMgr:LoadRBAC"); uint oldMSTime = Time.GetMSTime(); uint count1 = 0; uint count2 = 0; uint count3 = 0; Log.outDebug(LogFilter.Rbac, "AccountMgr:LoadRBAC: Loading permissions"); SQLResult result = DB.Login.Query("SELECT id, name FROM rbac_permissions"); if (result.IsEmpty()) { Log.outInfo(LogFilter.ServerLoading, "Loaded 0 account permission definitions. DB table `rbac_permissions` is empty."); return; } do { uint id = result.Read <uint>(0); _permissions[id] = new RBACPermission(id, result.Read <string>(1)); ++count1; }while (result.NextRow()); Log.outDebug(LogFilter.Rbac, "AccountMgr:LoadRBAC: Loading linked permissions"); result = DB.Login.Query("SELECT id, linkedId FROM rbac_linked_permissions ORDER BY id ASC"); if (result.IsEmpty()) { Log.outInfo(LogFilter.ServerLoading, "Loaded 0 linked permissions. DB table `rbac_linked_permissions` is empty."); return; } uint permissionId = 0; RBACPermission permission = null; do { uint newId = result.Read <uint>(0); if (permissionId != newId) { permissionId = newId; permission = _permissions[newId]; } uint linkedPermissionId = result.Read <uint>(1); if (linkedPermissionId == permissionId) { Log.outError(LogFilter.Sql, "RBAC Permission {0} has itself as linked permission. Ignored", permissionId); continue; } permission.AddLinkedPermission(linkedPermissionId); ++count2; }while (result.NextRow()); Log.outDebug(LogFilter.Rbac, "AccountMgr:LoadRBAC: Loading default permissions"); result = DB.Login.Query("SELECT secId, permissionId FROM rbac_default_permissions ORDER BY secId ASC"); if (result.IsEmpty()) { Log.outInfo(LogFilter.ServerLoading, "Loaded 0 default permission definitions. DB table `rbac_default_permissions` is empty."); return; } uint secId = 255; do { uint newId = result.Read <uint>(0); if (secId != newId) { secId = newId; } _defaultPermissions.Add((byte)secId, result.Read <uint>(1)); ++count3; }while (result.NextRow()); Log.outInfo(LogFilter.ServerLoading, "Loaded {0} permission definitions, {1} linked permissions and {2} default permissions in {3} ms", count1, count2, count3, Time.GetMSTimeDiffToNow(oldMSTime)); }
void HandleForceSpeedChangeAck(MovementSpeedAck packet) { GetPlayer().ValidateMovementInfo(packet.Ack.movementInfo); // now can skip not our packet if (GetPlayer().GetGUID() != packet.Ack.movementInfo.Guid) { return; } /*----------------*/ // client ACK send one packet for mounted/run case and need skip all except last from its // in other cases anti-cheat check can be fail in false case UnitMoveType move_type; ClientOpcodes opcode = packet.GetOpcode(); switch (opcode) { case ClientOpcodes.MoveForceWalkSpeedChangeAck: move_type = UnitMoveType.Walk; break; case ClientOpcodes.MoveForceRunSpeedChangeAck: move_type = UnitMoveType.Run; break; case ClientOpcodes.MoveForceRunBackSpeedChangeAck: move_type = UnitMoveType.RunBack; break; case ClientOpcodes.MoveForceSwimSpeedChangeAck: move_type = UnitMoveType.Swim; break; case ClientOpcodes.MoveForceSwimBackSpeedChangeAck: move_type = UnitMoveType.SwimBack; break; case ClientOpcodes.MoveForceTurnRateChangeAck: move_type = UnitMoveType.TurnRate; break; case ClientOpcodes.MoveForceFlightSpeedChangeAck: move_type = UnitMoveType.Flight; break; case ClientOpcodes.MoveForceFlightBackSpeedChangeAck: move_type = UnitMoveType.FlightBack; break; case ClientOpcodes.MoveForcePitchRateChangeAck: move_type = UnitMoveType.PitchRate; break; default: Log.outError(LogFilter.Network, "WorldSession.HandleForceSpeedChangeAck: Unknown move type opcode: {0}", opcode); return; } // skip all forced speed changes except last and unexpected // in run/mounted case used one ACK and it must be skipped. m_forced_speed_changes[MOVE_RUN] store both. if (GetPlayer().m_forced_speed_changes[(int)move_type] > 0) { --GetPlayer().m_forced_speed_changes[(int)move_type]; if (GetPlayer().m_forced_speed_changes[(int)move_type] > 0) { return; } } if (!GetPlayer().GetTransport() && Math.Abs(GetPlayer().GetSpeed(move_type) - packet.Speed) > 0.01f) { if (GetPlayer().GetSpeed(move_type) > packet.Speed) // must be greater - just correct { Log.outError(LogFilter.Network, "{0}SpeedChange player {1} is NOT correct (must be {2} instead {3}), force set to correct value", move_type, GetPlayer().GetName(), GetPlayer().GetSpeed(move_type), packet.Speed); GetPlayer().SetSpeedRate(move_type, GetPlayer().GetSpeedRate(move_type)); } else // must be lesser - cheating { Log.outDebug(LogFilter.Server, "Player {0} from account id {1} kicked for incorrect speed (must be {2} instead {3})", GetPlayer().GetName(), GetPlayer().GetSession().GetAccountId(), GetPlayer().GetSpeed(move_type), packet.Speed); GetPlayer().GetSession().KickPlayer(); } } }
void HandleAuctionRemoveItem(AuctionRemoveItem packet) { Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Auctioneer, NPCFlags.Auctioneer); if (!creature) { Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionRemoveItem - {0} not found or you can't interact with him.", packet.Auctioneer.ToString()); return; } // remove fake death if (GetPlayer().HasUnitState(UnitState.Died)) { GetPlayer().RemoveAurasByType(AuraType.FeignDeath); } AuctionHouseObject auctionHouse = Global.AuctionMgr.GetAuctionsMap(creature.getFaction()); AuctionEntry auction = auctionHouse.GetAuction((uint)packet.AuctionItemID); Player player = GetPlayer(); SQLTransaction trans = new SQLTransaction(); if (auction != null && auction.owner == player.GetGUID().GetCounter()) { Item pItem = Global.AuctionMgr.GetAItem(auction.itemGUIDLow); if (pItem) { if (auction.bidder > 0) // If we have a bidder, we have to send him the money he paid { ulong auctionCut = auction.GetAuctionCut(); if (!player.HasEnoughMoney(auctionCut)) //player doesn't have enough money, maybe message needed { return; } Global.AuctionMgr.SendAuctionCancelledToBidderMail(auction, trans); player.ModifyMoney(-(long)auctionCut); } // item will deleted or added to received mail list new MailDraft(auction.BuildAuctionMailSubject(MailAuctionAnswers.Canceled), AuctionEntry.BuildAuctionMailBody(0, 0, auction.buyout, auction.deposit, 0)) .AddItem(pItem) .SendMailTo(trans, new MailReceiver(player), new MailSender(auction), MailCheckMask.Copied); } else { Log.outError(LogFilter.Network, "Auction id: {0} got non existing item (item guid : {1})!", auction.Id, auction.itemGUIDLow); SendAuctionCommandResult(null, AuctionAction.Cancel, AuctionError.DatabaseError); return; } } else { SendAuctionCommandResult(null, AuctionAction.Cancel, AuctionError.DatabaseError); //this code isn't possible ... maybe there should be assert Log.outError(LogFilter.Network, "CHEATER: {0} tried to cancel auction (id: {1}) of another player or auction is null", player.GetGUID().ToString(), packet.AuctionItemID); return; } //inform player, that auction is removed SendAuctionCommandResult(auction, AuctionAction.Cancel, AuctionError.Ok); // Now remove the auction player.SaveInventoryAndGoldToDB(trans); auction.DeleteFromDB(trans); DB.Characters.CommitTransaction(trans); Global.AuctionMgr.RemoveAItem(auction.itemGUIDLow); auctionHouse.RemoveAuction(auction); }
public bool Update(uint diff, PacketFilter updater) { // Update Timeout timer. UpdateTimeOutTime(diff); // Before we process anything: // If necessary, kick the player from the character select screen if (IsConnectionIdle()) { m_Socket[(int)ConnectionType.Realm].CloseSocket(); } WorldPacket firstDelayedPacket = null; uint processedPackets = 0; long currentTime = Time.UnixTime; WorldPacket packet; //Check for any packets they was not recived yet. while (m_Socket[(int)ConnectionType.Realm] != null && !_recvQueue.IsEmpty && (_recvQueue.TryPeek(out packet, updater) && packet != firstDelayedPacket) && _recvQueue.TryDequeue(out packet)) { try { var handler = PacketManager.GetHandler((ClientOpcodes)packet.GetOpcode()); switch (handler.sessionStatus) { case SessionStatus.Loggedin: if (!_player) { if (!m_playerRecentlyLogout) { if (firstDelayedPacket == null) { firstDelayedPacket = packet; } QueuePacket(packet); Log.outDebug(LogFilter.Network, "Re-enqueueing packet with opcode {0} with with status OpcodeStatus.Loggedin. Player is currently not in world yet.", (ClientOpcodes)packet.GetOpcode()); } break; } else if (_player.IsInWorld && AntiDOS.EvaluateOpcode(packet, currentTime)) { handler.Invoke(this, packet); } break; case SessionStatus.LoggedinOrRecentlyLogout: if (!_player && !m_playerRecentlyLogout && !m_playerLogout) { LogUnexpectedOpcode(packet, handler.sessionStatus, "the player has not logged in yet and not recently logout"); } else if (AntiDOS.EvaluateOpcode(packet, currentTime)) { handler.Invoke(this, packet); } break; case SessionStatus.Transfer: if (!_player) { LogUnexpectedOpcode(packet, handler.sessionStatus, "the player has not logged in yet"); } else if (_player.IsInWorld) { LogUnexpectedOpcode(packet, handler.sessionStatus, "the player is still in world"); } else if (AntiDOS.EvaluateOpcode(packet, currentTime)) { handler.Invoke(this, packet); } break; case SessionStatus.Authed: // prevent cheating with skip queue wait if (m_inQueue) { LogUnexpectedOpcode(packet, handler.sessionStatus, "the player not pass queue yet"); break; } if ((ClientOpcodes)packet.GetOpcode() == ClientOpcodes.EnumCharacters) { m_playerRecentlyLogout = false; } if (AntiDOS.EvaluateOpcode(packet, currentTime)) { handler.Invoke(this, packet); } break; default: Log.outError(LogFilter.Network, "Received not handled opcode {0} from {1}", (ClientOpcodes)packet.GetOpcode(), GetPlayerInfo()); break; } } catch (InternalBufferOverflowException ex) { Log.outError(LogFilter.Network, "InternalBufferOverflowException: {0} while parsing {1} from {2}.", ex.Message, (ClientOpcodes)packet.GetOpcode(), GetPlayerInfo()); } catch (EndOfStreamException) { Log.outError(LogFilter.Network, "WorldSession:Update EndOfStreamException occured while parsing a packet (opcode: {0}) from client {1}, accountid={2}. Skipped packet.", (ClientOpcodes)packet.GetOpcode(), GetRemoteAddress(), GetAccountId()); } processedPackets++; if (processedPackets > 100) { break; } } if (m_Socket[(int)ConnectionType.Realm] != null && m_Socket[(int)ConnectionType.Realm].IsOpen() && _warden != null) { _warden.Update(); } ProcessQueryCallbacks(); if (updater.ProcessUnsafe()) { long currTime = Time.UnixTime; // If necessary, log the player out if (ShouldLogOut(currTime) && m_playerLoading.IsEmpty()) { LogoutPlayer(true); } if (m_Socket[(int)ConnectionType.Realm] != null && GetPlayer() && _warden != null) { _warden.Update(); } //- Cleanup socket if need if ((m_Socket[(int)ConnectionType.Realm] != null && !m_Socket[(int)ConnectionType.Realm].IsOpen()) || (m_Socket[(int)ConnectionType.Instance] != null && !m_Socket[(int)ConnectionType.Instance].IsOpen())) { expireTime -= expireTime > diff ? diff : expireTime; if (expireTime < diff || forceExit || !GetPlayer()) { if (m_Socket[(int)ConnectionType.Realm] != null) { m_Socket[(int)ConnectionType.Realm].CloseSocket(); m_Socket[(int)ConnectionType.Realm] = null; } if (m_Socket[(int)ConnectionType.Instance] != null) { m_Socket[(int)ConnectionType.Instance].CloseSocket(); m_Socket[(int)ConnectionType.Instance] = null; } } } if (m_Socket[(int)ConnectionType.Realm] == null) { return(false); //Will remove this session from the world session map } } return(true); }
public void SendLfgTeleportError(LfgTeleportResult err) { Log.outDebug(LogFilter.Lfg, "SMSG_LFG_TELEPORT_DENIED {0} reason: {1}", GetPlayerInfo(), err); SendPacket(new LfgTeleportDenied(err)); }
void HandleAuctionSellItem(AuctionSellItem packet) { foreach (var aitem in packet.Items) { if (aitem.Guid.IsEmpty() || aitem.UseCount == 0 || aitem.UseCount > 1000) { return; } } if (packet.MinBid == 0 || packet.RunTime == 0) { return; } if (packet.MinBid > PlayerConst.MaxMoneyAmount || packet.BuyoutPrice > PlayerConst.MaxMoneyAmount) { Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionSellItem - Player {0} ({1}) attempted to sell item with higher price than max gold amount.", GetPlayer().GetName(), GetPlayer().GetGUID().ToString()); SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError); return; } Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Auctioneer, NPCFlags.Auctioneer); if (!creature) { Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionSellItem - {0} not found or you can't interact with him.", packet.Auctioneer.ToString()); return; } uint houseId = 0; AuctionHouseRecord auctionHouseEntry = Global.AuctionMgr.GetAuctionHouseEntry(creature.getFaction(), ref houseId); if (auctionHouseEntry == null) { Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionSellItem - {0} has wrong faction.", packet.Auctioneer.ToString()); return; } packet.RunTime *= Time.Minute; switch (packet.RunTime) { case 1 * SharedConst.MinAuctionTime: case 2 * SharedConst.MinAuctionTime: case 4 * SharedConst.MinAuctionTime: break; default: return; } if (GetPlayer().HasUnitState(UnitState.Died)) { GetPlayer().RemoveAurasByType(AuraType.FeignDeath); } uint finalCount = 0; foreach (var packetItem in packet.Items) { Item aitem = GetPlayer().GetItemByGuid(packetItem.Guid); if (!aitem) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.ItemNotFound); return; } if (Global.AuctionMgr.GetAItem(aitem.GetGUID().GetCounter()) || !aitem.CanBeTraded() || aitem.IsNotEmptyBag() || aitem.GetTemplate().GetFlags().HasAnyFlag(ItemFlags.Conjured) || aitem.GetUInt32Value(ItemFields.Duration) != 0 || aitem.GetCount() < packetItem.UseCount) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError); return; } finalCount += packetItem.UseCount; } if (packet.Items.Empty()) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError); return; } if (finalCount == 0) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError); return; } // check if there are 2 identical guids, in this case user is most likely cheating for (int i = 0; i < packet.Items.Count; ++i) { for (int j = i + 1; j < packet.Items.Count; ++j) { if (packet.Items[i].Guid == packet.Items[j].Guid) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError); return; } } } foreach (var packetItem in packet.Items) { Item aitem = GetPlayer().GetItemByGuid(packetItem.Guid); if (aitem.GetMaxStackCount() < finalCount) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError); return; } } Item item = GetPlayer().GetItemByGuid(packet.Items[0].Guid); uint auctionTime = (uint)(packet.RunTime * WorldConfig.GetFloatValue(WorldCfg.RateAuctionTime)); AuctionHouseObject auctionHouse = Global.AuctionMgr.GetAuctionsMap(creature.getFaction()); ulong deposit = Global.AuctionMgr.GetAuctionDeposit(auctionHouseEntry, packet.RunTime, item, finalCount); if (!GetPlayer().HasEnoughMoney(deposit)) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.NotEnoughtMoney); return; } AuctionEntry AH = new AuctionEntry(); SQLTransaction trans; if (WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionAuction)) { AH.auctioneer = 23442; ///@TODO - HARDCODED DB GUID, BAD BAD BAD } else { AH.auctioneer = creature.GetSpawnId(); } // Required stack size of auction matches to current item stack size, just move item to auctionhouse if (packet.Items.Count == 1 && item.GetCount() == packet.Items[0].UseCount) { if (HasPermission(RBACPermissions.LogGmTrade)) { Log.outCommand(GetAccountId(), "GM {0} (Account: {1}) create auction: {2} (Entry: {3} Count: {4})", GetPlayerName(), GetAccountId(), item.GetTemplate().GetName(), item.GetEntry(), item.GetCount()); } AH.Id = Global.ObjectMgr.GenerateAuctionID(); AH.itemGUIDLow = item.GetGUID().GetCounter(); AH.itemEntry = item.GetEntry(); AH.itemCount = item.GetCount(); AH.owner = GetPlayer().GetGUID().GetCounter(); AH.startbid = (uint)packet.MinBid; AH.bidder = 0; AH.bid = 0; AH.buyout = (uint)packet.BuyoutPrice; AH.expire_time = Time.UnixTime + auctionTime; AH.deposit = deposit; AH.etime = packet.RunTime; AH.auctionHouseEntry = auctionHouseEntry; Log.outInfo(LogFilter.Network, "CMSG_AUCTION_SELL_ITEM: {0} {1} is selling item {2} {3} to auctioneer {4} with count {5} with initial bid {6} with buyout {7} and with time {8} (in sec) in auctionhouse {9}", GetPlayer().GetGUID().ToString(), GetPlayer().GetName(), item.GetGUID().ToString(), item.GetTemplate().GetName(), AH.auctioneer, item.GetCount(), packet.MinBid, packet.BuyoutPrice, auctionTime, AH.GetHouseId()); Global.AuctionMgr.AddAItem(item); auctionHouse.AddAuction(AH); GetPlayer().MoveItemFromInventory(item.GetBagSlot(), item.GetSlot(), true); trans = new SQLTransaction(); item.DeleteFromInventoryDB(trans); item.SaveToDB(trans); AH.SaveToDB(trans); GetPlayer().SaveInventoryAndGoldToDB(trans); DB.Characters.CommitTransaction(trans); SendAuctionCommandResult(AH, AuctionAction.SellItem, AuctionError.Ok); GetPlayer().UpdateCriteria(CriteriaTypes.CreateAuction, 1); } else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size { Item newItem = item.CloneItem(finalCount, GetPlayer()); if (!newItem) { Log.outError(LogFilter.Network, "CMSG_AuctionAction.SellItem: Could not create clone of item {0}", item.GetEntry()); SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError); return; } if (HasPermission(RBACPermissions.LogGmTrade)) { Log.outCommand(GetAccountId(), "GM {0} (Account: {1}) create auction: {2} (Entry: {3} Count: {4})", GetPlayerName(), GetAccountId(), newItem.GetTemplate().GetName(), newItem.GetEntry(), newItem.GetCount()); } AH.Id = Global.ObjectMgr.GenerateAuctionID(); AH.itemGUIDLow = newItem.GetGUID().GetCounter(); AH.itemEntry = newItem.GetEntry(); AH.itemCount = newItem.GetCount(); AH.owner = GetPlayer().GetGUID().GetCounter(); AH.startbid = (uint)packet.MinBid; AH.bidder = 0; AH.bid = 0; AH.buyout = (uint)packet.BuyoutPrice; AH.expire_time = Time.UnixTime + auctionTime; AH.deposit = deposit; AH.etime = packet.RunTime; AH.auctionHouseEntry = auctionHouseEntry; Log.outInfo(LogFilter.Network, "CMSG_AuctionAction.SellItem: {0} {1} is selling {2} {3} to auctioneer {4} with count {5} with initial bid {6} with buyout {7} and with time {8} (in sec) in auctionhouse {9}", GetPlayer().GetGUID().ToString(), GetPlayer().GetName(), newItem.GetGUID().ToString(), newItem.GetTemplate().GetName(), AH.auctioneer, newItem.GetCount(), packet.MinBid, packet.BuyoutPrice, auctionTime, AH.GetHouseId()); Global.AuctionMgr.AddAItem(newItem); auctionHouse.AddAuction(AH); foreach (var packetItem in packet.Items) { Item item2 = GetPlayer().GetItemByGuid(packetItem.Guid); // Item stack count equals required count, ready to delete item - cloned item will be used for auction if (item2.GetCount() == packetItem.UseCount) { GetPlayer().MoveItemFromInventory(item2.GetBagSlot(), item2.GetSlot(), true); trans = new SQLTransaction(); item2.DeleteFromInventoryDB(trans); item2.DeleteFromDB(trans); DB.Characters.CommitTransaction(trans); } else // Item stack count is bigger than required count, update item stack count and save to database - cloned item will be used for auction { item2.SetCount(item2.GetCount() - packetItem.UseCount); item2.SetState(ItemUpdateState.Changed, GetPlayer()); GetPlayer().ItemRemovedQuestCheck(item2.GetEntry(), packetItem.UseCount); item2.SendUpdateToPlayer(GetPlayer()); trans = new SQLTransaction(); item2.SaveToDB(trans); DB.Characters.CommitTransaction(trans); } } trans = new SQLTransaction(); newItem.SaveToDB(trans); AH.SaveToDB(trans); GetPlayer().SaveInventoryAndGoldToDB(trans); DB.Characters.CommitTransaction(trans); SendAuctionCommandResult(AH, AuctionAction.SellItem, AuctionError.Ok); GetPlayer().UpdateCriteria(CriteriaTypes.CreateAuction, 1); } GetPlayer().ModifyMoney(-(long)deposit); }
void SpawnQuestObject(ActivePoolData spawns, uint limit, ulong triggerFrom) { Log.outDebug(LogFilter.Pool, "PoolGroup<Quest>: Spawning pool {0}", poolId); // load state from db if (triggerFrom == 0) { PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_POOL_QUEST_SAVE); stmt.AddValue(0, poolId); SQLResult result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { do { uint questId = result.Read <uint>(0); spawns.ActivateObject <Quest>(questId, poolId); PoolObject tempObj = new PoolObject(questId, 0.0f); Spawn1Object(tempObj); --limit; } while (result.NextRow() && limit != 0); return; } } List <ulong> currentQuests = spawns.GetActiveQuests(); List <ulong> newQuests = new List <ulong>(); // always try to select different quests foreach (var poolObject in EqualChanced) { if (spawns.IsActiveObject <Quest>(poolObject.guid)) { continue; } newQuests.Add(poolObject.guid); } // clear the pool DespawnObject(spawns); // recycle minimal amount of quests if possible count is lower than limit while (limit > newQuests.Count && !currentQuests.Empty()) { ulong questId = currentQuests.SelectRandom(); newQuests.Add(questId); currentQuests.Remove(questId); } if (newQuests.Empty()) { return; } // activate <limit> random quests do { ulong questId = newQuests.SelectRandom(); spawns.ActivateObject <Quest>(questId, poolId); PoolObject tempObj = new PoolObject(questId, 0.0f); Spawn1Object(tempObj); newQuests.Remove(questId); --limit; } while (limit != 0 && !newQuests.Empty()); // if we are here it means the pool is initialized at startup and did not have previous saved state if (triggerFrom == 0) { Global.PoolMgr.SaveQuestsToDB(); } }
void Spawn1Object(PoolObject obj) { switch (typeof(T).Name) { case "Creature": CreatureData data = Global.ObjectMgr.GetCreatureData(obj.guid); if (data != null) { Global.ObjectMgr.AddCreatureToGrid(obj.guid, data); // Spawn if necessary (loaded grids only) Map map = Global.MapMgr.CreateBaseMap(data.mapid); // We use spawn coords to spawn if (!map.Instanceable() && map.IsGridLoaded(data.posX, data.posY)) { Creature.CreateCreatureFromDB(obj.guid, map); } } break; case "GameObject": GameObjectData data_ = Global.ObjectMgr.GetGOData(obj.guid); if (data_ != null) { Global.ObjectMgr.AddGameObjectToGrid(obj.guid, data_); // Spawn if necessary (loaded grids only) // this base map checked as non-instanced and then only existed Map map = Global.MapMgr.CreateBaseMap(data_.mapid); // We use current coords to unspawn, not spawn coords since creature can have changed grid if (!map.Instanceable() && map.IsGridLoaded(data_.posX, data_.posY)) { GameObject go = GameObject.CreateGameObjectFromDB(obj.guid, map, false); if (go) { if (go.isSpawnedByDefault()) { map.AddToMap(go); } } } } break; case "Pool": Global.PoolMgr.SpawnPool((uint)obj.guid); break; case "Quest": // Creatures var questMap = Global.ObjectMgr.GetCreatureQuestRelationMap(); var qr = Global.PoolMgr.mQuestCreatureRelation.LookupByKey(obj.guid); foreach (var creature in qr) { Log.outDebug(LogFilter.Pool, "PoolGroup<Quest>: Adding quest {0} to creature {1}", obj.guid, creature); questMap.Add(creature, (uint)obj.guid); } // Gameobjects questMap = Global.ObjectMgr.GetGOQuestRelationMap(); qr = Global.PoolMgr.mQuestGORelation.LookupByKey(obj.guid); foreach (var go in qr) { Log.outDebug(LogFilter.Pool, "PoolGroup<Quest>: Adding quest {0} to GO {1}", obj.guid, go); questMap.Add(go, (uint)obj.guid); } break; } }
void HandleBattlemasterJoin(BattlemasterJoin battlemasterJoin) { bool isPremade = false; Group grp = null; BattlefieldStatusFailed battlefieldStatusFailed; uint bgTypeId_ = (uint)(battlemasterJoin.QueueID & 0xFFFF); if (!CliDB.BattlemasterListStorage.ContainsKey(bgTypeId_)) { Log.outError(LogFilter.Network, "Battleground: invalid bgtype ({0}) received. possible cheater? player guid {1}", bgTypeId_, GetPlayer().GetGUID().ToString()); return; } if (Global.DisableMgr.IsDisabledFor(DisableType.Battleground, bgTypeId_, null)) { GetPlayer().SendSysMessage(CypherStrings.BgDisabled); return; } BattlegroundTypeId bgTypeId = (BattlegroundTypeId)bgTypeId_; // can do this, since it's Battleground, not arena BattlegroundQueueTypeId bgQueueTypeId = Global.BattlegroundMgr.BGQueueTypeId(bgTypeId, 0); BattlegroundQueueTypeId bgQueueTypeIdRandom = Global.BattlegroundMgr.BGQueueTypeId(BattlegroundTypeId.RB, 0); // ignore if player is already in BG if (GetPlayer().InBattleground()) { return; } // get bg instance or bg template if instance not found Battleground bg = Global.BattlegroundMgr.GetBattlegroundTemplate(bgTypeId); if (!bg) { return; } // expected bracket entry PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel()); if (bracketEntry == null) { return; } GroupJoinBattlegroundResult err = GroupJoinBattlegroundResult.None; // check queue conditions if (!battlemasterJoin.JoinAsGroup) { if (GetPlayer().isUsingLfg()) { Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.LfgCantUseBattleground); SendPacket(battlefieldStatusFailed); return; } // check Deserter debuff if (!GetPlayer().CanJoinToBattleground(bg)) { Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.Deserters); SendPacket(battlefieldStatusFailed); return; } if (GetPlayer().GetBattlegroundQueueIndex(bgQueueTypeIdRandom) < SharedConst.MaxPlayerBGQueues) { // player is already in random queue Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.InRandomBg); SendPacket(battlefieldStatusFailed); return; } if (GetPlayer().InBattlegroundQueue() && bgTypeId == BattlegroundTypeId.RB) { // player is already in queue, can't start random queue Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.InNonRandomBg); SendPacket(battlefieldStatusFailed); return; } // check if already in queue if (GetPlayer().GetBattlegroundQueueIndex(bgQueueTypeId) < SharedConst.MaxPlayerBGQueues) { return; // player is already in this queue } // check if has free queue slots if (!GetPlayer().HasFreeBattlegroundQueueId()) { Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.TooManyQueues); SendPacket(battlefieldStatusFailed); return; } // check Freeze debuff if (_player.HasAura(9454)) { return; } BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo ginfo = bgQueue.AddGroup(GetPlayer(), null, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); uint avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); uint queueSlot = GetPlayer().AddBattlegroundQueueId(bgQueueTypeId); BattlefieldStatusQueued battlefieldStatusQueued; Global.BattlegroundMgr.BuildBattlegroundStatusQueued(out battlefieldStatusQueued, bg, GetPlayer(), queueSlot, ginfo.JoinTime, avgTime, ginfo.ArenaType, false); SendPacket(battlefieldStatusQueued); Log.outDebug(LogFilter.Battleground, "Battleground: player joined queue for bg queue type {0} bg type {1}: GUID {2}, NAME {3}", bgQueueTypeId, bgTypeId, GetPlayer().GetGUID().ToString(), GetPlayer().GetName()); } else { grp = GetPlayer().GetGroup(); if (!grp) { return; } if (grp.GetLeaderGUID() != GetPlayer().GetGUID()) { return; } ObjectGuid errorGuid; err = grp.CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg.GetMaxPlayersPerTeam(), false, 0, out errorGuid); isPremade = (grp.GetMembersCount() >= bg.GetMinPlayersPerTeam()); BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo ginfo = null; uint avgTime = 0; if (err == 0) { Log.outDebug(LogFilter.Battleground, "Battleground: the following players are joining as group:"); ginfo = bgQueue.AddGroup(GetPlayer(), grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); } for (GroupReference refe = grp.GetFirstMember(); refe != null; refe = refe.next()) { Player member = refe.GetSource(); if (!member) { continue; // this should never happen } if (err != 0) { BattlefieldStatusFailed battlefieldStatus; Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatus, bg, GetPlayer(), 0, 0, err, errorGuid); member.SendPacket(battlefieldStatus); continue; } // add to queue uint queueSlot = member.AddBattlegroundQueueId(bgQueueTypeId); BattlefieldStatusQueued battlefieldStatusQueued; Global.BattlegroundMgr.BuildBattlegroundStatusQueued(out battlefieldStatusQueued, bg, member, queueSlot, ginfo.JoinTime, avgTime, ginfo.ArenaType, true); member.SendPacket(battlefieldStatusQueued); Log.outDebug(LogFilter.Battleground, "Battleground: player joined queue for bg queue type {0} bg type {1}: GUID {2}, NAME {3}", bgQueueTypeId, bgTypeId, member.GetGUID().ToString(), member.GetName()); } Log.outDebug(LogFilter.Battleground, "Battleground: group end"); } Global.BattlegroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry.GetBracketId()); }
public void LoadFromDB() { // Pool templates { uint oldMSTime = Time.GetMSTime(); SQLResult result = DB.World.Query("SELECT entry, max_limit FROM pool_template"); if (result.IsEmpty()) { mPoolTemplate.Clear(); Log.outInfo(LogFilter.ServerLoading, "Loaded 0 object pools. DB table `pool_template` is empty."); return; } uint count = 0; do { uint pool_id = result.Read <uint>(0); PoolTemplateData pPoolTemplate = new PoolTemplateData(); pPoolTemplate.MaxLimit = result.Read <uint>(1); mPoolTemplate[pool_id] = pPoolTemplate; ++count; }while (result.NextRow()); Log.outInfo(LogFilter.ServerLoading, "Loaded {0} objects pools in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime)); } // Creatures Log.outInfo(LogFilter.ServerLoading, "Loading Creatures Pooling Data..."); { uint oldMSTime = Time.GetMSTime(); // 1 2 3 SQLResult result = DB.World.Query("SELECT guid, pool_entry, chance FROM pool_creature"); if (result.IsEmpty()) { Log.outInfo(LogFilter.ServerLoading, "Loaded 0 creatures in pools. DB table `pool_creature` is empty."); } else { uint count = 0; do { ulong guid = result.Read <ulong>(0); uint pool_id = result.Read <uint>(1); float chance = result.Read <float>(2); CreatureData data = Global.ObjectMgr.GetCreatureData(guid); if (data == null) { Log.outError(LogFilter.Sql, "`pool_creature` has a non existing creature spawn (GUID: {0}) defined for pool id ({1}), skipped.", guid, pool_id); continue; } if (!mPoolTemplate.ContainsKey(pool_id)) { Log.outError(LogFilter.Sql, "`pool_creature` pool id ({0}) is not in `pool_template`, skipped.", pool_id); continue; } if (chance < 0 || chance > 100) { Log.outError(LogFilter.Sql, "`pool_creature` has an invalid chance ({0}) for creature guid ({1}) in pool id ({2}), skipped.", chance, guid, pool_id); continue; } PoolTemplateData pPoolTemplate = mPoolTemplate[pool_id]; PoolObject plObject = new PoolObject(guid, chance); if (!mPoolCreatureGroups.ContainsKey(pool_id)) { mPoolCreatureGroups[pool_id] = new PoolGroup <Creature>(); } PoolGroup <Creature> cregroup = mPoolCreatureGroups[pool_id]; cregroup.SetPoolId(pool_id); cregroup.AddEntry(plObject, pPoolTemplate.MaxLimit); mCreatureSearchMap.Add(guid, pool_id); ++count; }while (result.NextRow()); Log.outInfo(LogFilter.ServerLoading, "Loaded {0} creatures in pools in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime)); } } // Gameobjects Log.outInfo(LogFilter.ServerLoading, "Loading Gameobject Pooling Data..."); { uint oldMSTime = Time.GetMSTime(); // 1 2 3 SQLResult result = DB.World.Query("SELECT guid, pool_entry, chance FROM pool_gameobject"); if (result.IsEmpty()) { Log.outInfo(LogFilter.ServerLoading, "Loaded 0 gameobjects in pools. DB table `pool_gameobject` is empty."); } else { uint count = 0; do { ulong guid = result.Read <ulong>(0); uint pool_id = result.Read <uint>(1); float chance = result.Read <float>(2); GameObjectData data = Global.ObjectMgr.GetGOData(guid); if (data == null) { Log.outError(LogFilter.Sql, "`pool_gameobject` has a non existing gameobject spawn (GUID: {0}) defined for pool id ({1}), skipped.", guid, pool_id); continue; } GameObjectTemplate goinfo = Global.ObjectMgr.GetGameObjectTemplate(data.id); if (goinfo.type != GameObjectTypes.Chest && goinfo.type != GameObjectTypes.FishingHole && goinfo.type != GameObjectTypes.GatheringNode && goinfo.type != GameObjectTypes.Goober) { Log.outError(LogFilter.Sql, "`pool_gameobject` has a not lootable gameobject spawn (GUID: {0}, type: {1}) defined for pool id ({2}), skipped.", guid, goinfo.type, pool_id); continue; } if (!mPoolTemplate.ContainsKey(pool_id)) { Log.outError(LogFilter.Sql, "`pool_gameobject` pool id ({0}) is not in `pool_template`, skipped.", pool_id); continue; } if (chance < 0 || chance > 100) { Log.outError(LogFilter.Sql, "`pool_gameobject` has an invalid chance ({0}) for gameobject guid ({1}) in pool id ({2}), skipped.", chance, guid, pool_id); continue; } PoolTemplateData pPoolTemplate = mPoolTemplate[pool_id]; PoolObject plObject = new PoolObject(guid, chance); if (!mPoolGameobjectGroups.ContainsKey(pool_id)) { mPoolGameobjectGroups[pool_id] = new PoolGroup <GameObject>(); } PoolGroup <GameObject> gogroup = mPoolGameobjectGroups[pool_id]; gogroup.SetPoolId(pool_id); gogroup.AddEntry(plObject, pPoolTemplate.MaxLimit); mGameobjectSearchMap.Add(guid, pool_id); ++count; }while (result.NextRow()); Log.outInfo(LogFilter.ServerLoading, "Loaded {0} gameobject in pools in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime)); } } // Pool of pools Log.outInfo(LogFilter.ServerLoading, "Loading Mother Pooling Data..."); { uint oldMSTime = Time.GetMSTime(); // 1 2 3 SQLResult result = DB.World.Query("SELECT pool_id, mother_pool, chance FROM pool_pool"); if (result.IsEmpty()) { Log.outInfo(LogFilter.ServerLoading, "Loaded 0 pools in pools"); } else { uint count = 0; do { uint child_pool_id = result.Read <uint>(0); uint mother_pool_id = result.Read <uint>(1); float chance = result.Read <float>(2); if (!mPoolTemplate.ContainsKey(mother_pool_id)) { Log.outError(LogFilter.Sql, "`pool_pool` mother_pool id ({0}) is not in `pool_template`, skipped.", mother_pool_id); continue; } if (!mPoolTemplate.ContainsKey(child_pool_id)) { Log.outError(LogFilter.Sql, "`pool_pool` included pool_id ({0}) is not in `pool_template`, skipped.", child_pool_id); continue; } if (mother_pool_id == child_pool_id) { Log.outError(LogFilter.Sql, "`pool_pool` pool_id ({0}) includes itself, dead-lock detected, skipped.", child_pool_id); continue; } if (chance < 0 || chance > 100) { Log.outError(LogFilter.Sql, "`pool_pool` has an invalid chance ({0}) for pool id ({1}) in mother pool id ({2}), skipped.", chance, child_pool_id, mother_pool_id); continue; } PoolTemplateData pPoolTemplateMother = mPoolTemplate[mother_pool_id]; PoolObject plObject = new PoolObject(child_pool_id, chance); if (!mPoolPoolGroups.ContainsKey(mother_pool_id)) { mPoolPoolGroups[mother_pool_id] = new PoolGroup <Pool>(); } PoolGroup <Pool> plgroup = mPoolPoolGroups[mother_pool_id]; plgroup.SetPoolId(mother_pool_id); plgroup.AddEntry(plObject, pPoolTemplateMother.MaxLimit); mPoolSearchMap.Add(child_pool_id, mother_pool_id); ++count; }while (result.NextRow()); Log.outInfo(LogFilter.ServerLoading, "Loaded {0} pools in mother pools in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime)); } } Log.outInfo(LogFilter.ServerLoading, "Loading Quest Pooling Data..."); { uint oldMSTime = Time.GetMSTime(); PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.SEL_QUEST_POOLS); SQLResult result = DB.World.Query(stmt); if (result.IsEmpty()) { Log.outInfo(LogFilter.ServerLoading, "Loaded 0 quests in pools"); } else { List <uint> creBounds; List <uint> goBounds; Dictionary <uint, eQuestTypes> poolTypeMap = new Dictionary <uint, eQuestTypes>(); uint count = 0; do { uint entry = result.Read <uint>(0); uint pool_id = result.Read <uint>(1); if (!poolTypeMap.ContainsKey(pool_id)) { poolTypeMap[pool_id] = 0; } Quest quest = Global.ObjectMgr.GetQuestTemplate(entry); if (quest == null) { Log.outError(LogFilter.Sql, "`pool_quest` has a non existing quest template (Entry: {0}) defined for pool id ({1}), skipped.", entry, pool_id); continue; } if (!mPoolTemplate.ContainsKey(pool_id)) { Log.outError(LogFilter.Sql, "`pool_quest` pool id ({0}) is not in `pool_template`, skipped.", pool_id); continue; } if (!quest.IsDailyOrWeekly()) { Log.outError(LogFilter.Sql, "`pool_quest` has an quest ({0}) which is not daily or weekly in pool id ({1}), use ExclusiveGroup instead, skipped.", entry, pool_id); continue; } if (poolTypeMap[pool_id] == eQuestTypes.None) { poolTypeMap[pool_id] = quest.IsDaily() ? eQuestTypes.Daily : eQuestTypes.Weekly; } eQuestTypes currType = quest.IsDaily() ? eQuestTypes.Daily : eQuestTypes.Weekly; if (poolTypeMap[pool_id] != currType) { Log.outError(LogFilter.Sql, "`pool_quest` quest {0} is {1} but pool ({2}) is specified for {3}, mixing not allowed, skipped.", entry, currType, pool_id, poolTypeMap[pool_id]); continue; } creBounds = mQuestCreatureRelation.LookupByKey(entry); goBounds = mQuestGORelation.LookupByKey(entry); if (creBounds.Empty() && goBounds.Empty()) { Log.outError(LogFilter.Sql, "`pool_quest` lists entry ({0}) as member of pool ({1}) but is not started anywhere, skipped.", entry, pool_id); continue; } PoolTemplateData pPoolTemplate = mPoolTemplate[pool_id]; PoolObject plObject = new PoolObject(entry, 0.0f); if (!mPoolQuestGroups.ContainsKey(pool_id)) { mPoolQuestGroups[pool_id] = new PoolGroup <Quest>(); } PoolGroup <Quest> questgroup = mPoolQuestGroups[pool_id]; questgroup.SetPoolId(pool_id); questgroup.AddEntry(plObject, pPoolTemplate.MaxLimit); mQuestSearchMap.Add(entry, pool_id); ++count; }while (result.NextRow()); Log.outInfo(LogFilter.ServerLoading, "Loaded {0} quests in pools in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime)); } } // The initialize method will spawn all pools not in an event and not in another pool, this is why there is 2 left joins with 2 null checks Log.outInfo(LogFilter.ServerLoading, "Starting objects pooling system..."); { uint oldMSTime = Time.GetMSTime(); SQLResult result = DB.World.Query("SELECT DISTINCT pool_template.entry, pool_pool.pool_id, pool_pool.mother_pool FROM pool_template" + " LEFT JOIN game_event_pool ON pool_template.entry=game_event_pool.pool_entry" + " LEFT JOIN pool_pool ON pool_template.entry=pool_pool.pool_id WHERE game_event_pool.pool_entry IS NULL"); if (result.IsEmpty()) { Log.outInfo(LogFilter.ServerLoading, "Pool handling system initialized, 0 pools spawned."); } else { uint count = 0; do { uint pool_entry = result.Read <uint>(0); uint pool_pool_id = result.Read <uint>(1); if (!CheckPool(pool_entry)) { if (pool_pool_id != 0) { // The pool is a child pool in pool_pool table. Ideally we should remove it from the pool handler to ensure it never gets spawned, // however that could recursively invalidate entire chain of mother pools. It can be done in the future but for now we'll do nothing. Log.outError(LogFilter.Sql, "Pool Id {0} has no equal chance pooled entites defined and explicit chance sum is not 100. This broken pool is a child pool of Id {1} and cannot be safely removed.", pool_entry, result.Read <uint>(2)); } else { Log.outError(LogFilter.Sql, "Pool Id {0} has no equal chance pooled entites defined and explicit chance sum is not 100. The pool will not be spawned.", pool_entry); } continue; } // Don't spawn child pools, they are spawned recursively by their parent pools if (pool_pool_id == 0) { SpawnPool(pool_entry); count++; } }while (result.NextRow()); Log.outDebug(LogFilter.Pool, "Pool handling system initialized, {0} pools spawned in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime)); } } }
void HandleBattlemasterJoinArena(BattlemasterJoinArena packet) { // ignore if we already in BG or BG queue if (GetPlayer().InBattleground()) { return; } ArenaTypes arenatype = (ArenaTypes)ArenaTeam.GetTypeBySlot(packet.TeamSizeIndex); //check existence Battleground bg = Global.BattlegroundMgr.GetBattlegroundTemplate(BattlegroundTypeId.AA); if (!bg) { Log.outError(LogFilter.Network, "Battleground: template bg (all arenas) not found"); return; } if (Global.DisableMgr.IsDisabledFor(DisableType.Battleground, (uint)BattlegroundTypeId.AA, null)) { GetPlayer().SendSysMessage(CypherStrings.ArenaDisabled); return; } BattlegroundTypeId bgTypeId = bg.GetTypeID(); BattlegroundQueueTypeId bgQueueTypeId = Global.BattlegroundMgr.BGQueueTypeId(bgTypeId, arenatype); PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel()); if (bracketEntry == null) { return; } Group grp = GetPlayer().GetGroup(); // no group found, error if (!grp) { return; } if (grp.GetLeaderGUID() != GetPlayer().GetGUID()) { return; } uint ateamId = GetPlayer().GetArenaTeamId(packet.TeamSizeIndex); // check real arenateam existence only here (if it was moved to group.CanJoin .. () then we would ahve to get it twice) ArenaTeam at = Global.ArenaTeamMgr.GetArenaTeamById(ateamId); if (at == null) { GetPlayer().GetSession().SendNotInArenaTeamPacket(arenatype); return; } // get the team rating for queuing uint arenaRating = at.GetRating(); uint matchmakerRating = at.GetAverageMMR(grp); // the arenateam id must match for everyone in the group if (arenaRating <= 0) { arenaRating = 1; } BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); uint avgTime = 0; GroupQueueInfo ginfo = null; ObjectGuid errorGuid; var err = grp.CanJoinBattlegroundQueue(bg, bgQueueTypeId, (uint)arenatype, (uint)arenatype, true, packet.TeamSizeIndex, out errorGuid); if (err == 0) { Log.outDebug(LogFilter.Battleground, "Battleground: arena team id {0}, leader {1} queued with matchmaker rating {2} for type {3}", GetPlayer().GetArenaTeamId(packet.TeamSizeIndex), GetPlayer().GetName(), matchmakerRating, arenatype); ginfo = bgQueue.AddGroup(GetPlayer(), grp, bgTypeId, bracketEntry, arenatype, true, false, arenaRating, matchmakerRating, ateamId); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); } for (GroupReference refe = grp.GetFirstMember(); refe != null; refe = refe.next()) { Player member = refe.GetSource(); if (!member) { continue; } if (err != 0) { BattlefieldStatusFailed battlefieldStatus; Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatus, bg, GetPlayer(), 0, arenatype, err, errorGuid); member.SendPacket(battlefieldStatus); continue; } // add to queue uint queueSlot = member.AddBattlegroundQueueId(bgQueueTypeId); BattlefieldStatusQueued battlefieldStatusQueued; Global.BattlegroundMgr.BuildBattlegroundStatusQueued(out battlefieldStatusQueued, bg, member, queueSlot, ginfo.JoinTime, avgTime, arenatype, true); member.SendPacket(battlefieldStatusQueued); Log.outDebug(LogFilter.Battleground, "Battleground: player joined queue for arena as group bg queue type {0} bg type {1}: GUID {2}, NAME {3}", bgQueueTypeId, bgTypeId, member.GetGUID().ToString(), member.GetName()); } Global.BattlegroundMgr.ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry.GetBracketId()); }
void HandleBattleFieldPort(BattlefieldPort battlefieldPort) { if (!GetPlayer().InBattlegroundQueue()) { Log.outDebug(LogFilter.Battleground, "CMSG_BATTLEFIELD_PORT {0} Slot: {1}, Unk: {2}, Time: {3}, AcceptedInvite: {4}. Player not in queue!", GetPlayerInfo(), battlefieldPort.Ticket.Id, battlefieldPort.Ticket.Type, battlefieldPort.Ticket.Time, battlefieldPort.AcceptedInvite); return; } BattlegroundQueueTypeId bgQueueTypeId = GetPlayer().GetBattlegroundQueueTypeId(battlefieldPort.Ticket.Id); if (bgQueueTypeId == BattlegroundQueueTypeId.None) { Log.outDebug(LogFilter.Battleground, "CMSG_BATTLEFIELD_PORT {0} Slot: {1}, Unk: {2}, Time: {3}, AcceptedInvite: {4}. Invalid queueSlot!", GetPlayerInfo(), battlefieldPort.Ticket.Id, battlefieldPort.Ticket.Type, battlefieldPort.Ticket.Time, battlefieldPort.AcceptedInvite); return; } BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); //we must use temporary variable, because GroupQueueInfo pointer can be deleted in BattlegroundQueue.RemovePlayer() function GroupQueueInfo ginfo; if (!bgQueue.GetPlayerGroupInfoData(GetPlayer().GetGUID(), out ginfo)) { Log.outDebug(LogFilter.Battleground, "CMSG_BATTLEFIELD_PORT {0} Slot: {1}, Unk: {2}, Time: {3}, AcceptedInvite: {4}. Player not in queue (No player Group Info)!", GetPlayerInfo(), battlefieldPort.Ticket.Id, battlefieldPort.Ticket.Type, battlefieldPort.Ticket.Time, battlefieldPort.AcceptedInvite); return; } // if action == 1, then instanceId is required if (ginfo.IsInvitedToBGInstanceGUID == 0 && battlefieldPort.AcceptedInvite) { Log.outDebug(LogFilter.Battleground, "CMSG_BATTLEFIELD_PORT {0} Slot: {1}, Unk: {2}, Time: {3}, AcceptedInvite: {4}. Player is not invited to any bg!", GetPlayerInfo(), battlefieldPort.Ticket.Id, battlefieldPort.Ticket.Type, battlefieldPort.Ticket.Time, battlefieldPort.AcceptedInvite); return; } BattlegroundTypeId bgTypeId = Global.BattlegroundMgr.BGTemplateId(bgQueueTypeId); // BGTemplateId returns Battleground_AA when it is arena queue. // Do instance id search as there is no AA bg instances. Battleground bg = Global.BattlegroundMgr.GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId == BattlegroundTypeId.AA ? BattlegroundTypeId.None : bgTypeId); if (!bg) { if (battlefieldPort.AcceptedInvite) { Log.outDebug(LogFilter.Battleground, "CMSG_BATTLEFIELD_PORT {0} Slot: {1}, Unk: {2}, Time: {3}, AcceptedInvite: {4}. Cant find BG with id {5}!", GetPlayerInfo(), battlefieldPort.Ticket.Id, battlefieldPort.Ticket.Type, battlefieldPort.Ticket.Time, battlefieldPort.AcceptedInvite, ginfo.IsInvitedToBGInstanceGUID); return; } bg = Global.BattlegroundMgr.GetBattlegroundTemplate(bgTypeId); if (!bg) { Log.outError(LogFilter.Network, "BattlegroundHandler: bg_template not found for type id {0}.", bgTypeId); return; } } // get real bg type bgTypeId = bg.GetTypeID(); // expected bracket entry PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel()); if (bracketEntry == null) { return; } //some checks if player isn't cheating - it is not exactly cheating, but we cannot allow it if (battlefieldPort.AcceptedInvite && ginfo.ArenaType == 0) { //if player is trying to enter Battleground(not arena!) and he has deserter debuff, we must just remove him from queue if (!GetPlayer().CanJoinToBattleground(bg)) { // send bg command result to show nice message BattlefieldStatusFailed battlefieldStatus; Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatus, bg, GetPlayer(), battlefieldPort.Ticket.Id, 0, GroupJoinBattlegroundResult.Deserters); SendPacket(battlefieldStatus); battlefieldPort.AcceptedInvite = false; Log.outDebug(LogFilter.Battleground, "Player {0} ({1}) has a deserter debuff, do not port him to Battleground!", GetPlayer().GetName(), GetPlayer().GetGUID().ToString()); } //if player don't match Battlegroundmax level, then do not allow him to enter! (this might happen when player leveled up during his waiting in queue if (GetPlayer().getLevel() > bg.GetMaxLevel()) { Log.outDebug(LogFilter.Network, "Player {0} ({1}) has level ({2}) higher than maxlevel ({3}) of Battleground({4})! Do not port him to Battleground!", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), GetPlayer().getLevel(), bg.GetMaxLevel(), bg.GetTypeID()); battlefieldPort.AcceptedInvite = false; } } if (battlefieldPort.AcceptedInvite) { // check Freeze debuff if (GetPlayer().HasAura(9454)) { return; } if (!GetPlayer().IsInvitedForBattlegroundQueueType(bgQueueTypeId)) { return; // cheating? } if (!GetPlayer().InBattleground()) { GetPlayer().SetBattlegroundEntryPoint(); } // resurrect the player if (!GetPlayer().IsAlive()) { GetPlayer().ResurrectPlayer(1.0f); GetPlayer().SpawnCorpseBones(); } // stop taxi flight at port if (GetPlayer().IsInFlight()) { GetPlayer().GetMotionMaster().MovementExpired(); GetPlayer().CleanupAfterTaxiFlight(); } BattlefieldStatusActive battlefieldStatus; Global.BattlegroundMgr.BuildBattlegroundStatusActive(out battlefieldStatus, bg, GetPlayer(), battlefieldPort.Ticket.Id, GetPlayer().GetBattlegroundQueueJoinTime(bgQueueTypeId), bg.GetArenaType()); SendPacket(battlefieldStatus); // remove BattlegroundQueue status from BGmgr bgQueue.RemovePlayer(GetPlayer().GetGUID(), false); // this is still needed here if Battleground"jumping" shouldn't add deserter debuff // also this is required to prevent stuck at old Battlegroundafter SetBattlegroundId set to new Battleground currentBg = GetPlayer().GetBattleground(); if (currentBg) { currentBg.RemovePlayerAtLeave(GetPlayer().GetGUID(), false, true); } // set the destination instance id GetPlayer().SetBattlegroundId(bg.GetInstanceID(), bgTypeId); // set the destination team GetPlayer().SetBGTeam(ginfo.Team); Global.BattlegroundMgr.SendToBattleground(GetPlayer(), ginfo.IsInvitedToBGInstanceGUID, bgTypeId); Log.outDebug(LogFilter.Battleground, "Battleground: player {0} ({1}) joined battle for bg {2}, bgtype {3}, queue type {4}.", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), bg.GetInstanceID(), bg.GetTypeID(), bgQueueTypeId); } else // leave queue { // if player leaves rated arena match before match start, it is counted as he played but he lost if (ginfo.IsRated && ginfo.IsInvitedToBGInstanceGUID != 0) { ArenaTeam at = Global.ArenaTeamMgr.GetArenaTeamById((uint)ginfo.Team); if (at != null) { Log.outDebug(LogFilter.Battleground, "UPDATING memberLost's personal arena rating for {0} by opponents rating: {1}, because he has left queue!", GetPlayer().GetGUID().ToString(), ginfo.OpponentsTeamRating); at.MemberLost(GetPlayer(), ginfo.OpponentsMatchmakerRating); at.SaveToDB(); } } BattlefieldStatusNone battlefieldStatus = new BattlefieldStatusNone(); battlefieldStatus.Ticket = battlefieldPort.Ticket; SendPacket(battlefieldStatus); GetPlayer().RemoveBattlegroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue.removeplayer, it causes bugs bgQueue.RemovePlayer(GetPlayer().GetGUID(), true); // player left queue, we should update it - do not update Arena Queue if (ginfo.ArenaType == 0) { Global.BattlegroundMgr.ScheduleQueueUpdate(ginfo.ArenaMatchmakerRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, bracketEntry.GetBracketId()); } Log.outDebug(LogFilter.Battleground, "Battleground: player {0} ({1}) left queue for bgtype {2}, queue type {3}.", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), bg.GetTypeID(), bgQueueTypeId); } }
void HandleInspect(Inspect inspect) { Player player = Global.ObjAccessor.GetPlayer(_player, inspect.Target); if (!player) { Log.outDebug(LogFilter.Network, "WorldSession.HandleInspectOpcode: Target {0} not found.", inspect.Target.ToString()); return; } if (!GetPlayer().IsWithinDistInMap(player, SharedConst.InspectDistance, false)) { return; } if (GetPlayer().IsValidAttackTarget(player)) { return; } InspectResult inspectResult = new(); inspectResult.DisplayInfo.Initialize(player); if (GetPlayer().CanBeGameMaster() || WorldConfig.GetIntValue(WorldCfg.TalentsInspecting) + (GetPlayer().GetTeamId() == player.GetTeamId() ? 1 : 0) > 1) { var talents = player.GetTalentMap(player.GetActiveTalentGroup()); foreach (var v in talents) { if (v.Value != PlayerSpellState.Removed) { inspectResult.Talents.Add((ushort)v.Key); } } } Guild guild = Global.GuildMgr.GetGuildById(player.GetGuildId()); if (guild) { inspectResult.GuildData.Value = new(); InspectGuildData guildData; guildData.GuildGUID = guild.GetGUID(); guildData.NumGuildMembers = guild.GetMembersCount(); guildData.AchievementPoints = (int)guild.GetAchievementMgr().GetAchievementPoints(); inspectResult.GuildData.Set(guildData); } Item heartOfAzeroth = player.GetItemByEntry(PlayerConst.ItemIdHeartOfAzeroth, ItemSearchLocation.Everywhere); if (heartOfAzeroth != null) { AzeriteItem azeriteItem = heartOfAzeroth.ToAzeriteItem(); if (azeriteItem != null) { inspectResult.AzeriteLevel = azeriteItem.GetEffectiveLevel(); } } inspectResult.ItemLevel = (int)player.GetAverageItemLevel(); inspectResult.LifetimeMaxRank = player.m_activePlayerData.LifetimeMaxRank; inspectResult.TodayHK = player.m_activePlayerData.TodayHonorableKills; inspectResult.YesterdayHK = player.m_activePlayerData.YesterdayHonorableKills; inspectResult.LifetimeHK = player.m_activePlayerData.LifetimeHonorableKills; inspectResult.HonorLevel = player.m_playerData.HonorLevel; SendPacket(inspectResult); }
void HandleLfgTeleport(DFTeleport dfTeleport) { Log.outDebug(LogFilter.Lfg, "CMSG_DF_TELEPORT {0} out: {1}", GetPlayerInfo(), dfTeleport.TeleportOut ? 1 : 0); Global.LFGMgr.TeleportPlayer(GetPlayer(), dfTeleport.TeleportOut, true); }
void HandleSellItem(SellItem packet) { if (packet.ItemGUID.IsEmpty()) { return; } var pl = GetPlayer(); Creature creature = pl.GetNPCIfCanInteractWith(packet.VendorGUID, NPCFlags.Vendor, NPCFlags2.None); if (creature == null) { Log.outDebug(LogFilter.Network, "WORLD: HandleSellItemOpcode - {0} not found or you can not interact with him.", packet.VendorGUID.ToString()); pl.SendSellError(SellResult.CantFindVendor, null, packet.ItemGUID); return; } // remove fake death if (pl.HasUnitState(UnitState.Died)) { pl.RemoveAurasByType(AuraType.FeignDeath); } Item pItem = pl.GetItemByGuid(packet.ItemGUID); if (pItem != null) { // prevent sell not owner item if (pl.GetGUID() != pItem.GetOwnerGUID()) { pl.SendSellError(SellResult.CantSellItem, creature, packet.ItemGUID); return; } // prevent sell non empty bag by drag-and-drop at vendor's item list if (pItem.IsNotEmptyBag()) { pl.SendSellError(SellResult.CantSellItem, creature, packet.ItemGUID); return; } // prevent sell currently looted item if (pl.GetLootGUID() == pItem.GetGUID()) { pl.SendSellError(SellResult.CantSellItem, creature, packet.ItemGUID); return; } // prevent selling item for sellprice when the item is still refundable // this probably happens when right clicking a refundable item, the client sends both // CMSG_SELL_ITEM and CMSG_REFUND_ITEM (unverified) if (pItem.HasItemFlag(ItemFieldFlags.Refundable)) { return; // Therefore, no feedback to client } // special case at auto sell (sell all) if (packet.Amount == 0) { packet.Amount = pItem.GetCount(); } else { // prevent sell more items that exist in stack (possible only not from client) if (packet.Amount > pItem.GetCount()) { pl.SendSellError(SellResult.CantSellItem, creature, packet.ItemGUID); return; } } ItemTemplate pProto = pItem.GetTemplate(); if (pProto != null) { if (pProto.GetSellPrice() > 0) { ulong money = pProto.GetSellPrice() * packet.Amount; if (!_player.ModifyMoney((long)money)) // ensure player doesn't exceed gold limit { _player.SendSellError(SellResult.CantSellItem, creature, packet.ItemGUID); return; } _player.UpdateCriteria(CriteriaTypes.MoneyFromVendors, money); _player.UpdateCriteria(CriteriaTypes.SoldItemToVendor, 1); if (packet.Amount < pItem.GetCount()) // need split items { Item pNewItem = pItem.CloneItem(packet.Amount, pl); if (pNewItem == null) { Log.outError(LogFilter.Network, "WORLD: HandleSellItemOpcode - could not create clone of item {0}; count = {1}", pItem.GetEntry(), packet.Amount); pl.SendSellError(SellResult.CantSellItem, creature, packet.ItemGUID); return; } pItem.SetCount(pItem.GetCount() - packet.Amount); pl.ItemRemovedQuestCheck(pItem.GetEntry(), packet.Amount); if (pl.IsInWorld) { pItem.SendUpdateToPlayer(pl); } pItem.SetState(ItemUpdateState.Changed, pl); pl.AddItemToBuyBackSlot(pNewItem); if (pl.IsInWorld) { pNewItem.SendUpdateToPlayer(pl); } } else { pl.ItemRemovedQuestCheck(pItem.GetEntry(), pItem.GetCount()); pl.RemoveItem(pItem.GetBagSlot(), pItem.GetSlot(), true); Item.RemoveItemFromUpdateQueueOf(pItem, pl); pl.AddItemToBuyBackSlot(pItem); } } else { pl.SendSellError(SellResult.CantSellItem, creature, packet.ItemGUID); } return; } } pl.SendSellError(SellResult.CantSellItem, creature, packet.ItemGUID); return; }
public void SendLfgOfferContinue(uint dungeonEntry) { Log.outDebug(LogFilter.Lfg, "SMSG_LFG_OFFER_CONTINUE {0} dungeon entry: {1}", GetPlayerInfo(), dungeonEntry); SendPacket(new LfgOfferContinue(Global.LFGMgr.GetLFGDungeonEntry(dungeonEntry))); }
void HandleSetContactNotes(SetContactNotes packet) { // @todo: handle VirtualRealmAddress Log.outDebug(LogFilter.Network, "WorldSession.HandleSetContactNotesOpcode: Contact: {0}, Notes: {1}", packet.Player.Guid.ToString(), packet.Notes); GetPlayer().GetSocial().SetFriendNote(packet.Player.Guid, packet.Notes); }
void HandleLfgProposalResult(DFProposalResponse dfProposalResponse) { Log.outDebug(LogFilter.Lfg, "CMSG_LFG_PROPOSAL_RESULT {0} proposal: {1} accept: {2}", GetPlayerInfo(), dfProposalResponse.ProposalID, dfProposalResponse.Accepted ? 1 : 0); Global.LFGMgr.UpdateProposal(dfProposalResponse.ProposalID, GetPlayer().GetGUID(), dfProposalResponse.Accepted); }
void HandleChannelPlayerCommand(ChannelPlayerCommand packet) { if (packet.Name.Length >= 49) { Log.outDebug(LogFilter.ChatSystem, "{0} {1} ChannelName: {2}, Name: {3}, Name too long.", packet.GetOpcode(), GetPlayerInfo(), packet.ChannelName, packet.Name); return; } if (!ObjectManager.NormalizePlayerName(ref packet.Name)) { return; } Channel channel = ChannelManager.GetChannelForPlayerByNamePart(packet.ChannelName, GetPlayer()); if (channel == null) { return; } switch (packet.GetOpcode()) { case ClientOpcodes.ChatChannelBan: channel.Ban(GetPlayer(), packet.Name); break; case ClientOpcodes.ChatChannelInvite: channel.Invite(GetPlayer(), packet.Name); break; case ClientOpcodes.ChatChannelKick: channel.Kick(GetPlayer(), packet.Name); break; case ClientOpcodes.ChatChannelModerator: channel.SetModerator(GetPlayer(), packet.Name); break; case ClientOpcodes.ChatChannelMute: channel.SetMute(GetPlayer(), packet.Name); break; case ClientOpcodes.ChatChannelSetOwner: channel.SetOwner(GetPlayer(), packet.Name); break; case ClientOpcodes.ChatChannelSilenceAll: channel.SilenceAll(GetPlayer(), packet.Name); break; case ClientOpcodes.ChatChannelUnban: channel.UnBan(GetPlayer(), packet.Name); break; case ClientOpcodes.ChatChannelUnmoderator: channel.UnsetModerator(GetPlayer(), packet.Name); break; case ClientOpcodes.ChatChannelUnmute: channel.UnsetMute(GetPlayer(), packet.Name); break; case ClientOpcodes.ChatChannelUnsilenceAll: channel.UnsilenceAll(GetPlayer(), packet.Name); break; } }
void HandleAuctionPlaceBid(AuctionPlaceBid packet) { if (packet.AuctionItemID == 0 || packet.BidAmount == 0) { return; // check for cheaters } Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Auctioneer, NPCFlags.Auctioneer); if (!creature) { Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionPlaceBid - {0} not found or you can't interact with him.", packet.Auctioneer.ToString()); return; } // remove fake death if (GetPlayer().HasUnitState(UnitState.Died)) { GetPlayer().RemoveAurasByType(AuraType.FeignDeath); } AuctionHouseObject auctionHouse = Global.AuctionMgr.GetAuctionsMap(creature.getFaction()); AuctionEntry auction = auctionHouse.GetAuction(packet.AuctionItemID); Player player = GetPlayer(); if (auction == null || auction.owner == player.GetGUID().GetCounter()) { //you cannot bid your own auction: SendAuctionCommandResult(null, AuctionAction.PlaceBid, AuctionError.BidOwn); return; } // impossible have online own another character (use this for speedup check in case online owner) ObjectGuid ownerGuid = ObjectGuid.Create(HighGuid.Player, auction.owner); Player auction_owner = Global.ObjAccessor.FindPlayer(ownerGuid); if (!auction_owner && ObjectManager.GetPlayerAccountIdByGUID(ownerGuid) == player.GetSession().GetAccountId()) { //you cannot bid your another character auction: SendAuctionCommandResult(null, AuctionAction.PlaceBid, AuctionError.BidOwn); return; } // cheating if (packet.BidAmount <= auction.bid || packet.BidAmount < auction.startbid) { return; } // price too low for next bid if not buyout if ((packet.BidAmount < auction.buyout || auction.buyout == 0) && packet.BidAmount < auction.bid + auction.GetAuctionOutBid()) { // client already test it but just in case ... SendAuctionCommandResult(auction, AuctionAction.PlaceBid, AuctionError.HigherBid); return; } if (!player.HasEnoughMoney(packet.BidAmount)) { // client already test it but just in case ... SendAuctionCommandResult(auction, AuctionAction.PlaceBid, AuctionError.NotEnoughtMoney); return; } SQLTransaction trans = new SQLTransaction(); if (packet.BidAmount < auction.buyout || auction.buyout == 0) { if (auction.bidder > 0) { if (auction.bidder == player.GetGUID().GetCounter()) { player.ModifyMoney(-(long)(packet.BidAmount - auction.bid)); } else { // mail to last bidder and return money Global.AuctionMgr.SendAuctionOutbiddedMail(auction, packet.BidAmount, GetPlayer(), trans); player.ModifyMoney(-(long)packet.BidAmount); } } else { player.ModifyMoney(-(long)packet.BidAmount); } auction.bidder = player.GetGUID().GetCounter(); auction.bid = (uint)packet.BidAmount; GetPlayer().UpdateCriteria(CriteriaTypes.HighestAuctionBid, packet.BidAmount); PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_AUCTION_BID); stmt.AddValue(0, auction.bidder); stmt.AddValue(1, auction.bid); stmt.AddValue(2, auction.Id); trans.Append(stmt); SendAuctionCommandResult(auction, AuctionAction.PlaceBid, AuctionError.Ok); // Not sure if we must send this now. Player owner = Global.ObjAccessor.FindConnectedPlayer(ObjectGuid.Create(HighGuid.Player, auction.owner)); Item item = Global.AuctionMgr.GetAItem(auction.itemGUIDLow); if (owner && item) { owner.GetSession().SendAuctionOwnerBidNotification(auction, item); } } else { //buyout: if (player.GetGUID().GetCounter() == auction.bidder) { player.ModifyMoney(-(long)(auction.buyout - auction.bid)); } else { player.ModifyMoney(-(long)auction.buyout); if (auction.bidder != 0) //buyout for bidded auction .. { Global.AuctionMgr.SendAuctionOutbiddedMail(auction, auction.buyout, GetPlayer(), trans); } } auction.bidder = player.GetGUID().GetCounter(); auction.bid = auction.buyout; GetPlayer().UpdateCriteria(CriteriaTypes.HighestAuctionBid, auction.buyout); SendAuctionCommandResult(auction, AuctionAction.PlaceBid, AuctionError.Ok); //- Mails must be under transaction control too to prevent data loss Global.AuctionMgr.SendAuctionSalePendingMail(auction, trans); Global.AuctionMgr.SendAuctionSuccessfulMail(auction, trans); Global.AuctionMgr.SendAuctionWonMail(auction, trans); auction.DeleteFromDB(trans); Global.AuctionMgr.RemoveAItem(auction.itemGUIDLow); auctionHouse.RemoveAuction(auction); } player.SaveInventoryAndGoldToDB(trans); DB.Characters.CommitTransaction(trans); }
void HandlePetSetAction(PetSetAction packet) { ObjectGuid petguid = packet.PetGUID; Unit pet = Global.ObjAccessor.GetUnit(GetPlayer(), petguid); if (!pet || pet != GetPlayer().GetFirstControlled()) { Log.outError(LogFilter.Network, "HandlePetSetAction: Unknown {0} or pet owner {1}", petguid.ToString(), GetPlayer().GetGUID().ToString()); return; } CharmInfo charmInfo = pet.GetCharmInfo(); if (charmInfo == null) { Log.outError(LogFilter.Network, "WorldSession.HandlePetSetAction: {0} is considered pet-like but doesn't have a charminfo!", pet.GetGUID().ToString()); return; } List <Unit> pets = new(); foreach (Unit controlled in _player.m_Controlled) { if (controlled.GetEntry() == pet.GetEntry() && controlled.IsAlive()) { pets.Add(controlled); } } uint position = packet.Index; uint actionData = packet.Action; uint spell_id = UnitActionBarEntry.UNIT_ACTION_BUTTON_ACTION(actionData); ActiveStates act_state = (ActiveStates)UnitActionBarEntry.UNIT_ACTION_BUTTON_TYPE(actionData); Log.outDebug(LogFilter.Network, "Player {0} has changed pet spell action. Position: {1}, Spell: {2}, State: {3}", GetPlayer().GetName(), position, spell_id, act_state); foreach (Unit petControlled in pets) { //if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add if (!((act_state == ActiveStates.Enabled || act_state == ActiveStates.Disabled || act_state == ActiveStates.Passive) && spell_id != 0 && !petControlled.HasSpell(spell_id))) { SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id, petControlled.GetMap().GetDifficultyID()); if (spellInfo != null) { //sign for autocast if (act_state == ActiveStates.Enabled) { if (petControlled.GetTypeId() == TypeId.Unit && petControlled.IsPet()) { ((Pet)petControlled).ToggleAutocast(spellInfo, true); } else { foreach (var unit in GetPlayer().m_Controlled) { if (unit.GetEntry() == petControlled.GetEntry()) { unit.GetCharmInfo().ToggleCreatureAutocast(spellInfo, true); } } } } //sign for no/turn off autocast else if (act_state == ActiveStates.Disabled) { if (petControlled.GetTypeId() == TypeId.Unit && petControlled.IsPet()) { petControlled.ToPet().ToggleAutocast(spellInfo, false); } else { foreach (var unit in GetPlayer().m_Controlled) { if (unit.GetEntry() == petControlled.GetEntry()) { unit.GetCharmInfo().ToggleCreatureAutocast(spellInfo, false); } } } } } charmInfo.SetActionBar((byte)position, spell_id, act_state); } } }
public override void CallServerMethod(uint token, uint methodId, CodedInputStream stream) { switch (methodId) { case 1: { ClientRequest request = new ClientRequest(); request.MergeFrom(stream); ClientResponse response = new ClientResponse(); BattlenetRpcErrorCode status = HandleProcessClientRequest(request, response); Log.outDebug(LogFilter.ServiceProtobuf, "{0} Client called server method GameUtilitiesService.ProcessClientRequest(bgs.protocol.game_utilities.v1.ClientRequest: {1}) returned bgs.protocol.game_utilities.v1.ClientResponse: {2} status: {3}.", GetCallerInfo(), request.ToString(), response.ToString(), status); if (status == 0) { SendResponse(1, token, response); } else { SendResponse(1, token, status); } break; } case 2: { PresenceChannelCreatedRequest request = new PresenceChannelCreatedRequest(); request.MergeFrom(stream); Bgs.Protocol.NoData response = new Bgs.Protocol.NoData(); BattlenetRpcErrorCode status = HandlePresenceChannelCreated(request, response); Log.outDebug(LogFilter.ServiceProtobuf, "{0} Client called server method GameUtilitiesService.PresenceChannelCreated(bgs.protocol.game_utilities.v1.PresenceChannelCreatedRequest: {1}) returned bgs.protocol.NoData: {2} status: {3}.", GetCallerInfo(), request.ToString(), response.ToString(), status); if (status == 0) { SendResponse(2, token, response); } else { SendResponse(2, token, status); } break; } case 3: { GetPlayerVariablesRequest request = new GetPlayerVariablesRequest(); request.MergeFrom(stream); GetPlayerVariablesResponse response = new GetPlayerVariablesResponse(); BattlenetRpcErrorCode status = HandleGetPlayerVariables(request, response); Log.outDebug(LogFilter.ServiceProtobuf, "{0} Client called server method GameUtilitiesService.GetPlayerVariables(bgs.protocol.game_utilities.v1.GetPlayerVariablesRequest: {1}) returned bgs.protocol.game_utilities.v1.GetPlayerVariablesResponse: {2} status: {3}.", GetCallerInfo(), request.ToString(), response.ToString(), status); if (status == 0) { SendResponse(3, token, response); } else { SendResponse(3, token, status); } break; } case 6: { ServerRequest request = new ServerRequest(); request.MergeFrom(stream); ServerResponse response = new ServerResponse(); BattlenetRpcErrorCode status = HandleProcessServerRequest(request, response); Log.outDebug(LogFilter.ServiceProtobuf, "{0} Client called server method GameUtilitiesService.ProcessServerRequest(bgs.protocol.game_utilities.v1.ServerRequest: {1}) returned bgs.protocol.game_utilities.v1.ServerResponse: {2} status: {3}.", GetCallerInfo(), request.ToString(), response.ToString(), status); if (status == 0) { SendResponse(6, token, response); } else { SendResponse(6, token, status); } break; } case 7: { GameAccountOnlineNotification request = new GameAccountOnlineNotification(); request.MergeFrom(stream); BattlenetRpcErrorCode status = HandleOnGameAccountOnline(request); Log.outDebug(LogFilter.ServiceProtobuf, "{0} Client called server method GameUtilitiesService.OnGameAccountOnline(bgs.protocol.game_utilities.v1.GameAccountOnlineNotification: {1}) status: {2}.", GetCallerInfo(), request.ToString(), status); if (status != 0) { SendResponse(7, token, status); } break; } case 8: { GameAccountOfflineNotification request = new GameAccountOfflineNotification(); request.MergeFrom(stream); BattlenetRpcErrorCode status = HandleOnGameAccountOffline(request); Log.outDebug(LogFilter.ServiceProtobuf, "{0} Client called server method GameUtilitiesService.OnGameAccountOffline(bgs.protocol.game_utilities.v1.GameAccountOfflineNotification: {1}) status: {2}.", GetCallerInfo(), request.ToString(), status); if (status != 0) { SendResponse(8, token, status); } break; } case 9: { GetAchievementsFileRequest request = new GetAchievementsFileRequest(); request.MergeFrom(stream); GetAchievementsFileResponse response = new GetAchievementsFileResponse(); BattlenetRpcErrorCode status = HandleGetAchievementsFile(request, response); Log.outDebug(LogFilter.ServiceProtobuf, "{0} Client called server method GameUtilitiesService.GetAchievementsFile(bgs.protocol.game_utilities.v1.GetAchievementsFileRequest: {1}) returned bgs.protocol.game_utilities.v1.GetAchievementsFileResponse: {2} status: {3}.", GetCallerInfo(), request.ToString(), response.ToString(), status); if (status == 0) { SendResponse(9, token, response); } else { SendResponse(9, token, status); } break; } case 10: { GetAllValuesForAttributeRequest request = new GetAllValuesForAttributeRequest(); request.MergeFrom(stream); GetAllValuesForAttributeResponse response = new GetAllValuesForAttributeResponse(); BattlenetRpcErrorCode status = HandleGetAllValuesForAttribute(request, response); Log.outDebug(LogFilter.ServiceProtobuf, "{0} Client called server method GameUtilitiesService.GetAllValuesForAttribute(bgs.protocol.game_utilities.v1.GetAllValuesForAttributeRequest: {1}) returned bgs.protocol.game_utilities.v1.GetAllValuesForAttributeResponse: {2} status: {3}.", GetCallerInfo(), request.ToString(), response.ToString(), status); if (status == 0) { SendResponse(10, token, response); } else { SendResponse(10, token, status); } break; } default: Log.outError(LogFilter.ServiceProtobuf, "Bad method id {0}.", methodId); SendResponse(methodId, token, BattlenetRpcErrorCode.RpcInvalidMethod); break; } }
void HandleSignPetition(SignPetition packet) { PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_PETITION_SIGNATURES); stmt.AddValue(0, packet.PetitionGUID.GetCounter()); stmt.AddValue(1, packet.PetitionGUID.GetCounter()); SQLResult result = DB.Characters.Query(stmt); if (result.IsEmpty()) { Log.outError(LogFilter.Network, "Petition {0} is not found for player {1} {2}", packet.PetitionGUID.ToString(), GetPlayer().GetGUID().ToString(), GetPlayer().GetName()); return; } ObjectGuid ownerGuid = ObjectGuid.Create(HighGuid.Player, result.Read <ulong>(0)); //ulong signs = result.Read<ulong>(1); if (ownerGuid == GetPlayer().GetGUID()) { return; } // not let enemies sign guild charter if (!WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionGuild) && GetPlayer().GetTeam() != ObjectManager.GetPlayerTeamByGUID(ownerGuid)) { Guild.SendCommandResult(this, GuildCommandType.CreateGuild, GuildCommandError.NotAllied); return; } if (GetPlayer().GetGuildId() != 0) { Guild.SendCommandResult(this, GuildCommandType.InvitePlayer, GuildCommandError.AlreadyInGuild_S, GetPlayer().GetName()); return; } if (GetPlayer().GetGuildIdInvited() != 0) { Guild.SendCommandResult(this, GuildCommandType.InvitePlayer, GuildCommandError.AlreadyInvitedToGuild_S, GetPlayer().GetName()); return; } // Client doesn't allow to sign petition two times by one character, but not check sign by another character from same account // not allow sign another player from already sign player account stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_PETITION_SIG_BY_ACCOUNT); stmt.AddValue(0, GetAccountId()); stmt.AddValue(1, packet.PetitionGUID.GetCounter()); result = DB.Characters.Query(stmt); PetitionSignResults signResult = new PetitionSignResults(); signResult.Player = GetPlayer().GetGUID(); signResult.Item = packet.PetitionGUID; if (!result.IsEmpty()) { signResult.Error = PetitionSigns.AlreadySigned; // close at signer side SendPacket(signResult); return; } stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_PETITION_SIGNATURE); stmt.AddValue(0, ownerGuid.GetCounter()); stmt.AddValue(1, packet.PetitionGUID.GetCounter()); stmt.AddValue(2, GetPlayer().GetGUID().GetCounter()); stmt.AddValue(3, GetAccountId()); DB.Characters.Execute(stmt); Log.outDebug(LogFilter.Network, "PETITION SIGN: {0} by player: {1} ({2} Account: {3})", packet.PetitionGUID.ToString(), GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), GetAccountId()); signResult.Error = PetitionSigns.Ok; // close at signer side SendPacket(signResult); // update for owner if online Player owner = Global.ObjAccessor.FindPlayer(ownerGuid); if (owner) { owner.SendPacket(signResult); } }
public void InvalidateRBACData() { Log.outDebug(LogFilter.Rbac, "WorldSession:Invalidaterbac:RBACData [AccountId: {0}, Name: {1}, realmId: {2}]", _RBACData.GetId(), _RBACData.GetName(), Global.WorldMgr.GetRealm().Id.Realm); _RBACData = null; }
void HandlePetitionBuy(PetitionBuy packet) { // prevent cheating Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Unit, NPCFlags.Petitioner); if (!creature) { Log.outDebug(LogFilter.Network, "WORLD: HandlePetitionBuyOpcode - {0} not found or you can't interact with him.", packet.Unit.ToString()); return; } // remove fake death if (GetPlayer().HasUnitState(UnitState.Died)) { GetPlayer().RemoveAurasByType(AuraType.FeignDeath); } uint charterItemID = GuildConst.CharterItemId; int cost = WorldConfig.GetIntValue(WorldCfg.CharterCostGuild); // do not let if already in guild. if (GetPlayer().GetGuildId() != 0) { return; } if (Global.GuildMgr.GetGuildByName(packet.Title)) { Guild.SendCommandResult(this, GuildCommandType.CreateGuild, GuildCommandError.NameExists_S, packet.Title); return; } if (Global.ObjectMgr.IsReservedName(packet.Title) || !ObjectManager.IsValidCharterName(packet.Title)) { Guild.SendCommandResult(this, GuildCommandType.CreateGuild, GuildCommandError.NameInvalid, packet.Title); return; } ItemTemplate pProto = Global.ObjectMgr.GetItemTemplate(charterItemID); if (pProto == null) { GetPlayer().SendBuyError(BuyResult.CantFindItem, null, charterItemID); return; } if (!GetPlayer().HasEnoughMoney(cost)) { //player hasn't got enough money GetPlayer().SendBuyError(BuyResult.NotEnoughtMoney, creature, charterItemID); return; } List <ItemPosCount> dest = new List <ItemPosCount>(); InventoryResult msg = GetPlayer().CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, charterItemID, pProto.GetBuyCount()); if (msg != InventoryResult.Ok) { GetPlayer().SendEquipError(msg, null, null, charterItemID); return; } GetPlayer().ModifyMoney(-cost); Item charter = GetPlayer().StoreNewItem(dest, charterItemID, true); if (!charter) { return; } charter.SetUInt32Value(ItemFields.Enchantment, (uint)charter.GetGUID().GetCounter()); // ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id // ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item) charter.SetState(ItemUpdateState.Changed, GetPlayer()); GetPlayer().SendNewItem(charter, 1, true, false); // a petition is invalid, if both the owner and the type matches // we checked above, if this player is in an arenateam, so this must be // datacorruption PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_PETITION_BY_OWNER); stmt.AddValue(0, GetPlayer().GetGUID().GetCounter()); SQLResult result = DB.Characters.Query(stmt); StringBuilder ssInvalidPetitionGUIDs = new StringBuilder(); if (!result.IsEmpty()) { do { ssInvalidPetitionGUIDs.AppendFormat("'{0}', ", result.Read <uint>(0)); } while (result.NextRow()); } // delete petitions with the same guid as this one ssInvalidPetitionGUIDs.AppendFormat("'{0}'", charter.GetGUID().GetCounter()); Log.outDebug(LogFilter.Network, "Invalid petition GUIDs: {0}", ssInvalidPetitionGUIDs.ToString()); SQLTransaction trans = new SQLTransaction(); trans.Append("DELETE FROM petition WHERE petitionguid IN ({0})", ssInvalidPetitionGUIDs.ToString()); trans.Append("DELETE FROM petition_sign WHERE petitionguid IN ({0})", ssInvalidPetitionGUIDs.ToString()); stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_PETITION); stmt.AddValue(0, GetPlayer().GetGUID().GetCounter()); stmt.AddValue(1, charter.GetGUID().GetCounter()); stmt.AddValue(2, packet.Title); trans.Append(stmt); DB.Characters.CommitTransaction(trans); }
public RBACPermission GetRBACPermission(uint permissionId) { Log.outDebug(LogFilter.Rbac, "AccountMgr:GetRBACPermission: {0}", permissionId); return(_permissions.LookupByKey(permissionId)); }
void HandleTurnInPetition(TurnInPetition packet) { // Check if player really has the required petition charter Item item = GetPlayer().GetItemByGuid(packet.Item); if (!item) { return; } // Get petition data from db ObjectGuid ownerguid; string name; PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_PETITION); stmt.AddValue(0, packet.Item.GetCounter()); SQLResult result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { ownerguid = ObjectGuid.Create(HighGuid.Player, result.Read <ulong>(0)); name = result.Read <string>(1); } else { Log.outError(LogFilter.Network, "Player {0} ({1}) tried to turn in petition ({2}) that is not present in the database", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), packet.Item.ToString()); return; } // Only the petition owner can turn in the petition if (GetPlayer().GetGUID() != ownerguid) { return; } TurnInPetitionResult resultPacket = new TurnInPetitionResult(); // Check if player is already in a guild if (GetPlayer().GetGuildId() != 0) { resultPacket.Result = PetitionTurns.AlreadyInGuild; GetPlayer().SendPacket(resultPacket); return; } // Check if guild name is already taken if (Global.GuildMgr.GetGuildByName(name)) { Guild.SendCommandResult(this, GuildCommandType.CreateGuild, GuildCommandError.NameExists_S, name); return; } // Get petition signatures from db stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_PETITION_SIGNATURE); stmt.AddValue(0, packet.Item.GetCounter()); result = DB.Characters.Query(stmt); List <ObjectGuid> guids = new List <ObjectGuid>(); if (!result.IsEmpty()) { do { guids.Add(ObjectGuid.Create(HighGuid.Player, result.Read <ulong>(0))); }while (result.NextRow()); } uint requiredSignatures = WorldConfig.GetUIntValue(WorldCfg.MinPetitionSigns); // Notify player if signatures are missing if (guids.Count < requiredSignatures) { resultPacket.Result = PetitionTurns.NeedMoreSignatures; SendPacket(resultPacket); return; } // Proceed with guild/arena team creation // Delete charter item GetPlayer().DestroyItem(item.GetBagSlot(), item.GetSlot(), true); // Create guild Guild guild = new Guild(); if (!guild.Create(GetPlayer(), name)) { return; } // Register guild and add guild master Global.GuildMgr.AddGuild(guild); Guild.SendCommandResult(this, GuildCommandType.CreateGuild, GuildCommandError.Success, name); SQLTransaction trans = new SQLTransaction(); // Add members from signatures foreach (var guid in guids) { guild.AddMember(trans, guid); } stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_PETITION_BY_GUID); stmt.AddValue(0, packet.Item.GetCounter()); trans.Append(stmt); stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_PETITION_SIGNATURE_BY_GUID); stmt.AddValue(0, packet.Item.GetCounter()); trans.Append(stmt); DB.Characters.CommitTransaction(trans); // created Log.outDebug(LogFilter.Network, "Player {0} ({1}) turning in petition {2}", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), packet.Item.ToString()); resultPacket.Result = PetitionTurns.Ok; SendPacket(resultPacket); }
void HandleTransmogrifyItems(TransmogrifyItems transmogrifyItems) { Player player = GetPlayer(); // Validate if (!player.GetNPCIfCanInteractWith(transmogrifyItems.Npc, NPCFlags.Transmogrifier)) { Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - Unit (GUID: {0}) not found or player can't interact with it.", transmogrifyItems.ToString()); return; } long cost = 0; Dictionary <Item, uint> transmogItems = new Dictionary <Item, uint>(); Dictionary <Item, uint> illusionItems = new Dictionary <Item, uint>(); List <Item> resetAppearanceItems = new List <Item>(); List <Item> resetIllusionItems = new List <Item>(); List <uint> bindAppearances = new List <uint>(); foreach (TransmogrifyItem transmogItem in transmogrifyItems.Items) { // slot of the transmogrified item if (transmogItem.Slot >= EquipmentSlot.End) { Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - Player ({0}, name: {1}) tried to transmogrify wrong slot {2} when transmogrifying items.", player.GetGUID().ToString(), player.GetName(), transmogItem.Slot); return; } // transmogrified item Item itemTransmogrified = player.GetItemByPos(InventorySlots.Bag0, (byte)transmogItem.Slot); if (!itemTransmogrified) { Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - Player (GUID: {0}, name: {1}) tried to transmogrify an invalid item in a valid slot (slot: {2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.Slot); return; } if (transmogItem.ItemModifiedAppearanceID != 0) { ItemModifiedAppearanceRecord itemModifiedAppearance = CliDB.ItemModifiedAppearanceStorage.LookupByKey(transmogItem.ItemModifiedAppearanceID); if (itemModifiedAppearance == null) { Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify using invalid appearance ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.ItemModifiedAppearanceID); return; } var pairValue = GetCollectionMgr().HasItemAppearance((uint)transmogItem.ItemModifiedAppearanceID); if (!pairValue.Item1) { Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify using appearance he has not collected ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.ItemModifiedAppearanceID); return; } ItemTemplate itemTemplate = Global.ObjectMgr.GetItemTemplate(itemModifiedAppearance.ItemID); if (player.CanUseItem(itemTemplate) != InventoryResult.Ok) { Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify using appearance he can never use ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.ItemModifiedAppearanceID); return; } // validity of the transmogrification items if (!Item.CanTransmogrifyItemWithItem(itemTransmogrified, itemModifiedAppearance)) { Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} failed CanTransmogrifyItemWithItem ({2} with appearance {3}).", player.GetGUID().ToString(), player.GetName(), itemTransmogrified.GetEntry(), transmogItem.ItemModifiedAppearanceID); return; } transmogItems[itemTransmogrified] = (uint)transmogItem.ItemModifiedAppearanceID; if (pairValue.Item2) { bindAppearances.Add((uint)transmogItem.ItemModifiedAppearanceID); } // add cost cost += itemTransmogrified.GetSellPrice(_player); } else { resetAppearanceItems.Add(itemTransmogrified); } if (transmogItem.SpellItemEnchantmentID != 0) { if (transmogItem.Slot != EquipmentSlot.MainHand && transmogItem.Slot != EquipmentSlot.OffHand) { Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify illusion into non-weapon slot ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.Slot); return; } SpellItemEnchantmentRecord illusion = CliDB.SpellItemEnchantmentStorage.LookupByKey(transmogItem.SpellItemEnchantmentID); if (illusion == null) { Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify illusion using invalid enchant ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.SpellItemEnchantmentID); return; } if (illusion.ItemVisual == 0 || !illusion.Flags.HasAnyFlag(EnchantmentSlotMask.Collectable)) { Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify illusion using not allowed enchant ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.SpellItemEnchantmentID); return; } PlayerConditionRecord condition = CliDB.PlayerConditionStorage.LookupByKey(illusion.TransmogPlayerConditionID); if (condition != null) { if (!ConditionManager.IsPlayerMeetingCondition(player, condition)) { Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify illusion using not collected enchant ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.SpellItemEnchantmentID); return; } } if (illusion.ScalingClassRestricted > 0 && illusion.ScalingClassRestricted != (byte)player.GetClass()) { Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify illusion using not allowed class enchant ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.SpellItemEnchantmentID); return; } illusionItems[itemTransmogrified] = (uint)transmogItem.SpellItemEnchantmentID; cost += illusion.TransmogCost; } else { resetIllusionItems.Add(itemTransmogrified); } } if (cost != 0) // 0 cost if reverting look { if (!player.HasEnoughMoney(cost)) { return; } player.ModifyMoney(-cost); } // Everything is fine, proceed foreach (var transmogPair in transmogItems) { Item transmogrified = transmogPair.Key; if (!transmogrifyItems.CurrentSpecOnly) { transmogrified.SetModifier(ItemModifier.TransmogAppearanceAllSpecs, transmogPair.Value); transmogrified.SetModifier(ItemModifier.TransmogAppearanceSpec1, 0); transmogrified.SetModifier(ItemModifier.TransmogAppearanceSpec2, 0); transmogrified.SetModifier(ItemModifier.TransmogAppearanceSpec3, 0); transmogrified.SetModifier(ItemModifier.TransmogAppearanceSpec4, 0); } else { if (transmogrified.GetModifier(ItemModifier.TransmogAppearanceSpec1) == 0) { transmogrified.SetModifier(ItemModifier.TransmogAppearanceSpec1, transmogrified.GetModifier(ItemModifier.TransmogAppearanceAllSpecs)); } if (transmogrified.GetModifier(ItemModifier.TransmogAppearanceSpec2) == 0) { transmogrified.SetModifier(ItemModifier.TransmogAppearanceSpec2, transmogrified.GetModifier(ItemModifier.TransmogAppearanceAllSpecs)); } if (transmogrified.GetModifier(ItemModifier.TransmogAppearanceSpec3) == 0) { transmogrified.SetModifier(ItemModifier.TransmogAppearanceSpec3, transmogrified.GetModifier(ItemModifier.TransmogAppearanceAllSpecs)); } if (transmogrified.GetModifier(ItemModifier.TransmogAppearanceSpec4) == 0) { transmogrified.SetModifier(ItemModifier.TransmogAppearanceSpec4, transmogrified.GetModifier(ItemModifier.TransmogAppearanceAllSpecs)); } transmogrified.SetModifier(ItemConst.AppearanceModifierSlotBySpec[player.GetActiveTalentGroup()], transmogPair.Value); } player.SetVisibleItemSlot(transmogrified.GetSlot(), transmogrified); transmogrified.SetNotRefundable(player); transmogrified.ClearSoulboundTradeable(player); transmogrified.SetState(ItemUpdateState.Changed, player); } foreach (var illusionPair in illusionItems) { Item transmogrified = illusionPair.Key; if (!transmogrifyItems.CurrentSpecOnly) { transmogrified.SetModifier(ItemModifier.EnchantIllusionAllSpecs, illusionPair.Value); transmogrified.SetModifier(ItemModifier.EnchantIllusionSpec1, 0); transmogrified.SetModifier(ItemModifier.EnchantIllusionSpec2, 0); transmogrified.SetModifier(ItemModifier.EnchantIllusionSpec3, 0); transmogrified.SetModifier(ItemModifier.EnchantIllusionSpec4, 0); } else { if (transmogrified.GetModifier(ItemModifier.EnchantIllusionSpec1) == 0) { transmogrified.SetModifier(ItemModifier.EnchantIllusionSpec1, transmogrified.GetModifier(ItemModifier.EnchantIllusionAllSpecs)); } if (transmogrified.GetModifier(ItemModifier.EnchantIllusionSpec2) == 0) { transmogrified.SetModifier(ItemModifier.EnchantIllusionSpec2, transmogrified.GetModifier(ItemModifier.EnchantIllusionAllSpecs)); } if (transmogrified.GetModifier(ItemModifier.EnchantIllusionSpec3) == 0) { transmogrified.SetModifier(ItemModifier.EnchantIllusionSpec3, transmogrified.GetModifier(ItemModifier.EnchantIllusionAllSpecs)); } if (transmogrified.GetModifier(ItemModifier.EnchantIllusionSpec4) == 0) { transmogrified.SetModifier(ItemModifier.EnchantIllusionSpec4, transmogrified.GetModifier(ItemModifier.EnchantIllusionAllSpecs)); } transmogrified.SetModifier(ItemConst.IllusionModifierSlotBySpec[player.GetActiveTalentGroup()], illusionPair.Value); } player.SetVisibleItemSlot(transmogrified.GetSlot(), transmogrified); transmogrified.SetNotRefundable(player); transmogrified.ClearSoulboundTradeable(player); transmogrified.SetState(ItemUpdateState.Changed, player); } foreach (Item item in resetAppearanceItems) { if (!transmogrifyItems.CurrentSpecOnly) { item.SetModifier(ItemModifier.TransmogAppearanceAllSpecs, 0); item.SetModifier(ItemModifier.TransmogAppearanceSpec1, 0); item.SetModifier(ItemModifier.TransmogAppearanceSpec2, 0); item.SetModifier(ItemModifier.TransmogAppearanceSpec3, 0); item.SetModifier(ItemModifier.TransmogAppearanceSpec4, 0); } else { if (item.GetModifier(ItemModifier.TransmogAppearanceSpec1) == 0) { item.SetModifier(ItemModifier.TransmogAppearanceSpec1, item.GetModifier(ItemModifier.TransmogAppearanceAllSpecs)); } if (item.GetModifier(ItemModifier.TransmogAppearanceSpec2) == 0) { item.SetModifier(ItemModifier.TransmogAppearanceSpec2, item.GetModifier(ItemModifier.TransmogAppearanceAllSpecs)); } if (item.GetModifier(ItemModifier.TransmogAppearanceSpec2) == 0) { item.SetModifier(ItemModifier.TransmogAppearanceSpec3, item.GetModifier(ItemModifier.TransmogAppearanceAllSpecs)); } if (item.GetModifier(ItemModifier.TransmogAppearanceSpec4) == 0) { item.SetModifier(ItemModifier.TransmogAppearanceSpec4, item.GetModifier(ItemModifier.TransmogAppearanceAllSpecs)); } item.SetModifier(ItemConst.AppearanceModifierSlotBySpec[player.GetActiveTalentGroup()], 0); item.SetModifier(ItemModifier.EnchantIllusionAllSpecs, 0); } item.SetState(ItemUpdateState.Changed, player); player.SetVisibleItemSlot(item.GetSlot(), item); } foreach (Item item in resetIllusionItems) { if (!transmogrifyItems.CurrentSpecOnly) { item.SetModifier(ItemModifier.EnchantIllusionAllSpecs, 0); item.SetModifier(ItemModifier.EnchantIllusionSpec1, 0); item.SetModifier(ItemModifier.EnchantIllusionSpec2, 0); item.SetModifier(ItemModifier.EnchantIllusionSpec3, 0); item.SetModifier(ItemModifier.EnchantIllusionSpec4, 0); } else { if (item.GetModifier(ItemModifier.EnchantIllusionSpec1) == 0) { item.SetModifier(ItemModifier.EnchantIllusionSpec1, item.GetModifier(ItemModifier.EnchantIllusionAllSpecs)); } if (item.GetModifier(ItemModifier.EnchantIllusionSpec2) == 0) { item.SetModifier(ItemModifier.EnchantIllusionSpec2, item.GetModifier(ItemModifier.EnchantIllusionAllSpecs)); } if (item.GetModifier(ItemModifier.EnchantIllusionSpec3) == 0) { item.SetModifier(ItemModifier.EnchantIllusionSpec3, item.GetModifier(ItemModifier.EnchantIllusionAllSpecs)); } if (item.GetModifier(ItemModifier.EnchantIllusionSpec4) == 0) { item.SetModifier(ItemModifier.EnchantIllusionSpec4, item.GetModifier(ItemModifier.EnchantIllusionAllSpecs)); } item.SetModifier(ItemConst.IllusionModifierSlotBySpec[player.GetActiveTalentGroup()], 0); item.SetModifier(ItemModifier.TransmogAppearanceAllSpecs, 0); } item.SetState(ItemUpdateState.Changed, player); player.SetVisibleItemSlot(item.GetSlot(), item); } foreach (uint itemModifedAppearanceId in bindAppearances) { var itemsProvidingAppearance = GetCollectionMgr().GetItemsProvidingTemporaryAppearance(itemModifedAppearanceId); foreach (ObjectGuid itemGuid in itemsProvidingAppearance) { Item item = player.GetItemByGuid(itemGuid); if (item) { item.SetNotRefundable(player); item.ClearSoulboundTradeable(player); GetCollectionMgr().AddItemAppearance(item); } } } }
void MoveItems(Item[] myItems, Item[] hisItems) { Player trader = GetPlayer().GetTrader(); if (!trader) return; for (byte i = 0; i < (int)TradeSlots.TradedCount; ++i) { List<ItemPosCount> traderDst = new List<ItemPosCount>(); List<ItemPosCount> playerDst = new List<ItemPosCount>(); bool traderCanTrade = (myItems[i] == null || trader.CanStoreItem(ItemConst.NullBag, ItemConst.NullSlot, traderDst, myItems[i], false) == InventoryResult.Ok); bool playerCanTrade = (hisItems[i] == null || GetPlayer().CanStoreItem(ItemConst.NullBag, ItemConst.NullSlot, playerDst, hisItems[i], false) == InventoryResult.Ok); if (traderCanTrade && playerCanTrade) { // Ok, if trade item exists and can be stored // If we trade in both directions we had to check, if the trade will work before we actually do it // A roll back is not possible after we stored it if (myItems[i]) { // logging Log.outDebug(LogFilter.Network, "partner storing: {0}", myItems[i].GetGUID().ToString()); if (HasPermission(RBACPermissions.LogGmTrade)) { Log.outCommand(_player.GetSession().GetAccountId(), "GM {0} (Account: {1}) trade: {2} (Entry: {3} Count: {4}) to player: {5} (Account: {6})", GetPlayer().GetName(), GetPlayer().GetSession().GetAccountId(), myItems[i].GetTemplate().GetName(), myItems[i].GetEntry(), myItems[i].GetCount(), trader.GetName(), trader.GetSession().GetAccountId()); } // adjust time (depends on /played) if (myItems[i].HasItemFlag(ItemFieldFlags.BopTradeable)) myItems[i].SetCreatePlayedTime(trader.GetTotalPlayedTime() - (GetPlayer().GetTotalPlayedTime() - myItems[i].m_itemData.CreatePlayedTime)); // store trader.MoveItemToInventory(traderDst, myItems[i], true, true); } if (hisItems[i]) { // logging Log.outDebug(LogFilter.Network, "player storing: {0}", hisItems[i].GetGUID().ToString()); if (HasPermission(RBACPermissions.LogGmTrade)) { Log.outCommand(trader.GetSession().GetAccountId(), "GM {0} (Account: {1}) trade: {2} (Entry: {3} Count: {4}) to player: {5} (Account: {6})", trader.GetName(), trader.GetSession().GetAccountId(), hisItems[i].GetTemplate().GetName(), hisItems[i].GetEntry(), hisItems[i].GetCount(), GetPlayer().GetName(), GetPlayer().GetSession().GetAccountId()); } // adjust time (depends on /played) if (hisItems[i].HasItemFlag(ItemFieldFlags.BopTradeable)) hisItems[i].SetCreatePlayedTime(GetPlayer().GetTotalPlayedTime() - (trader.GetTotalPlayedTime() - hisItems[i].m_itemData.CreatePlayedTime)); // store GetPlayer().MoveItemToInventory(playerDst, hisItems[i], true, true); } } else { // in case of fatal error log error message // return the already removed items to the original owner if (myItems[i]) { if (!traderCanTrade) Log.outError(LogFilter.Network, "trader can't store item: {0}", myItems[i].GetGUID().ToString()); if (GetPlayer().CanStoreItem(ItemConst.NullBag, ItemConst.NullSlot, playerDst, myItems[i], false) == InventoryResult.Ok) GetPlayer().MoveItemToInventory(playerDst, myItems[i], true, true); else Log.outError(LogFilter.Network, "player can't take item back: {0}", myItems[i].GetGUID().ToString()); } // return the already removed items to the original owner if (hisItems[i]) { if (!playerCanTrade) Log.outError(LogFilter.Network, "player can't store item: {0}", hisItems[i].GetGUID().ToString()); if (trader.CanStoreItem(ItemConst.NullBag, ItemConst.NullSlot, traderDst, hisItems[i], false) == InventoryResult.Ok) trader.MoveItemToInventory(traderDst, hisItems[i], true, true); else Log.outError(LogFilter.Network, "trader can't take item back: {0}", hisItems[i].GetGUID().ToString()); } } } }