From e5b6703dd08488125b53aafbe9edbd2557d1a4cf Mon Sep 17 00:00:00 2001 From: hondacrx Date: Fri, 24 Jul 2020 11:46:44 -0400 Subject: [PATCH] Make some adjustments to .summon and .group summon behavior to make them more permissive: - Now only requires the either target's group leader or target itself to be on your map - Now summons all applicable group members even if one member fails checks - No longer has some truly weird edge case instance unbind code that could cause exploit behavior (Really, I have no idea why this existed, because it certainly didn't do what it might've been meant to do.) Port From (https://github.com/TrinityCore/TrinityCore/commit/f543e570d65fec3546e982d27d458a759922602d) --- Source/Framework/Constants/Language.cs | 3 +- Source/Game/Chat/Commands/GroupCommands.cs | 29 +++++++----- Source/Game/Chat/Commands/MiscCommands.cs | 46 +++++++++---------- ...020_07_16_03_world_2017_06_12_00_world.sql | 5 ++ 4 files changed, 45 insertions(+), 38 deletions(-) create mode 100644 sql/updates/world/master/2020_07_16_03_world_2017_06_12_00_world.sql diff --git a/Source/Framework/Constants/Language.cs b/Source/Framework/Constants/Language.cs index 0fd83aed7..05110b1b5 100644 --- a/Source/Framework/Constants/Language.cs +++ b/Source/Framework/Constants/Language.cs @@ -249,7 +249,8 @@ namespace Framework.Constants // 185 not used TransportPosition = 186, - // Room For More Level 1 187-199 Not Used + PartialGroupSummon = 187, + // Room For More Level 1 188-199 not used // Level 2 Chat NoSelection = 200, diff --git a/Source/Game/Chat/Commands/GroupCommands.cs b/Source/Game/Chat/Commands/GroupCommands.cs index 0c2c0e6c8..dea06af0d 100644 --- a/Source/Game/Chat/Commands/GroupCommands.cs +++ b/Source/Game/Chat/Commands/GroupCommands.cs @@ -57,15 +57,19 @@ namespace Game.Chat Group gmGroup = gmPlayer.GetGroup(); Map gmMap = gmPlayer.GetMap(); bool toInstance = gmMap.Instanceable(); + bool onlyLocalSummon = false; - // we are in instance, and can summon only player in our group with us as lead - if (toInstance && ( - !gmGroup || group.GetLeaderGUID() != gmPlayer.GetGUID() || - gmGroup.GetLeaderGUID() != gmPlayer.GetGUID())) - // the last check is a bit excessive, but let it be, just in case + // make sure people end up on our instance of the map, disallow far summon if intended destination is different from actual destination + // note: we could probably relax this further by checking permanent saves and the like, but eh + // :close enough: + if (toInstance) { - handler.SendSysMessage(CypherStrings.CannotSummonToInst); - return false; + Player groupLeader = Global.ObjAccessor.GetPlayer(gmMap, group.GetLeaderGUID()); + if (!groupLeader || (groupLeader.GetMapId() != gmMap.GetId()) || (groupLeader.GetInstanceId() != gmMap.GetInstanceId())) + { + handler.SendSysMessage(CypherStrings.PartialGroupSummon); + onlyLocalSummon = true; + } } for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) @@ -77,25 +81,26 @@ namespace Game.Chat // check online security if (handler.HasLowerSecurity(player, ObjectGuid.Empty)) - return false; + continue; string plNameLink = handler.GetNameLink(player); if (player.IsBeingTeleported()) { handler.SendSysMessage(CypherStrings.IsTeleported, plNameLink); - return false; + continue; } if (toInstance) { Map playerMap = player.GetMap(); - if (playerMap.Instanceable() && playerMap.GetInstanceId() != gmMap.GetInstanceId()) + if ((onlyLocalSummon || (playerMap.Instanceable() && playerMap.GetId() == gmMap.GetId())) && // either no far summon allowed or we're in the same map as player (no map switch) + ((playerMap.GetId() != gmMap.GetId()) || (playerMap.GetInstanceId() != gmMap.GetInstanceId()))) // so we need to be in the same map and instance of the map, otherwise skip { // cannot summon from instance to instance - handler.SendSysMessage(CypherStrings.CannotSummonToInst, plNameLink); - return false; + handler.SendSysMessage(CypherStrings.CannotSummonInstInst, plNameLink); + continue; } } diff --git a/Source/Game/Chat/Commands/MiscCommands.cs b/Source/Game/Chat/Commands/MiscCommands.cs index e1e5c2a07..e47e5a06e 100644 --- a/Source/Game/Chat/Commands/MiscCommands.cs +++ b/Source/Game/Chat/Commands/MiscCommands.cs @@ -656,8 +656,7 @@ namespace Game.Chat return false; } - Map map = handler.GetSession().GetPlayer().GetMap(); - + Map map = _player.GetMap(); if (map.IsBattlegroundOrArena()) { // only allow if gm mode is on @@ -667,31 +666,34 @@ namespace Game.Chat return false; } // if both players are in different bgs - else if (target.GetBattlegroundId() != 0 && handler.GetSession().GetPlayer().GetBattlegroundId() != target.GetBattlegroundId()) + else if (target.GetBattlegroundId() != 0 && _player.GetBattlegroundId() != target.GetBattlegroundId()) target.LeaveBattleground(false); // Note: should be changed so target gets no Deserter debuff // all's well, set bg id // when porting out from the bg, it will be reset to 0 - target.SetBattlegroundId(handler.GetSession().GetPlayer().GetBattlegroundId(), handler.GetSession().GetPlayer().GetBattlegroundTypeId()); + target.SetBattlegroundId(_player.GetBattlegroundId(), _player.GetBattlegroundTypeId()); // remember current position as entry point for return at bg end teleportation if (!target.GetMap().IsBattlegroundOrArena()) target.SetBattlegroundEntryPoint(); } - else if (map.IsDungeon()) + else if (map.Instanceable()) { - Map destMap = target.GetMap(); + Group targetGroup = target.GetGroup(); + Map targetMap = target.GetMap(); + Player targetGroupLeader = Global.ObjAccessor.GetPlayer(map, targetGroup.GetLeaderGUID()); - if (destMap.Instanceable() && destMap.GetInstanceId() != map.GetInstanceId()) - target.UnbindInstance(map.GetInstanceId(), target.GetDungeonDifficultyID(), true); + // check if far teleport is allowed + if (!targetGroupLeader || (targetGroupLeader.GetMapId() != map.GetId()) || (targetGroupLeader.GetInstanceId() != map.GetInstanceId())) + if ((targetMap.GetId() != map.GetId()) || (targetMap.GetInstanceId() != map.GetInstanceId())) + { + handler.SendSysMessage(CypherStrings.CannotSummonToInst); + return false; + } - // we are in an instance, and can only summon players in our group with us as leader - if (handler.GetSession().GetPlayer().GetGroup() || !target.GetGroup() || - (target.GetGroup().GetLeaderGUID() != handler.GetSession().GetPlayer().GetGUID()) || - (handler.GetSession().GetPlayer().GetGroup().GetLeaderGUID() != handler.GetSession().GetPlayer().GetGUID())) - // the last check is a bit excessive, but let it be, just in case + // check if we're already in a different instance of the same map + if ((targetMap.GetId() == map.GetId()) && (targetMap.GetInstanceId() != map.GetInstanceId())) { - handler.SendSysMessage(CypherStrings.CannotSummonToInst, nameLink); - + handler.SendSysMessage(CypherStrings.CannotSummonInstInst, nameLink); return false; } } @@ -712,9 +714,9 @@ namespace Game.Chat // before GM float x, y, z; - handler.GetSession().GetPlayer().GetClosePoint(out x, out y, out z, target.GetCombatReach()); - target.TeleportTo(handler.GetSession().GetPlayer().GetMapId(), x, y, z, target.GetOrientation()); - PhasingHandler.InheritPhaseShift(target, handler.GetSession().GetPlayer()); + _player.GetClosePoint(out x, out y, out z, target.GetCombatReach()); + target.TeleportTo(_player.GetMapId(), x, y, z, target.GetOrientation()); + PhasingHandler.InheritPhaseShift(target, _player); target.UpdateObjectVisibility(); } else @@ -728,13 +730,7 @@ namespace Game.Chat handler.SendSysMessage(CypherStrings.Summoning, nameLink, handler.GetCypherString(CypherStrings.Offline)); // in point where GM stay - Player.SavePositionInDB(new WorldLocation(handler.GetSession().GetPlayer().GetMapId(), - handler.GetSession().GetPlayer().GetPositionX(), - handler.GetSession().GetPlayer().GetPositionY(), - handler.GetSession().GetPlayer().GetPositionZ(), - handler.GetSession().GetPlayer().GetOrientation()), - handler.GetSession().GetPlayer().GetZoneId(), - targetGuid); + Player.SavePositionInDB(new WorldLocation(_player.GetMapId(), _player.GetPositionX(), _player.GetPositionY(), _player.GetPositionZ(), _player.GetOrientation()), _player.GetZoneId(), targetGuid); } return true; diff --git a/sql/updates/world/master/2020_07_16_03_world_2017_06_12_00_world.sql b/sql/updates/world/master/2020_07_16_03_world_2017_06_12_00_world.sql new file mode 100644 index 000000000..56d15d977 --- /dev/null +++ b/sql/updates/world/master/2020_07_16_03_world_2017_06_12_00_world.sql @@ -0,0 +1,5 @@ +-- +UPDATE `trinity_string` SET `content_default`="You can only summon a player to your instance if either that player or his group leader is in your instance, too." WHERE `entry`=103; +DELETE FROM `trinity_string` WHERE `entry`=187; +INSERT INTO `trinity_string` (`entry`,`content_default`) VALUES + (187, "The group's leader is not in your instance - summoning only members that are already in your map.");