void HandlePetSpellAutocast(PetSpellAutocast packet) { Creature pet = ObjectAccessor.GetCreatureOrPetOrVehicle(GetPlayer(), packet.PetGUID); if (!pet) { Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocast: {0} not found.", packet.PetGUID.ToString()); return; } if (pet != GetPlayer().GetGuardianPet() && pet != GetPlayer().GetCharmed()) { Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocast: {0} isn't pet of player {1} ({2}).", packet.PetGUID.ToString(), GetPlayer().GetName(), GetPlayer().GetGUID().ToString()); return; } SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(packet.SpellID, pet.GetMap().GetDifficultyID()); if (spellInfo == null) { Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocast: Unknown spell id {0} used by {1}.", packet.SpellID, packet.PetGUID.ToString()); return; } List <Unit> pets = new(); foreach (Unit controlled in _player.m_Controlled) { if (controlled.GetEntry() == pet.GetEntry() && controlled.IsAlive()) { pets.Add(controlled); } } foreach (Unit petControlled in pets) { // do not add not learned spells/ passive spells if (!petControlled.HasSpell(packet.SpellID) || !spellInfo.IsAutocastable()) { return; } CharmInfo charmInfo = petControlled.GetCharmInfo(); if (charmInfo == null) { Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocastOpcod: object {0} is considered pet-like but doesn't have a charminfo!", petControlled.GetGUID().ToString()); return; } if (petControlled.IsPet()) { petControlled.ToPet().ToggleAutocast(spellInfo, packet.AutocastEnabled); } else { charmInfo.ToggleCreatureAutocast(spellInfo, packet.AutocastEnabled); } charmInfo.SetSpellAutocast(spellInfo, packet.AutocastEnabled); } }
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()); } } } } }
void HandleCastSpell(CastSpell cast) { // ignore for remote control state (for player case) Unit mover = GetPlayer().m_unitMovedByMe; if (mover != GetPlayer() && mover.IsTypeId(TypeId.Player)) { return; } SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(cast.Cast.SpellID); if (spellInfo == null) { Log.outError(LogFilter.Network, "WORLD: unknown spell id {0}", cast.Cast.SpellID); return; } if (spellInfo.IsPassive()) { return; } Unit caster = mover; if (caster.IsTypeId(TypeId.Unit) && !caster.ToCreature().HasSpell(spellInfo.Id)) { // If the vehicle creature does not have the spell but it allows the passenger to cast own spells // change caster to player and let him cast if (!GetPlayer().IsOnVehicle(caster) || spellInfo.CheckVehicle(GetPlayer()) != SpellCastResult.SpellCastOk) { return; } caster = GetPlayer(); } // check known spell or raid marker spell (which not requires player to know it) if (caster.IsTypeId(TypeId.Player) && !caster.ToPlayer().HasActiveSpell(spellInfo.Id) && !spellInfo.HasEffect(SpellEffectName.ChangeRaidMarker) && !spellInfo.HasAttribute(SpellAttr8.RaidMarker)) { return; } // Check possible spell cast overrides spellInfo = caster.GetCastSpellInfo(spellInfo); // Client is resending autoshot cast opcode when other spell is casted during shoot rotation // Skip it to prevent "interrupt" message if (spellInfo.IsAutoRepeatRangedSpell() && GetPlayer().GetCurrentSpell(CurrentSpellTypes.AutoRepeat) != null && GetPlayer().GetCurrentSpell(CurrentSpellTypes.AutoRepeat).m_spellInfo == spellInfo) { return; } // can't use our own spells when we're in possession of another unit, if (GetPlayer().isPossessing()) { return; } // client provided targets SpellCastTargets targets = new SpellCastTargets(caster, cast.Cast); // auto-selection buff level base at target level (in spellInfo) if (targets.GetUnitTarget() != null) { SpellInfo actualSpellInfo = spellInfo.GetAuraRankForLevel(targets.GetUnitTarget().GetLevelForTarget(caster)); // if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message if (actualSpellInfo != null) { spellInfo = actualSpellInfo; } } if (cast.Cast.MoveUpdate.HasValue) { HandleMovementOpcode(ClientOpcodes.MoveStop, cast.Cast.MoveUpdate.Value); } Spell spell = new Spell(caster, spellInfo, TriggerCastFlags.None, ObjectGuid.Empty, false); SpellPrepare spellPrepare = new SpellPrepare(); spellPrepare.ClientCastID = cast.Cast.CastID; spellPrepare.ServerCastID = spell.m_castId; SendPacket(spellPrepare); spell.m_fromClient = true; spell.m_misc.Data0 = cast.Cast.Misc[0]; spell.m_misc.Data1 = cast.Cast.Misc[1]; spell.prepare(targets); }
void HandleQuestgiverCompleteQuest(QuestGiverCompleteQuest packet) { bool autoCompleteMode = packet.FromScript; // 0 - standart complete quest mode with npc, 1 - auto-complete mode Quest quest = Global.ObjectMgr.GetQuestTemplate(packet.QuestID); if (quest == null) { return; } if (autoCompleteMode && !quest.HasFlag(QuestFlags.AutoComplete)) { return; } WorldObject obj; if (autoCompleteMode) { obj = GetPlayer(); } else { obj = Global.ObjAccessor.GetObjectByTypeMask(GetPlayer(), packet.QuestGiverGUID, TypeMask.Unit | TypeMask.GameObject); } if (!obj) { return; } if (!autoCompleteMode) { if (!obj.HasInvolvedQuest(packet.QuestID)) { return; } // some kind of WPE protection if (!GetPlayer().CanInteractWithQuestGiver(obj)) { return; } } else { // Do not allow completing quests on other players. if (packet.QuestGiverGUID != GetPlayer().GetGUID()) { return; } } if (!GetPlayer().CanSeeStartQuest(quest) && GetPlayer().GetQuestStatus(packet.QuestID) == QuestStatus.None) { Log.outError(LogFilter.Network, "Possible hacking attempt: Player {0} ({1}) tried to complete quest [entry: {2}] without being in possession of the quest!", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), packet.QuestID); return; } Battleground bg = GetPlayer().GetBattleground(); if (bg) { bg.HandleQuestComplete(packet.QuestID, GetPlayer()); } if (GetPlayer().GetQuestStatus(packet.QuestID) != QuestStatus.Complete) { if (quest.IsRepeatable()) { GetPlayer().PlayerTalkClass.SendQuestGiverRequestItems(quest, packet.QuestGiverGUID, GetPlayer().CanCompleteRepeatableQuest(quest), false); } else { GetPlayer().PlayerTalkClass.SendQuestGiverRequestItems(quest, packet.QuestGiverGUID, GetPlayer().CanRewardQuest(quest, false), false); } } else { if (quest.HasSpecialFlag(QuestSpecialFlags.Deliver)) // some items required { GetPlayer().PlayerTalkClass.SendQuestGiverRequestItems(quest, packet.QuestGiverGUID, GetPlayer().CanRewardQuest(quest, false), false); } else // no items required { GetPlayer().PlayerTalkClass.SendQuestGiverOfferReward(quest, packet.QuestGiverGUID, true); } } }
public uint SendChat(Creature source, byte textGroup, WorldObject whisperTarget = null, ChatMsg msgType = ChatMsg.Addon, Language language = Language.Addon, CreatureTextRange range = CreatureTextRange.Normal, uint sound = 0, SoundKitPlayType playType = SoundKitPlayType.Normal, Team team = Team.Other, bool gmOnly = false, Player srcPlr = null) { if (source == null) { return(0); } var sList = mTextMap.LookupByKey(source.GetEntry()); if (sList == null) { Log.outError(LogFilter.Sql, "GossipManager: Could not find Text for Creature({0}) Entry {1} in 'creature_text' table. Ignoring.", source.GetName(), source.GetEntry()); return(0); } var textGroupContainer = sList.LookupByKey(textGroup); if (textGroupContainer.Empty()) { Log.outError(LogFilter.ChatSystem, "GossipManager: Could not find TextGroup {0} for Creature({1}) GuidLow {2} Entry {3}. Ignoring.", textGroup, source.GetName(), source.GetGUID().ToString(), source.GetEntry()); return(0); } List <CreatureTextEntry> tempGroup = new(); var repeatGroup = source.GetTextRepeatGroup(textGroup); foreach (var entry in textGroupContainer) { if (!repeatGroup.Contains(entry.id)) { tempGroup.Add(entry); } } if (tempGroup.Empty()) { source.ClearTextRepeatGroup(textGroup); tempGroup = textGroupContainer; } var textEntry = tempGroup.SelectRandomElementByWeight(t => t.probability); ChatMsg finalType = (msgType == ChatMsg.Addon) ? textEntry.type : msgType; Language finalLang = (language == Language.Addon) ? textEntry.lang : language; uint finalSound = textEntry.sound; SoundKitPlayType finalPlayType = textEntry.SoundPlayType; if (sound != 0) { finalSound = sound; finalPlayType = playType; } else { BroadcastTextRecord bct = CliDB.BroadcastTextStorage.LookupByKey(textEntry.BroadcastTextId); if (bct != null) { uint broadcastTextSoundId = bct.SoundKitID[source.GetGender() == Gender.Female ? 1 : 0]; if (broadcastTextSoundId != 0) { finalSound = broadcastTextSoundId; } } } if (range == CreatureTextRange.Normal) { range = textEntry.TextRange; } if (finalSound != 0) { SendSound(source, finalSound, finalType, whisperTarget, range, team, gmOnly, textEntry.BroadcastTextId, finalPlayType); } Unit finalSource = source; if (srcPlr) { finalSource = srcPlr; } if (textEntry.emote != 0) { SendEmote(finalSource, textEntry.emote); } if (srcPlr) { PlayerTextBuilder builder = new(source, finalSource, finalSource.GetGender(), finalType, textEntry.groupId, textEntry.id, finalLang, whisperTarget); SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly); } else { CreatureTextBuilder builder = new(finalSource, finalSource.GetGender(), finalType, textEntry.groupId, textEntry.id, finalLang, whisperTarget); SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly); } source.SetTextRepeatId(textGroup, textEntry.id); return(textEntry.duration); }
void HandleMoveWorldportAck() { // ignore unexpected far teleports if (!GetPlayer().IsBeingTeleportedFar()) { return; } bool seamlessTeleport = GetPlayer().IsBeingTeleportedSeamlessly(); GetPlayer().SetSemaphoreTeleportFar(false); // get the teleport destination WorldLocation loc = GetPlayer().GetTeleportDest(); // possible errors in the coordinate validity check if (!GridDefines.IsValidMapCoord(loc)) { LogoutPlayer(false); return; } // get the destination map entry, not the current one, this will fix homebind and reset greeting MapRecord mapEntry = CliDB.MapStorage.LookupByKey(loc.GetMapId()); InstanceTemplate mInstance = Global.ObjectMgr.GetInstanceTemplate(loc.GetMapId()); // reset instance validity, except if going to an instance inside an instance if (!GetPlayer().m_InstanceValid&& mInstance == null) { GetPlayer().m_InstanceValid = true; } Map oldMap = GetPlayer().GetMap(); Map newMap = Global.MapMgr.CreateMap(loc.GetMapId(), GetPlayer()); if (GetPlayer().IsInWorld) { Log.outError(LogFilter.Network, "Player (Name {0}) is still in world when teleported from map {1} to new map {2}", GetPlayer().GetName(), oldMap.GetId(), loc.GetMapId()); oldMap.RemovePlayerFromMap(GetPlayer(), false); } // relocate the player to the teleport destination // the CannotEnter checks are done in TeleporTo but conditions may change // while the player is in transit, for example the map may get full if (newMap == null || newMap.CannotEnter(GetPlayer()) != 0) { Log.outError(LogFilter.Network, "Map {0} could not be created for {1} ({2}), porting player to homebind", loc.GetMapId(), newMap ? newMap.GetMapName() : "Unknown", GetPlayer().GetGUID().ToString()); GetPlayer().TeleportTo(GetPlayer().GetHomebind()); return; } float z = loc.GetPositionZ(); if (GetPlayer().HasUnitMovementFlag(MovementFlag.Hover)) { z += GetPlayer().m_unitData.HoverHeight; } GetPlayer().Relocate(loc.GetPositionX(), loc.GetPositionY(), z, loc.GetOrientation()); GetPlayer().SetFallInformation(0, GetPlayer().GetPositionZ()); GetPlayer().ResetMap(); GetPlayer().SetMap(newMap); ResumeToken resumeToken = new(); resumeToken.SequenceIndex = _player.m_movementCounter; resumeToken.Reason = seamlessTeleport ? 2 : 1u; SendPacket(resumeToken); if (!seamlessTeleport) { GetPlayer().SendInitialPacketsBeforeAddToMap(); } if (!GetPlayer().GetMap().AddPlayerToMap(GetPlayer(), !seamlessTeleport)) { Log.outError(LogFilter.Network, "WORLD: failed to teleport player {0} ({1}) to map {2} ({3}) because of unknown reason!", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), loc.GetMapId(), newMap ? newMap.GetMapName() : "Unknown"); GetPlayer().ResetMap(); GetPlayer().SetMap(oldMap); GetPlayer().TeleportTo(GetPlayer().GetHomebind()); return; } // Battleground state prepare (in case join to BG), at relogin/tele player not invited // only add to bg group and object, if the player was invited (else he entered through command) if (GetPlayer().InBattleground()) { // cleanup setting if outdated if (!mapEntry.IsBattlegroundOrArena()) { // We're not in BG GetPlayer().SetBattlegroundId(0, BattlegroundTypeId.None); // reset destination bg team GetPlayer().SetBGTeam(0); } // join to bg case else { Battleground bg = GetPlayer().GetBattleground(); if (bg) { if (GetPlayer().IsInvitedForBattlegroundInstance(GetPlayer().GetBattlegroundId())) { bg.AddPlayer(GetPlayer()); } } } } if (!seamlessTeleport) { GetPlayer().SendInitialPacketsAfterAddToMap(); } else { GetPlayer().UpdateVisibilityForPlayer(); Garrison garrison = GetPlayer().GetGarrison(); if (garrison != null) { garrison.SendRemoteInfo(); } } // flight fast teleport case if (GetPlayer().GetMotionMaster().GetCurrentMovementGeneratorType() == MovementGeneratorType.Flight) { if (!GetPlayer().InBattleground()) { if (!seamlessTeleport) { // short preparations to continue flight IMovementGenerator movementGenerator = GetPlayer().GetMotionMaster().Top(); movementGenerator.Initialize(GetPlayer()); } return; } // Battlegroundstate prepare, stop flight GetPlayer().GetMotionMaster().MovementExpired(); GetPlayer().CleanupAfterTaxiFlight(); } // resurrect character at enter into instance where his corpse exist after add to map if (mapEntry.IsDungeon() && !GetPlayer().IsAlive()) { if (GetPlayer().GetCorpseLocation().GetMapId() == mapEntry.Id) { GetPlayer().ResurrectPlayer(0.5f, false); GetPlayer().SpawnCorpseBones(); } } bool allowMount = !mapEntry.IsDungeon() || mapEntry.IsBattlegroundOrArena(); if (mInstance != null) { // check if this instance has a reset time and send it to player if so Difficulty diff = newMap.GetDifficultyID(); MapDifficultyRecord mapDiff = Global.DB2Mgr.GetMapDifficultyData(mapEntry.Id, diff); if (mapDiff != null) { if (mapDiff.GetRaidDuration() != 0) { long timeReset = Global.InstanceSaveMgr.GetResetTimeFor(mapEntry.Id, diff); if (timeReset != 0) { uint timeleft = (uint)(timeReset - Time.UnixTime); GetPlayer().SendInstanceResetWarning(mapEntry.Id, diff, timeleft, true); } } } // check if instance is valid if (!GetPlayer().CheckInstanceValidity(false)) { GetPlayer().m_InstanceValid = false; } // instance mounting is handled in InstanceTemplate allowMount = mInstance.AllowMount; } // mount allow check if (!allowMount) { GetPlayer().RemoveAurasByType(AuraType.Mounted); } // update zone immediately, otherwise leave channel will cause crash in mtmap uint newzone, newarea; GetPlayer().GetZoneAndAreaId(out newzone, out newarea); GetPlayer().UpdateZone(newzone, newarea); // honorless target if (GetPlayer().pvpInfo.IsHostile) { GetPlayer().CastSpell(GetPlayer(), 2479, true); } // in friendly area else if (GetPlayer().IsPvP() && !GetPlayer().HasPlayerFlag(PlayerFlags.InPVP)) { GetPlayer().UpdatePvP(false, false); } // resummon pet GetPlayer().ResummonPetTemporaryUnSummonedIfAny(); //lets process all delayed operations on successful teleport GetPlayer().ProcessDelayedOperations(); }
void HandleMovementOpcode(ClientOpcodes opcode, MovementInfo movementInfo) { Unit mover = GetPlayer().m_unitMovedByMe; Player plrMover = mover.ToPlayer(); if (plrMover && plrMover.IsBeingTeleported()) { return; } GetPlayer().ValidateMovementInfo(movementInfo); if (movementInfo.Guid != mover.GetGUID()) { Log.outError(LogFilter.Network, "HandleMovementOpcodes: guid error"); return; } if (!movementInfo.Pos.IsPositionValid()) { Log.outError(LogFilter.Network, "HandleMovementOpcodes: Invalid Position"); return; } // stop some emotes at player move if (plrMover && (plrMover.GetEmoteState() != 0)) { plrMover.SetEmoteState(Emote.OneshotNone); } //handle special cases if (!movementInfo.transport.guid.IsEmpty()) { // We were teleported, skip packets that were broadcast before teleport if (movementInfo.Pos.GetExactDist2d(mover) > MapConst.SizeofGrids) { return; } if (Math.Abs(movementInfo.transport.pos.GetPositionX()) > 75f || Math.Abs(movementInfo.transport.pos.GetPositionY()) > 75f || Math.Abs(movementInfo.transport.pos.GetPositionZ()) > 75f) { return; } if (!GridDefines.IsValidMapCoord(movementInfo.Pos.posX + movementInfo.transport.pos.posX, movementInfo.Pos.posY + movementInfo.transport.pos.posY, movementInfo.Pos.posZ + movementInfo.transport.pos.posZ, movementInfo.Pos.Orientation + movementInfo.transport.pos.Orientation)) { return; } if (plrMover) { if (!plrMover.GetTransport()) { Transport transport = plrMover.GetMap().GetTransport(movementInfo.transport.guid); if (transport) { transport.AddPassenger(plrMover); } } else if (plrMover.GetTransport().GetGUID() != movementInfo.transport.guid) { plrMover.GetTransport().RemovePassenger(plrMover); Transport transport = plrMover.GetMap().GetTransport(movementInfo.transport.guid); if (transport) { transport.AddPassenger(plrMover); } else { movementInfo.ResetTransport(); } } } if (!mover.GetTransport() && !mover.GetVehicle()) { GameObject go = mover.GetMap().GetGameObject(movementInfo.transport.guid); if (!go || go.GetGoType() != GameObjectTypes.Transport) { movementInfo.transport.Reset(); } } } else if (plrMover && plrMover.GetTransport()) // if we were on a transport, leave { plrMover.GetTransport().RemovePassenger(plrMover); } // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map). if (opcode == ClientOpcodes.MoveFallLand && plrMover && !plrMover.IsInFlight()) { plrMover.HandleFall(movementInfo); } // interrupt parachutes upon falling or landing in water if (opcode == ClientOpcodes.MoveFallLand || opcode == ClientOpcodes.MoveStartSwim) { mover.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Landing); // Parachutes } uint mstime = GameTime.GetGameTimeMS(); if (m_clientTimeDelay == 0) { m_clientTimeDelay = mstime - movementInfo.Time; } movementInfo.Time = movementInfo.Time + m_clientTimeDelay; movementInfo.Guid = mover.GetGUID(); mover.m_movementInfo = movementInfo; // Some vehicles allow the passenger to turn by himself Vehicle vehicle = mover.GetVehicle(); if (vehicle) { VehicleSeatRecord seat = vehicle.GetSeatForPassenger(mover); if (seat != null) { if (seat.HasSeatFlag(VehicleSeatFlags.AllowTurning)) { if (movementInfo.Pos.GetOrientation() != mover.GetOrientation()) { mover.SetOrientation(movementInfo.Pos.GetOrientation()); mover.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Turning); } } } return; } mover.UpdatePosition(movementInfo.Pos); MoveUpdate moveUpdate = new(); moveUpdate.Status = mover.m_movementInfo; mover.SendMessageToSet(moveUpdate, GetPlayer()); if (plrMover) // nothing is charmed, or player charmed { if (plrMover.IsSitState() && movementInfo.HasMovementFlag(MovementFlag.MaskMoving | MovementFlag.MaskTurning)) { plrMover.SetStandState(UnitStandStateType.Stand); } plrMover.UpdateFallInformationIfNeed(movementInfo, opcode); if (movementInfo.Pos.posZ < plrMover.GetMap().GetMinHeight(plrMover.GetPhaseShift(), movementInfo.Pos.GetPositionX(), movementInfo.Pos.GetPositionY())) { if (!(plrMover.GetBattleground() && plrMover.GetBattleground().HandlePlayerUnderMap(GetPlayer()))) { // NOTE: this is actually called many times while falling // even after the player has been teleported away // @todo discard movement packets after the player is rooted if (plrMover.IsAlive()) { plrMover.AddPlayerFlag(PlayerFlags.IsOutOfBounds); plrMover.EnvironmentalDamage(EnviromentalDamage.FallToVoid, (uint)GetPlayer().GetMaxHealth()); // player can be alive if GM/etc // change the death state to CORPSE to prevent the death timer from // starting in the next player update if (plrMover.IsAlive()) { plrMover.KillPlayer(); } } } } else { plrMover.RemovePlayerFlag(PlayerFlags.IsOutOfBounds); } if (opcode == ClientOpcodes.MoveJump) { plrMover.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Jump, 605); // Mind Control plrMover.ProcSkillsAndAuras(null, ProcFlags.Jump, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null); } } }
BattlenetRpcErrorCode HandleGetAchievementsFile(GetAchievementsFileRequest request, GetAchievementsFileResponse response) { Log.outError(LogFilter.ServiceProtobuf, "{0} Client tried to call not implemented method GameUtilitiesService.GetAchievementsFile: {1}", GetCallerInfo(), request.ToString()); return(BattlenetRpcErrorCode.RpcNotImplemented); }
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; } }
BattlenetRpcErrorCode HandlePresenceChannelCreated(PresenceChannelCreatedRequest request, Bgs.Protocol.NoData response) { Log.outError(LogFilter.ServiceProtobuf, "{0} Client tried to call not implemented method GameUtilitiesService.PresenceChannelCreated: {1}", GetCallerInfo(), request.ToString()); return(BattlenetRpcErrorCode.RpcNotImplemented); }
BattlenetRpcErrorCode HandleOnGameAccountOffline(GameAccountOfflineNotification request) { Log.outError(LogFilter.ServiceProtobuf, "{0} Client tried to call not implemented method GameUtilitiesService.OnGameAccountOffline: {1}", GetCallerInfo(), request.ToString()); return(BattlenetRpcErrorCode.RpcNotImplemented); }
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 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); } }
void HandlePetCastSpell(PetCastSpell petCastSpell) { Unit caster = Global.ObjAccessor.GetUnit(GetPlayer(), petCastSpell.PetGUID); if (!caster) { Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: Caster {0} not found.", petCastSpell.PetGUID.ToString()); return; } SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(petCastSpell.Cast.SpellID, caster.GetMap().GetDifficultyID()); if (spellInfo == null) { Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: unknown spell id {0} tried to cast by {1}", petCastSpell.Cast.SpellID, petCastSpell.PetGUID.ToString()); return; } // This opcode is also sent from charmed and possessed units (players and creatures) if (caster != GetPlayer().GetGuardianPet() && caster != GetPlayer().GetCharmed()) { Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: {0} isn't pet of player {1} ({2}).", petCastSpell.PetGUID.ToString(), GetPlayer().GetName(), GetPlayer().GetGUID().ToString()); return; } SpellCastTargets targets = new(caster, petCastSpell.Cast); TriggerCastFlags triggerCastFlags = TriggerCastFlags.None; if (spellInfo.IsPassive()) { return; } // cast only learned spells if (!caster.HasSpell(spellInfo.Id)) { bool allow = false; // allow casting of spells triggered by clientside periodic trigger auras if (caster.HasAuraTypeWithTriggerSpell(AuraType.PeriodicTriggerSpellFromClient, spellInfo.Id)) { allow = true; triggerCastFlags = TriggerCastFlags.FullMask; } if (!allow) { return; } } Spell spell = new(caster, spellInfo, triggerCastFlags); spell.m_fromClient = true; spell.m_misc.Data0 = petCastSpell.Cast.Misc[0]; spell.m_misc.Data1 = petCastSpell.Cast.Misc[1]; spell.m_targets = targets; SpellCastResult result = spell.CheckPetCast(null); if (result == SpellCastResult.SpellCastOk) { Creature creature = caster.ToCreature(); if (creature) { Pet pet = creature.ToPet(); if (pet) { // 10% chance to play special pet attack talk, else growl // actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell if (pet.GetPetType() == PetType.Summon && (RandomHelper.IRand(0, 100) < 10)) { pet.SendPetTalk(PetTalk.SpecialSpell); } else { pet.SendPetAIReaction(petCastSpell.PetGUID); } } } SpellPrepare spellPrepare = new(); spellPrepare.ClientCastID = petCastSpell.Cast.CastID; spellPrepare.ServerCastID = spell.m_castId; SendPacket(spellPrepare); spell.Prepare(targets); } else { spell.SendPetCastResult(result); if (!caster.GetSpellHistory().HasCooldown(spellInfo.Id)) { caster.GetSpellHistory().ResetCooldown(spellInfo.Id, true); } spell.Finish(false); spell.Dispose(); } }
void HandleMovementOpcode(ClientOpcodes opcode, MovementInfo movementInfo) { Unit mover = GetPlayer().m_unitMovedByMe; Player plrMover = mover.ToPlayer(); if (plrMover && plrMover.IsBeingTeleported()) { return; } GetPlayer().ValidateMovementInfo(movementInfo); if (movementInfo.Guid != mover.GetGUID()) { Log.outError(LogFilter.Network, "HandleMovementOpcodes: guid error"); return; } if (!movementInfo.Pos.IsPositionValid()) { Log.outError(LogFilter.Network, "HandleMovementOpcodes: Invalid Position"); return; } // stop some emotes at player move if (plrMover && (plrMover.GetUInt32Value(UnitFields.NpcEmotestate) != 0)) { plrMover.SetUInt32Value(UnitFields.NpcEmotestate, (uint)Emote.OneshotNone); } //handle special cases if (!movementInfo.transport.guid.IsEmpty()) { if (movementInfo.transport.pos.GetPositionX() > 50 || movementInfo.transport.pos.GetPositionY() > 50 || movementInfo.transport.pos.GetPositionZ() > 50) { return; } if (!GridDefines.IsValidMapCoord(movementInfo.Pos.posX + movementInfo.transport.pos.posX, movementInfo.Pos.posY + movementInfo.transport.pos.posY, movementInfo.Pos.posZ + movementInfo.transport.pos.posZ, movementInfo.Pos.Orientation + movementInfo.transport.pos.Orientation)) { return; } if (plrMover) { if (!plrMover.GetTransport()) { Transport transport = plrMover.GetMap().GetTransport(movementInfo.transport.guid); if (transport) { transport.AddPassenger(plrMover); } } else if (plrMover.GetTransport().GetGUID() != movementInfo.transport.guid) { plrMover.GetTransport().RemovePassenger(plrMover); Transport transport = plrMover.GetMap().GetTransport(movementInfo.transport.guid); if (transport) { transport.AddPassenger(plrMover); } else { movementInfo.ResetTransport(); } } } if (!mover.GetTransport() && !mover.GetVehicle()) { GameObject go = mover.GetMap().GetGameObject(movementInfo.transport.guid); if (!go || go.GetGoType() != GameObjectTypes.Transport) { movementInfo.transport.Reset(); } } } else if (plrMover && plrMover.GetTransport()) // if we were on a transport, leave { plrMover.GetTransport().RemovePassenger(plrMover); } // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map). if (opcode == ClientOpcodes.MoveFallLand && plrMover && !plrMover.IsInFlight()) { plrMover.HandleFall(movementInfo); } if (plrMover && movementInfo.HasMovementFlag(MovementFlag.Swimming) != plrMover.IsInWater()) { // now client not include swimming flag in case jumping under water plrMover.SetInWater(!plrMover.IsInWater() || plrMover.GetMap().IsUnderWater(movementInfo.Pos.posX, movementInfo.Pos.posY, movementInfo.Pos.posZ)); } uint mstime = Time.GetMSTime(); if (m_clientTimeDelay == 0) { m_clientTimeDelay = mstime - movementInfo.Time; } movementInfo.Time = movementInfo.Time + m_clientTimeDelay; movementInfo.Guid = mover.GetGUID(); mover.m_movementInfo = movementInfo; // Some vehicles allow the passenger to turn by himself Vehicle vehicle = mover.GetVehicle(); if (vehicle) { VehicleSeatRecord seat = vehicle.GetSeatForPassenger(mover); if (seat != null) { if (seat.Flags[0].HasAnyFlag((uint)VehicleSeatFlags.AllowTurning)) { if (movementInfo.Pos.GetOrientation() != mover.GetOrientation()) { mover.SetOrientation(movementInfo.Pos.GetOrientation()); mover.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Turning); } } } return; } mover.UpdatePosition(movementInfo.Pos); MoveUpdate moveUpdate = new MoveUpdate(); moveUpdate.movementInfo = mover.m_movementInfo; mover.SendMessageToSet(moveUpdate, GetPlayer()); if (plrMover) // nothing is charmed, or player charmed { if (plrMover.IsSitState() && movementInfo.HasMovementFlag(MovementFlag.MaskMoving | MovementFlag.MaskTurning)) { plrMover.SetStandState(UnitStandStateType.Stand); } plrMover.UpdateFallInformationIfNeed(movementInfo, opcode); if (movementInfo.Pos.posZ < plrMover.GetMap().GetMinHeight(movementInfo.Pos.GetPositionX(), movementInfo.Pos.GetPositionY())) { if (!(plrMover.GetBattleground() && plrMover.GetBattleground().HandlePlayerUnderMap(GetPlayer()))) { // NOTE: this is actually called many times while falling // even after the player has been teleported away /// @todo discard movement packets after the player is rooted if (plrMover.IsAlive()) { plrMover.SetFlag(PlayerFields.Flags, PlayerFlags.IsOutOfBounds); plrMover.EnvironmentalDamage(EnviromentalDamage.FallToVoid, (uint)GetPlayer().GetMaxHealth()); // player can be alive if GM/etc // change the death state to CORPSE to prevent the death timer from // starting in the next player update if (!plrMover.IsAlive()) { plrMover.KillPlayer(); } } } } else { plrMover.RemoveFlag(PlayerFields.Flags, PlayerFlags.IsOutOfBounds); } } }
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); }
public bool ReGenerate() { if (m_weatherChances == null) { m_type = WeatherType.Fine; m_grade = 0.0f; return(false); } // Weather statistics: // 30% - no change // 30% - weather gets better (if not fine) or change weather type // 30% - weather worsens (if not fine) // 10% - radical change (if not fine) uint u = RandomHelper.URand(0, 99); if (u < 30) { return(false); } // remember old values WeatherType old_type = m_type; float old_grade = m_grade; long gtime = Global.WorldMgr.GetGameTime(); var ltime = Time.UnixTimeToDateTime(gtime).ToLocalTime(); uint season = (uint)((ltime.DayOfYear - 78 + 365) / 91) % 4; string[] seasonName = { "spring", "summer", "fall", "winter" }; Log.outError(LogFilter.Server, "Generating a change in {0} weather for zone {1}.", seasonName[season], m_zone); if ((u < 60) && (m_grade < 0.33333334f)) // Get fair { m_type = WeatherType.Fine; m_grade = 0.0f; } if ((u < 60) && (m_type != WeatherType.Fine)) // Get better { m_grade -= 0.33333334f; return(true); } if ((u < 90) && (m_type != WeatherType.Fine)) // Get worse { m_grade += 0.33333334f; return(true); } if (m_type != WeatherType.Fine) { // Radical change: // if light . heavy // if medium . change weather type // if heavy . 50% light, 50% change weather type if (m_grade < 0.33333334f) { m_grade = 0.9999f; // go nuts return(true); } else { if (m_grade > 0.6666667f) { // Severe change, but how severe? uint rnd = RandomHelper.URand(0, 99); if (rnd < 50) { m_grade -= 0.6666667f; return(true); } } m_type = WeatherType.Fine; // clear up m_grade = 0; } } // At this point, only weather that isn't doing anything remains but that have weather data uint chance1 = m_weatherChances.data[season].rainChance; uint chance2 = chance1 + m_weatherChances.data[season].snowChance; uint chance3 = chance2 + m_weatherChances.data[season].stormChance; uint rn = RandomHelper.URand(1, 100); if (rn <= chance1) { m_type = WeatherType.Rain; } else if (rn <= chance2) { m_type = WeatherType.Snow; } else if (rn <= chance3) { m_type = WeatherType.Storm; } else { m_type = WeatherType.Fine; } // New weather statistics (if not fine): // 85% light // 7% medium // 7% heavy // If fine 100% sun (no fog) if (m_type == WeatherType.Fine) { m_grade = 0.0f; } else if (u < 90) { m_grade = (float)RandomHelper.NextDouble() * 0.3333f; } else { // Severe change, but how severe? rn = RandomHelper.URand(0, 99); if (rn < 50) { m_grade = (float)RandomHelper.NextDouble() * 0.3333f + 0.3334f; } else { m_grade = (float)RandomHelper.NextDouble() * 0.3333f + 0.6667f; } } // return true only in case weather changes return(m_type != old_type || m_grade != old_grade); }
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); }
void HandleForceSpeedChangeAck(MovementSpeedAck packet) { GetPlayer().ValidateMovementInfo(packet.Ack.Status); // now can skip not our packet if (GetPlayer().GetGUID() != packet.Ack.Status.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(); } } }
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); }
void HandleQuestgiverChooseReward(QuestGiverChooseReward packet) { Quest quest = Global.ObjectMgr.GetQuestTemplate(packet.QuestID); if (quest == null) { return; } // This is Real Item Entry, not slot id as pre 5.x if (packet.ItemChoiceID != 0) { ItemTemplate rewardProto = Global.ObjectMgr.GetItemTemplate(packet.ItemChoiceID); if (rewardProto == null) { Log.outError(LogFilter.Network, "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player {0} ({1}) tried to get invalid reward item (Item Entry: {2}) for quest {3} (possible packet-hacking detected)", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), packet.ItemChoiceID, packet.QuestID); return; } bool itemValid = false; for (uint i = 0; i < quest.GetRewChoiceItemsCount(); ++i) { if (quest.RewardChoiceItemId[i] != 0 && quest.RewardChoiceItemId[i] == packet.ItemChoiceID) { itemValid = true; break; } } if (!itemValid && quest.PackageID != 0) { var questPackageItems = Global.DB2Mgr.GetQuestPackageItems(quest.PackageID); if (questPackageItems != null) { foreach (var questPackageItem in questPackageItems) { if (questPackageItem.ItemID != packet.ItemChoiceID) { continue; } if (_player.CanSelectQuestPackageItem(questPackageItem)) { itemValid = true; break; } } } if (!itemValid) { var questPackageItems1 = Global.DB2Mgr.GetQuestPackageItemsFallback(quest.PackageID); if (questPackageItems1 != null) { foreach (var questPackageItem in questPackageItems1) { if (questPackageItem.ItemID != packet.ItemChoiceID) { continue; } itemValid = true; break; } } } } if (!itemValid) { Log.outError(LogFilter.Network, "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player {0} ({1}) tried to get reward item (Item Entry: {2}) wich is not a reward for quest {3} (possible packet-hacking detected)", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), packet.ItemChoiceID, packet.QuestID); return; } } WorldObject obj = GetPlayer(); if (!quest.HasFlag(QuestFlags.AutoComplete)) { obj = Global.ObjAccessor.GetObjectByTypeMask(GetPlayer(), packet.QuestGiverGUID, TypeMask.Unit | TypeMask.GameObject); if (!obj || !obj.HasInvolvedQuest(packet.QuestID)) { return; } // some kind of WPE protection if (!GetPlayer().CanInteractWithQuestGiver(obj)) { return; } } if ((!GetPlayer().CanSeeStartQuest(quest) && GetPlayer().GetQuestStatus(packet.QuestID) == QuestStatus.None) || (GetPlayer().GetQuestStatus(packet.QuestID) != QuestStatus.Complete && !quest.IsAutoComplete())) { Log.outError(LogFilter.Network, "Error in QuestStatus.Complete: player {0} ({1}) tried to complete quest {2}, but is not allowed to do so (possible packet-hacking or high latency)", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), packet.QuestID); return; } if (GetPlayer().CanRewardQuest(quest, packet.ItemChoiceID, true)) { GetPlayer().RewardQuest(quest, packet.ItemChoiceID, obj); switch (obj.GetTypeId()) { case TypeId.Unit: case TypeId.Player: { //For AutoSubmition was added plr case there as it almost same exclute AI script cases. Creature creatureQGiver = obj.ToCreature(); if (!creatureQGiver || !Global.ScriptMgr.OnQuestReward(GetPlayer(), creatureQGiver, quest, packet.ItemChoiceID)) { // Send next quest Quest nextQuest = GetPlayer().GetNextQuest(packet.QuestGiverGUID, quest); if (nextQuest != null) { // Only send the quest to the player if the conditions are met if (GetPlayer().CanTakeQuest(nextQuest, false)) { if (nextQuest.IsAutoAccept() && GetPlayer().CanAddQuest(nextQuest, true)) { GetPlayer().AddQuestAndCheckCompletion(nextQuest, obj); } GetPlayer().PlayerTalkClass.SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true, false); } } if (creatureQGiver) { creatureQGiver.GetAI().QuestReward(GetPlayer(), quest, packet.ItemChoiceID); } } break; } case TypeId.GameObject: GameObject questGiver = obj.ToGameObject(); if (!Global.ScriptMgr.OnQuestReward(GetPlayer(), questGiver, quest, packet.ItemChoiceID)) { // Send next quest Quest nextQuest = GetPlayer().GetNextQuest(packet.QuestGiverGUID, quest); if (nextQuest != null) { // Only send the quest to the player if the conditions are met if (GetPlayer().CanTakeQuest(nextQuest, false)) { if (nextQuest.IsAutoAccept() && GetPlayer().CanAddQuest(nextQuest, true)) { GetPlayer().AddQuestAndCheckCompletion(nextQuest, obj); } GetPlayer().PlayerTalkClass.SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true, false); } } questGiver.GetAI().QuestReward(GetPlayer(), quest, packet.ItemChoiceID); } break; default: break; } } else { GetPlayer().PlayerTalkClass.SendQuestGiverOfferReward(quest, packet.QuestGiverGUID, true); } }
void LogUnexpectedOpcode(WorldPacket packet, SessionStatus status, string reason) { Log.outError(LogFilter.Network, "Received unexpected opcode {0} Status: {1} Reason: {2} from {3}", (ClientOpcodes)packet.GetOpcode(), status, reason, GetPlayerInfo()); }
void HandlePlayerChoiceResponse(ChoiceResponse choiceResponse) { if (_player.PlayerTalkClass.GetInteractionData().PlayerChoiceId != choiceResponse.ChoiceID) { Log.outError(LogFilter.Player, $"Error in CMSG_CHOICE_RESPONSE: {GetPlayerInfo()} tried to respond to invalid player choice {choiceResponse.ChoiceID} (allowed {_player.PlayerTalkClass.GetInteractionData().PlayerChoiceId}) (possible packet-hacking detected)"); return; } PlayerChoice playerChoice = Global.ObjectMgr.GetPlayerChoice(choiceResponse.ChoiceID); if (playerChoice == null) { return; } PlayerChoiceResponse playerChoiceResponse = playerChoice.GetResponse(choiceResponse.ResponseID); if (playerChoiceResponse == null) { Log.outError(LogFilter.Player, $"Error in CMSG_CHOICE_RESPONSE: {GetPlayerInfo()} tried to select invalid player choice response {choiceResponse.ResponseID} (possible packet-hacking detected)"); return; } Global.ScriptMgr.OnPlayerChoiceResponse(GetPlayer(), (uint)choiceResponse.ChoiceID, (uint)choiceResponse.ResponseID); if (playerChoiceResponse.Reward.HasValue) { var reward = playerChoiceResponse.Reward.Value; if (reward.TitleId != 0) { _player.SetTitle(CliDB.CharTitlesStorage.LookupByKey(reward.TitleId), false); } if (reward.PackageId != 0) { _player.RewardQuestPackage((uint)reward.PackageId); } if (reward.SkillLineId != 0 && _player.HasSkill((SkillType)reward.SkillLineId)) { _player.UpdateSkillPro((uint)reward.SkillLineId, 1000, reward.SkillPointCount); } if (reward.HonorPointCount != 0) { _player.AddHonorXP(reward.HonorPointCount); } if (reward.Money != 0) { _player.ModifyMoney((long)reward.Money, false); } if (reward.Xp != 0) { _player.GiveXP(reward.Xp, null, 0.0f); } foreach (PlayerChoiceResponseRewardItem item in reward.Items) { List <ItemPosCount> dest = new List <ItemPosCount>(); if (_player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, item.Id, (uint)item.Quantity) == InventoryResult.Ok) { Item newItem = _player.StoreNewItem(dest, item.Id, true, ItemEnchantmentManager.GenerateItemRandomBonusListId(item.Id), null, ItemContext.QuestReward, item.BonusListIDs); _player.SendNewItem(newItem, (uint)item.Quantity, true, false); } } foreach (PlayerChoiceResponseRewardEntry currency in reward.Currency) { _player.ModifyCurrency((CurrencyTypes)currency.Id, currency.Quantity); } foreach (PlayerChoiceResponseRewardEntry faction in reward.Faction) { _player.GetReputationMgr().ModifyReputation(CliDB.FactionStorage.LookupByKey(faction.Id), faction.Quantity); } } }
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)); }
public void LoadCreatureTexts() { uint oldMSTime = Time.GetMSTime(); mTextMap.Clear(); // for reload case //all currently used temp texts are NOT reset PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.SEL_CREATURE_TEXT); SQLResult result = DB.World.Query(stmt); if (result.IsEmpty()) { Log.outInfo(LogFilter.ServerLoading, "Loaded 0 ceature texts. DB table `creature_texts` is empty."); return; } uint textCount = 0; uint creatureCount = 0; do { CreatureTextEntry temp = new(); temp.creatureId = result.Read <uint>(0); temp.groupId = result.Read <byte>(1); temp.id = result.Read <byte>(2); temp.text = result.Read <string>(3); temp.type = (ChatMsg)result.Read <byte>(4); temp.lang = (Language)result.Read <byte>(5); temp.probability = result.Read <float>(6); temp.emote = (Emote)result.Read <uint>(7); temp.duration = result.Read <uint>(8); temp.sound = result.Read <uint>(9); temp.SoundPlayType = (SoundKitPlayType)result.Read <byte>(10); temp.BroadcastTextId = result.Read <uint>(11); temp.TextRange = (CreatureTextRange)result.Read <byte>(12); if (temp.sound != 0) { if (!CliDB.SoundKitStorage.ContainsKey(temp.sound)) { Log.outError(LogFilter.Sql, $"GossipManager: Entry {temp.creatureId}, Group {temp.groupId} in table `creature_texts` has Sound {temp.sound} but sound does not exist."); temp.sound = 0; } } if (temp.SoundPlayType >= SoundKitPlayType.Max) { Log.outError(LogFilter.Sql, $"CreatureTextMgr: Entry {temp.creatureId}, Group {temp.groupId} in table `creature_text` has PlayType {temp.SoundPlayType} but does not exist."); temp.SoundPlayType = SoundKitPlayType.Normal; } if (temp.lang != Language.Universal && !Global.LanguageMgr.IsLanguageExist(temp.lang)) { Log.outError(LogFilter.Sql, $"CreatureTextMgr: Entry {temp.creatureId}, Group {temp.groupId} in table `creature_texts` using Language {temp.lang} but Language does not exist."); temp.lang = Language.Universal; } if (temp.type >= ChatMsg.Max) { Log.outError(LogFilter.Sql, $"CreatureTextMgr: Entry {temp.creatureId}, Group {temp.groupId} in table `creature_texts` has Type {temp.type} but this Chat Type does not exist."); temp.type = ChatMsg.Say; } if (temp.emote != 0) { if (!CliDB.EmotesStorage.ContainsKey((uint)temp.emote)) { Log.outError(LogFilter.Sql, $"CreatureTextMgr: Entry {temp.creatureId}, Group {temp.groupId} in table `creature_texts` has Emote {temp.emote} but emote does not exist."); temp.emote = Emote.OneshotNone; } } if (temp.BroadcastTextId != 0) { if (!CliDB.BroadcastTextStorage.ContainsKey(temp.BroadcastTextId)) { Log.outError(LogFilter.Sql, $"CreatureTextMgr: Entry {temp.creatureId}, Group {temp.groupId}, Id {temp.id} in table `creature_texts` has non-existing or incompatible BroadcastTextId {temp.BroadcastTextId}."); temp.BroadcastTextId = 0; } } if (temp.TextRange > CreatureTextRange.Personal) { Log.outError(LogFilter.Sql, $"CreatureTextMgr: Entry {temp.creatureId}, Group {temp.groupId}, Id {temp.id} in table `creature_text` has incorrect TextRange {temp.TextRange}."); temp.TextRange = CreatureTextRange.Normal; } if (!mTextMap.ContainsKey(temp.creatureId)) { mTextMap[temp.creatureId] = new MultiMap <byte, CreatureTextEntry>(); ++creatureCount; } mTextMap[temp.creatureId].Add(temp.groupId, temp); ++textCount; } while (result.NextRow()); Log.outInfo(LogFilter.ServerLoading, $"Loaded {textCount} creature texts for {creatureCount} creatures in {Time.GetMSTimeDiffToNow(oldMSTime)} ms"); }
void HandleChat(ChatMsg type, Language lang, string msg, string target = "") { Player sender = GetPlayer(); if (lang == Language.Universal && type != ChatMsg.Emote) { Log.outError(LogFilter.Network, "CMSG_MESSAGECHAT: Possible hacking-attempt: {0} tried to send a message in universal language", GetPlayerInfo()); SendNotification(CypherStrings.UnknownLanguage); return; } // prevent talking at unknown language (cheating) LanguageDesc langDesc = ObjectManager.GetLanguageDescByID(lang); if (langDesc == null) { SendNotification(CypherStrings.UnknownLanguage); return; } if (langDesc.skill_id != 0 && !sender.HasSkill((SkillType)langDesc.skill_id)) { // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language) var langAuras = sender.GetAuraEffectsByType(AuraType.ComprehendLanguage); bool foundAura = false; foreach (var eff in langAuras) { if (eff.GetMiscValue() == (int)lang) { foundAura = true; break; } } if (!foundAura) { SendNotification(CypherStrings.NotLearnedLanguage); return; } } // send in universal language if player in .gm on mode (ignore spell effects) if (sender.IsGameMaster()) { lang = Language.Universal; } else { // send in universal language in two side iteration allowed mode if (HasPermission(RBACPermissions.TwoSideInteractionChat)) { lang = Language.Universal; } else { switch (type) { case ChatMsg.Party: case ChatMsg.Raid: case ChatMsg.RaidWarning: // allow two side chat at group channel if two side group allowed if (WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionGroup)) { lang = Language.Universal; } break; case ChatMsg.Guild: case ChatMsg.Officer: // allow two side chat at guild channel if two side guild allowed if (WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionGuild)) { lang = Language.Universal; } break; } } // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used) var ModLangAuras = sender.GetAuraEffectsByType(AuraType.ModLanguage); if (!ModLangAuras.Empty()) { lang = (Language)ModLangAuras.FirstOrDefault().GetMiscValue(); } } if (!sender.CanSpeak()) { string timeStr = Time.secsToTimeString((ulong)(m_muteTime - Time.UnixTime)); SendNotification(CypherStrings.WaitBeforeSpeaking, timeStr); return; } if (sender.HasAura(1852) && type != ChatMsg.Whisper) { SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.GmSilence), sender.GetName()); return; } if (string.IsNullOrEmpty(msg)) { return; } if (new CommandHandler(this).ParseCommand(msg)) { return; } switch (type) { case ChatMsg.Say: // Prevent cheating if (!sender.IsAlive()) { return; } if (sender.getLevel() < WorldConfig.GetIntValue(WorldCfg.ChatSayLevelReq)) { SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.SayReq), WorldConfig.GetIntValue(WorldCfg.ChatSayLevelReq)); return; } sender.Say(msg, lang); break; case ChatMsg.Emote: // Prevent cheating if (!sender.IsAlive()) { return; } if (sender.getLevel() < WorldConfig.GetIntValue(WorldCfg.ChatEmoteLevelReq)) { SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.SayReq), WorldConfig.GetIntValue(WorldCfg.ChatEmoteLevelReq)); return; } sender.TextEmote(msg); break; case ChatMsg.Yell: // Prevent cheating if (!sender.IsAlive()) { return; } if (sender.getLevel() < WorldConfig.GetIntValue(WorldCfg.ChatYellLevelReq)) { SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.SayReq), WorldConfig.GetIntValue(WorldCfg.ChatYellLevelReq)); return; } sender.Yell(msg, lang); break; case ChatMsg.Whisper: // @todo implement cross realm whispers (someday) ExtendedPlayerName extName = ObjectManager.ExtractExtendedPlayerName(target); if (!ObjectManager.NormalizePlayerName(ref extName.Name)) { SendChatPlayerNotfoundNotice(target); break; } Player receiver = Global.ObjAccessor.FindPlayerByName(extName.Name); if (!receiver || (lang != Language.Addon && !receiver.isAcceptWhispers() && receiver.GetSession().HasPermission(RBACPermissions.CanFilterWhispers) && !receiver.IsInWhisperWhiteList(sender.GetGUID()))) { SendChatPlayerNotfoundNotice(target); return; } if (!sender.IsGameMaster() && sender.getLevel() < WorldConfig.GetIntValue(WorldCfg.ChatWhisperLevelReq) && !receiver.IsInWhisperWhiteList(sender.GetGUID())) { SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.WhisperReq), WorldConfig.GetIntValue(WorldCfg.ChatWhisperLevelReq)); return; } if (GetPlayer().GetTeam() != receiver.GetTeam() && !HasPermission(RBACPermissions.TwoSideInteractionChat) && !receiver.IsInWhisperWhiteList(sender.GetGUID())) { SendChatPlayerNotfoundNotice(target); return; } if (GetPlayer().HasAura(1852) && !receiver.IsGameMaster()) { SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.GmSilence), GetPlayer().GetName()); return; } if (receiver.getLevel() < WorldConfig.GetIntValue(WorldCfg.ChatWhisperLevelReq) || (HasPermission(RBACPermissions.CanFilterWhispers) && !sender.isAcceptWhispers() && !sender.IsInWhisperWhiteList(receiver.GetGUID()))) { sender.AddWhisperWhiteList(receiver.GetGUID()); } GetPlayer().Whisper(msg, lang, receiver); break; case ChatMsg.Party: { // if player is in Battleground, he cannot say to Battlegroundmembers by /p Group group = GetPlayer().GetOriginalGroup(); if (!group) { group = GetPlayer().GetGroup(); if (!group || group.isBGGroup()) { return; } } if (group.IsLeader(GetPlayer().GetGUID())) { type = ChatMsg.PartyLeader; } Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, group); ChatPkt data = new ChatPkt(); data.Initialize(type, lang, sender, null, msg); group.BroadcastPacket(data, false, group.GetMemberGroup(GetPlayer().GetGUID())); } break; case ChatMsg.Guild: if (GetPlayer().GetGuildId() != 0) { Guild guild = Global.GuildMgr.GetGuildById(GetPlayer().GetGuildId()); if (guild) { Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, guild); guild.BroadcastToGuild(this, false, msg, lang == Language.Addon ? Language.Addon : Language.Universal); } } break; case ChatMsg.Officer: if (GetPlayer().GetGuildId() != 0) { Guild guild = Global.GuildMgr.GetGuildById(GetPlayer().GetGuildId()); if (guild) { Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, guild); guild.BroadcastToGuild(this, true, msg, lang == Language.Addon ? Language.Addon : Language.Universal); } } break; case ChatMsg.Raid: { Group group = GetPlayer().GetGroup(); if (!group || !group.isRaidGroup() || group.isBGGroup()) { return; } if (group.IsLeader(GetPlayer().GetGUID())) { type = ChatMsg.RaidLeader; } Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, group); ChatPkt data = new ChatPkt(); data.Initialize(type, lang, sender, null, msg); group.BroadcastPacket(data, false); } break; case ChatMsg.RaidWarning: { Group group = GetPlayer().GetGroup(); if (!group || !group.isRaidGroup() || !(group.IsLeader(GetPlayer().GetGUID()) || group.IsAssistant(GetPlayer().GetGUID())) || group.isBGGroup()) { return; } Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, group); ChatPkt data = new ChatPkt(); //in Battleground, raid warning is sent only to players in Battleground - code is ok data.Initialize(ChatMsg.RaidWarning, lang, sender, null, msg); group.BroadcastPacket(data, false); } break; case ChatMsg.Channel: if (!HasPermission(RBACPermissions.SkipCheckChatChannelReq)) { if (GetPlayer().getLevel() < WorldConfig.GetIntValue(WorldCfg.ChatChannelLevelReq)) { SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.ChannelReq), WorldConfig.GetIntValue(WorldCfg.ChatChannelLevelReq)); return; } } Channel chn = ChannelManager.GetChannelForPlayerByNamePart(target, sender); if (chn != null) { Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, chn); chn.Say(GetPlayer().GetGUID(), msg, lang); } break; case ChatMsg.InstanceChat: { Group group = GetPlayer().GetGroup(); if (!group) { return; } if (group.IsLeader(GetPlayer().GetGUID())) { type = ChatMsg.InstanceChatLeader; } Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, group); ChatPkt packet = new ChatPkt(); packet.Initialize(type, lang, sender, null, msg); group.BroadcastPacket(packet, false); break; } default: Log.outError(LogFilter.ChatSystem, "CHAT: unknown message type {0}, lang: {1}", type, lang); break; } }
void HandleOpenItem(OpenItem packet) { Player player = GetPlayer(); // ignore for remote control state if (player.m_unitMovedByMe != player) { return; } Item item = player.GetItemByPos(packet.Slot, packet.PackSlot); if (!item) { player.SendEquipError(InventoryResult.ItemNotFound); return; } ItemTemplate proto = item.GetTemplate(); if (proto == null) { player.SendEquipError(InventoryResult.ItemNotFound, item); return; } // Verify that the bag is an actual bag or wrapped item that can be used "normally" if (!proto.GetFlags().HasAnyFlag(ItemFlags.HasLoot) && !item.HasFlag(ItemFields.Flags, ItemFieldFlags.Wrapped)) { player.SendEquipError(InventoryResult.ClientLockedOut, item); Log.outError(LogFilter.Network, "Possible hacking attempt: Player {0} [guid: {1}] tried to open item [guid: {2}, entry: {3}] which is not openable!", player.GetName(), player.GetGUID().ToString(), item.GetGUID().ToString(), proto.GetId()); return; } // locked item uint lockId = proto.GetLockID(); if (lockId != 0) { LockRecord lockInfo = CliDB.LockStorage.LookupByKey(lockId); if (lockInfo == null) { player.SendEquipError(InventoryResult.ItemLocked, item); Log.outError(LogFilter.Network, "WORLD:OpenItem: item [guid = {0}] has an unknown lockId: {1}!", item.GetGUID().ToString(), lockId); return; } // was not unlocked yet if (item.IsLocked()) { player.SendEquipError(InventoryResult.ItemLocked, item); return; } } if (item.HasFlag(ItemFields.Flags, ItemFieldFlags.Wrapped))// wrapped? { PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHARACTER_GIFT_BY_ITEM); stmt.AddValue(0, item.GetGUID().GetCounter()); SQLResult result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { uint entry = result.Read <uint>(0); uint flags = result.Read <uint>(1); item.SetUInt64Value(ItemFields.GiftCreator, 0); item.SetEntry(entry); item.SetUInt32Value(ItemFields.Flags, flags); item.SetState(ItemUpdateState.Changed, player); } else { Log.outError(LogFilter.Network, "Wrapped item {0} don't have record in character_gifts table and will deleted", item.GetGUID().ToString()); player.DestroyItem(item.GetBagSlot(), item.GetSlot(), true); return; } stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_GIFT); stmt.AddValue(0, item.GetGUID().GetCounter()); DB.Characters.Execute(stmt); } else { player.SendLoot(item.GetGUID(), LootType.Corpse); } }
void HandleChatAddon(ChatMsg type, string prefix, string text, string target = "") { Player sender = GetPlayer(); if (string.IsNullOrEmpty(prefix) || prefix.Length > 16) { return; } // Disabled addon channel? if (!WorldConfig.GetBoolValue(WorldCfg.AddonChannel)) { return; } switch (type) { case ChatMsg.Guild: case ChatMsg.Officer: if (sender.GetGuildId() != 0) { Guild guild = Global.GuildMgr.GetGuildById(sender.GetGuildId()); if (guild) { guild.BroadcastAddonToGuild(this, type == ChatMsg.Officer, text, prefix); } } break; case ChatMsg.Whisper: // @todo implement cross realm whispers (someday) ExtendedPlayerName extName = ObjectManager.ExtractExtendedPlayerName(target); if (!ObjectManager.NormalizePlayerName(ref extName.Name)) { break; } Player receiver = Global.ObjAccessor.FindPlayerByName(extName.Name); if (!receiver) { break; } sender.WhisperAddon(text, prefix, receiver); break; // Messages sent to "RAID" while in a party will get delivered to "PARTY" case ChatMsg.Party: case ChatMsg.Raid: case ChatMsg.InstanceChat: { Group group = null; int subGroup = -1; if (type != ChatMsg.InstanceChat) { group = sender.GetOriginalGroup(); } if (!group) { group = sender.GetGroup(); if (!group) { break; } if (type == ChatMsg.Party) { subGroup = sender.GetSubGroup(); } } ChatPkt data = new ChatPkt(); data.Initialize(type, Language.Addon, sender, null, text, 0, "", LocaleConstant.enUS, prefix); group.BroadcastAddonMessagePacket(data, prefix, true, subGroup, sender.GetGUID()); break; } case ChatMsg.Channel: Channel chn = ChannelManager.GetChannelForPlayerByNamePart(target, sender); if (chn != null) { chn.AddonSay(sender.GetGUID(), prefix, text); } break; default: Log.outError(LogFilter.Server, "HandleAddonMessagechat: unknown addon message type {0}", type); break; } }
public void LoadDisables() { uint oldMSTime = Time.GetMSTime(); // reload case m_DisableMap.Clear(); SQLResult result = DB.World.Query("SELECT sourceType, entry, flags, params_0, params_1 FROM disables"); if (result.IsEmpty()) { Log.outError(LogFilter.ServerLoading, "Loaded 0 disables. DB table `disables` is empty!"); return; } uint total_count = 0; do { DisableType type = (DisableType)result.Read <uint>(0); if (type >= DisableType.Max) { Log.outError(LogFilter.Sql, "Invalid type {0} specified in `disables` table, skipped.", type); continue; } uint entry = result.Read <uint>(1); byte flags = result.Read <byte>(2); string params_0 = result.Read <string>(3); string params_1 = result.Read <string>(4); DisableData data = new DisableData(); data.flags = flags; switch (type) { case DisableType.Spell: if (!(Global.SpellMgr.HasSpellInfo(entry) || flags.HasAnyFlag <byte>(DisableFlags.SpellDeprecatedSpell))) { Log.outError(LogFilter.Sql, "Spell entry {0} from `disables` doesn't exist in dbc, skipped.", entry); continue; } if (flags == 0 || flags > DisableFlags.MaxSpell) { Log.outError(LogFilter.Sql, "Disable flags for spell {0} are invalid, skipped.", entry); continue; } if (flags.HasAnyFlag(DisableFlags.SpellMap)) { var array = new StringArray(params_0, ','); for (byte i = 0; i < array.Length;) { if (uint.TryParse(array[i++], out uint id)) { data.param0.Add(id); } } } if (flags.HasAnyFlag(DisableFlags.SpellArea)) { var array = new StringArray(params_1, ','); for (byte i = 0; i < array.Length;) { if (uint.TryParse(array[i++], out uint id)) { data.param1.Add(id); } } } break; // checked later case DisableType.Quest: break; case DisableType.Map: case DisableType.LFGMap: { MapRecord mapEntry = CliDB.MapStorage.LookupByKey(entry); if (mapEntry == null) { Log.outError(LogFilter.Sql, "Map entry {0} from `disables` doesn't exist in dbc, skipped.", entry); continue; } bool isFlagInvalid = false; switch (mapEntry.InstanceType) { case MapTypes.Common: if (flags != 0) { isFlagInvalid = true; } break; case MapTypes.Instance: case MapTypes.Raid: if (flags.HasAnyFlag(DisableFlags.DungeonStatusHeroic) && Global.DB2Mgr.GetMapDifficultyData(entry, Difficulty.Heroic) == null) { flags -= DisableFlags.DungeonStatusHeroic; } if (flags.HasAnyFlag(DisableFlags.DungeonStatusHeroic10Man) && Global.DB2Mgr.GetMapDifficultyData(entry, Difficulty.Raid10HC) == null) { flags -= DisableFlags.DungeonStatusHeroic10Man; } if (flags.HasAnyFlag(DisableFlags.DungeonStatusHeroic25Man) && Global.DB2Mgr.GetMapDifficultyData(entry, Difficulty.Raid25HC) == null) { flags -= DisableFlags.DungeonStatusHeroic25Man; } if (flags == 0) { isFlagInvalid = true; } break; case MapTypes.Battleground: case MapTypes.Arena: Log.outError(LogFilter.Sql, "Battlegroundmap {0} specified to be disabled in map case, skipped.", entry); continue; } if (isFlagInvalid) { Log.outError(LogFilter.Sql, "Disable flags for map {0} are invalid, skipped.", entry); continue; } break; } case DisableType.Battleground: if (!CliDB.BattlemasterListStorage.ContainsKey(entry)) { Log.outError(LogFilter.Sql, "Battlegroundentry {0} from `disables` doesn't exist in dbc, skipped.", entry); continue; } if (flags != 0) { Log.outError(LogFilter.Sql, "Disable flags specified for Battleground{0}, useless data.", entry); } break; case DisableType.OutdoorPVP: if (entry > (int)OutdoorPvPTypes.Max) { Log.outError(LogFilter.Sql, "OutdoorPvPTypes value {0} from `disables` is invalid, skipped.", entry); continue; } if (flags != 0) { Log.outError(LogFilter.Sql, "Disable flags specified for outdoor PvP {0}, useless data.", entry); } break; case DisableType.Criteria: if (Global.CriteriaMgr.GetCriteria(entry) == null) { Log.outError(LogFilter.Sql, "Criteria entry {0} from `disables` doesn't exist in dbc, skipped.", entry); continue; } if (flags != 0) { Log.outError(LogFilter.Sql, "Disable flags specified for Criteria {0}, useless data.", entry); } break; case DisableType.VMAP: { MapRecord mapEntry = CliDB.MapStorage.LookupByKey(entry); if (mapEntry == null) { Log.outError(LogFilter.Sql, "Map entry {0} from `disables` doesn't exist in dbc, skipped.", entry); continue; } switch (mapEntry.InstanceType) { case MapTypes.Common: if (flags.HasAnyFlag(DisableFlags.VmapAreaFlag)) { Log.outInfo(LogFilter.Server, "Areaflag disabled for world map {0}.", entry); } if (flags.HasAnyFlag(DisableFlags.VmapLiquidStatus)) { Log.outInfo(LogFilter.Server, "Liquid status disabled for world map {0}.", entry); } break; case MapTypes.Instance: case MapTypes.Raid: if (flags.HasAnyFlag(DisableFlags.VmapHeight)) { Log.outInfo(LogFilter.Server, "Height disabled for instance map {0}.", entry); } if (flags.HasAnyFlag(DisableFlags.VmapLOS)) { Log.outInfo(LogFilter.Server, "LoS disabled for instance map {0}.", entry); } break; case MapTypes.Battleground: if (flags.HasAnyFlag(DisableFlags.VmapHeight)) { Log.outInfo(LogFilter.Server, "Height disabled for Battlegroundmap {0}.", entry); } if (flags.HasAnyFlag(DisableFlags.VmapLOS)) { Log.outInfo(LogFilter.Server, "LoS disabled for Battlegroundmap {0}.", entry); } break; case MapTypes.Arena: if (flags.HasAnyFlag(DisableFlags.VmapHeight)) { Log.outInfo(LogFilter.Server, "Height disabled for arena map {0}.", entry); } if (flags.HasAnyFlag(DisableFlags.VmapLOS)) { Log.outInfo(LogFilter.Server, "LoS disabled for arena map {0}.", entry); } break; default: break; } break; } case DisableType.MMAP: { MapRecord mapEntry = CliDB.MapStorage.LookupByKey(entry); if (mapEntry == null) { Log.outError(LogFilter.Sql, "Map entry {0} from `disables` doesn't exist in dbc, skipped.", entry); continue; } switch (mapEntry.InstanceType) { case MapTypes.Common: Log.outInfo(LogFilter.Server, "Pathfinding disabled for world map {0}.", entry); break; case MapTypes.Instance: case MapTypes.Raid: Log.outInfo(LogFilter.Server, "Pathfinding disabled for instance map {0}.", entry); break; case MapTypes.Battleground: Log.outInfo(LogFilter.Server, "Pathfinding disabled for Battlegroundmap {0}.", entry); break; case MapTypes.Arena: Log.outInfo(LogFilter.Server, "Pathfinding disabled for arena map {0}.", entry); break; default: break; } break; } default: break; } if (!m_DisableMap.ContainsKey(type)) { m_DisableMap[type] = new Dictionary <uint, DisableData>(); } m_DisableMap[type].Add(entry, data); ++total_count; }while (result.NextRow()); Log.outInfo(LogFilter.ServerLoading, "Loaded {0} disables in {1} ms", total_count, Time.GetMSTimeDiffToNow(oldMSTime)); }
void HandlePetAction(PetAction packet) { ObjectGuid guid1 = packet.PetGUID; //pet guid ObjectGuid guid2 = packet.TargetGUID; //tag guid uint spellid = UnitActionBarEntry.UNIT_ACTION_BUTTON_ACTION(packet.Action); ActiveStates flag = (ActiveStates)UnitActionBarEntry.UNIT_ACTION_BUTTON_TYPE(packet.Action); //delete = 0x07 CastSpell = C1 // used also for charmed creature Unit pet = Global.ObjAccessor.GetUnit(GetPlayer(), guid1); if (!pet) { Log.outError(LogFilter.Network, "HandlePetAction: {0} doesn't exist for {1}", guid1.ToString(), GetPlayer().GetGUID().ToString()); return; } if (pet != GetPlayer().GetFirstControlled()) { Log.outError(LogFilter.Network, "HandlePetAction: {0} does not belong to {1}", guid1.ToString(), GetPlayer().GetGUID().ToString()); return; } if (!pet.IsAlive()) { SpellInfo spell = (flag == ActiveStates.Enabled || flag == ActiveStates.Passive) ? Global.SpellMgr.GetSpellInfo(spellid, pet.GetMap().GetDifficultyID()) : null; if (spell == null) { return; } if (!spell.HasAttribute(SpellAttr0.CastableWhileDead)) { return; } } // @todo allow control charmed player? if (pet.IsTypeId(TypeId.Player) && !(flag == ActiveStates.Command && spellid == (uint)CommandStates.Attack)) { return; } if (GetPlayer().m_Controlled.Count == 1) { HandlePetActionHelper(pet, guid1, spellid, flag, guid2, packet.ActionPosition.X, packet.ActionPosition.Y, packet.ActionPosition.Z); } else { //If a pet is dismissed, m_Controlled will change List <Unit> controlled = new(); foreach (var unit in GetPlayer().m_Controlled) { if (unit.GetEntry() == pet.GetEntry() && unit.IsAlive()) { controlled.Add(unit); } } foreach (var unit in controlled) { HandlePetActionHelper(unit, guid1, spellid, flag, guid2, packet.ActionPosition.X, packet.ActionPosition.Y, packet.ActionPosition.Z); } } }