diff options
Diffstat (limited to 'src/server')
23 files changed, 425 insertions, 296 deletions
diff --git a/src/server/apps/worldserver/Main.cpp b/src/server/apps/worldserver/Main.cpp index d1c10131b1..511c17e367 100644 --- a/src/server/apps/worldserver/Main.cpp +++ b/src/server/apps/worldserver/Main.cpp @@ -48,6 +48,7 @@ #include "SecretMgr.h" #include "SharedDefines.h" #include "SteadyTimer.h" +#include "Systemd.h" #include "World.h" #include "WorldSessionMgr.h" #include "WorldSocket.h" @@ -406,7 +407,8 @@ int main(int argc, char** argv) sScriptMgr->OnShutdown(); // set server offline - LoginDatabase.DirectExecute("UPDATE realmlist SET flag = flag | {} WHERE id = '{}'", REALM_FLAG_OFFLINE, realm.Id.Realm); + if (!sConfigMgr->GetOption<bool>("Network.UseSocketActivation", false)) + LoginDatabase.DirectExecute("UPDATE realmlist SET flag = flag | {} WHERE id = '{}'", REALM_FLAG_OFFLINE, realm.Id.Realm); LOG_INFO("server.worldserver", "Halting process..."); diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 07945f07f3..089c1911a5 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -398,6 +398,20 @@ Network.TcpNodelay = 1 Network.EnableProxyProtocol = 0 # +# Network.UseSocketActivation +# Description: Enable systemd socket activation support for the worldserver. +# When enabled and the process is started by systemd socket activation, +# the server will use the socket passed by systemd instead of +# creating and binding its own listening socket. Disabled by default. +# +# When enabled the realm is not automatically set as offline on shutdown. +# +# Example: 1 - (Enabled) +# Default: 0 - (Disabled) + +Network.UseSocketActivation = 0 + +# ################################################################################################### ################################################################################################### diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index f888403491..3c952a42d9 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -858,7 +858,7 @@ void SmartAI::AttackStart(Unit* who) return; } - if (who && me->Attack(who, me->IsWithinMeleeRange(who))) + if (who && me->Attack(who, me->IsWithinMeleeRange(who) || _currentRangeMode)) { if (!me->HasUnitState(UNIT_STATE_NO_COMBAT_MOVEMENT)) { @@ -870,7 +870,7 @@ void SmartAI::AttackStart(Unit* who) me->GetMotionMaster()->Clear(false); } - me->GetMotionMaster()->MoveChase(who); + me->GetMotionMaster()->MoveChase(who, _attackDistance); } } } @@ -941,6 +941,35 @@ void SmartAI::PassengerBoarded(Unit* who, int8 seatId, bool apply) void SmartAI::InitializeAI() { GetScript()->OnInitialize(me); + + for (SmartScriptHolder const& event : GetScript()->GetEvents()) + { + if (event.GetActionType() != SMART_ACTION_CAST) + continue; + + if (!(event.action.cast.castFlags & SMARTCAST_MAIN_SPELL)) + continue; + + SetMainSpell(event.action.cast.spell); + break; + } + + // Fallback: use first SMARTCAST_COMBAT_MOVE if no MAIN_SPELL found + if (!_currentRangeMode) + { + for (SmartScriptHolder const& event : GetScript()->GetEvents()) + { + if (event.GetActionType() != SMART_ACTION_CAST) + continue; + + if (!(event.action.cast.castFlags & SMARTCAST_COMBAT_MOVE)) + continue; + + SetMainSpell(event.action.cast.spell); + break; + } + } + if (!me->isDead()) { mJustReset = true; @@ -1083,6 +1112,20 @@ void SmartAI::SetCurrentRangeMode(bool on, float range) me->GetMotionMaster()->MoveChase(victim, _attackDistance); } +void SmartAI::SetMainSpell(uint32 spellId) +{ + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); + if (!spellInfo) + return; + + float maxRange = spellInfo->GetMaxRange(false); + if (maxRange <= NOMINAL_MELEE_RANGE) + return; + + _attackDistance = std::max(maxRange - NOMINAL_MELEE_RANGE, 0.0f); + _currentRangeMode = true; +} + void SmartAI::DistanceYourself(float range) { Unit* victim = me->GetVictim(); diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index d6b957cc00..0876336458 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -67,6 +67,7 @@ public: void SetAutoAttack(bool on) { mCanAutoAttack = on; } void SetCombatMovement(bool on, bool stopOrStartMovement); void SetCurrentRangeMode(bool on, float range = 0.f); + void SetMainSpell(uint32 spellId); void DistanceYourself(float range); void SetFollow(Unit* target, float dist = 0.0f, float angle = 0.0f, uint32 credit = 0, uint32 end = 0, uint32 creditType = 0, bool aliveState = true); void StopFollow(bool complete); diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index e7a5c4fd84..2f66b4ac11 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -707,7 +707,6 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u continue; } - // Let us not try to cast spell if we know it is going to fail anyway. Stick to chasing and continue. if (distanceToTarget > spellMaxRange && isWithinLOSInMap) { failedSpellCast = true; @@ -745,12 +744,9 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (e.action.cast.castFlags & SMARTCAST_COMBAT_MOVE) { - // If cast flag SMARTCAST_COMBAT_MOVE is set combat movement will not be allowed unless target is outside spell range, out of mana, or LOS. - if (result == SPELL_FAILED_OUT_OF_RANGE || result == SPELL_CAST_OK) - // if we are just out of range, we only chase until we are back in spell range. + if (result == SPELL_FAILED_OUT_OF_RANGE) CAST_AI(SmartAI, me->AI())->SetCurrentRangeMode(true, std::max(spellMaxRange - NOMINAL_MELEE_RANGE, 0.0f)); - else // move into melee on any other fail - // if spell fail for any other reason, we chase to melee range, or stay where we are if spellcast was successful. + else if (result != SPELL_CAST_OK) CAST_AI(SmartAI, me->AI())->SetCurrentRangeMode(false, 0.f); } diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index e0f32438c8..250fdd775a 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -207,6 +207,8 @@ public: void AddCreatureSummon(ObjectGuid const& guid); void RemoveCreatureSummon(ObjectGuid const& guid); + SmartAIEventList const& GetEvents() const { return mEvents; } + private: void IncPhase(uint32 p); void DecPhase(uint32 p); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 5e8e5e9e0c..8dd177dfa6 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1932,16 +1932,17 @@ enum SmartEventFlags enum SmartCastFlags { - SMARTCAST_INTERRUPT_PREVIOUS = 0x001, // Interrupt any spell casting - SMARTCAST_TRIGGERED = 0x002, // Triggered (this makes spell cost zero mana and have no cast time) - //CAST_FORCE_CAST = 0x004, // Forces cast even if creature is out of mana or out of range - //CAST_NO_MELEE_IF_OOM = 0x008, // Prevents creature from entering melee if out of mana or out of range - //CAST_FORCE_TARGET_SELF = 0x010, // Forces the target to cast this spell on itself - SMARTCAST_AURA_NOT_PRESENT = 0x020, // Only casts the spell if the target does not have an aura from the spell - SMARTCAST_COMBAT_MOVE = 0x040, // Prevents combat movement if cast successful. Allows movement on range, OOM, LOS - SMARTCAST_THREATLIST_NOT_SINGLE = 0x080, // Only cast if the source's threatlist is higher than one. This includes pets (see Skeram's True Fulfillment) - SMARTCAST_TARGET_POWER_MANA = 0x100, // Only cast if the target has power type mana (e.g. Mana Drain) - SMARTCAST_ENABLE_COMBAT_MOVE_ON_LOS = 0x200, + SMARTCAST_INTERRUPT_PREVIOUS = 0x001, // Interrupt any spell casting + SMARTCAST_TRIGGERED = 0x002, // Triggered (this makes spell cost zero mana and have no cast time) + //CAST_FORCE_CAST = 0x004, // Forces cast even if creature is out of mana or out of range + //CAST_NO_MELEE_IF_OOM = 0x008, // Prevents creature from entering melee if out of mana or out of range + //CAST_FORCE_TARGET_SELF = 0x010, // Forces the target to cast this spell on itself + SMARTCAST_AURA_NOT_PRESENT = 0x020, // Only casts the spell if the target does not have an aura from the spell + SMARTCAST_COMBAT_MOVE = 0x040, // Prevents combat movement if cast successful. Allows movement on range, OOM, LOS + SMARTCAST_THREATLIST_NOT_SINGLE = 0x080, // Only cast if the source's threatlist is higher than one. This includes pets (see Skeram's True Fulfillment) + SMARTCAST_TARGET_POWER_MANA = 0x100, // Only cast if the target has power type mana (e.g. Mana Drain) + SMARTCAST_ENABLE_COMBAT_MOVE_ON_LOS = 0x200, // Allows combat movement when not in line of sight + SMARTCAST_MAIN_SPELL = 0x400, // Sets this spell's max range as the creature's chase distance on spawn }; enum SmartFollowType diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 8891c8788e..5bcd49fcf3 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7647,7 +7647,7 @@ void Player::_ApplyAllItemMods() if (!proto) continue; - ApplyItemDependentAuras(m_items[i], false); + ApplyItemDependentAuras(m_items[i], true); _ApplyItemBonuses(proto, i, true); WeaponAttackType const attackType = Player::GetAttackBySlot(i); diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index 1d3b5788b3..9a4427ce49 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -701,7 +701,7 @@ void Player::UpdateRating(CombatRating cr) void Player::UpdateAllRatings() { - for (uint cr = 0; cr < MAX_COMBAT_RATING; ++cr) + for (uint8 cr = 0; cr < MAX_COMBAT_RATING; ++cr) UpdateRating(CombatRating(cr)); } diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 4e2fd4532a..24c025ac6d 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -157,7 +157,7 @@ bool Player::UpdateStats(Stats stat) mask |= (*i)->GetMiscValue(); if (mask) { - for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating) + for (uint8 rating = 0; rating < MAX_COMBAT_RATING; ++rating) if (mask & (1 << rating)) ApplyRatingMod(CombatRating(rating), 0, true); } @@ -272,7 +272,7 @@ void Player::UpdateArmor() float value = GetFlatModifierValue(unitMod, BASE_VALUE); // base armor (from items) value *= GetPctModifierValue(unitMod, BASE_PCT); // armor percent from items - value += GetStat(STAT_AGILITY) * 2.0f; // armor bonus from stats + value += GetStat(STAT_AGILITY) * 2.0f; // armor bonus from stats value += GetFlatModifierValue(unitMod, TOTAL_VALUE); //add dynamic flat mods diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 817bc25b77..623886eb78 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -628,7 +628,7 @@ void Unit::UpdateSplinePosition() //if (HasUnitState(UNIT_STATE_CANNOT_TURN)) // loc.orientation = GetOrientation(); - if (IsPlayer()) + if (IsPlayer() || IsPet()) UpdatePosition(loc.x, loc.y, loc.z, loc.orientation); else ToCreature()->SetPosition(loc.x, loc.y, loc.z, loc.orientation); @@ -13465,7 +13465,12 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT if (mechanicMask) { - TakenTotalMod *= GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT, mechanicMask); + TakenTotalMod *= GetTotalAuraMultiplier(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT, [mechanicMask](AuraEffect const* aurEff) -> bool + { + if (mechanicMask & uint32(1 << (aurEff->GetMiscValue()))) + return true; + return false; + }); } } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 8370ebae57..934bb1c70c 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -219,7 +219,7 @@ enum WeaponAttackType : uint8 MAX_ATTACK }; -enum CombatRating +enum CombatRating : uint8 { CR_WEAPON_SKILL = 0, CR_DEFENSE_SKILL = 1, diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index a878194589..fb40ce36ac 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -299,6 +299,8 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recvData) plMover->UpdatePosition(dest, true); + plMover->SetFallInformation(GameTime::GetGameTime().count(), dest.GetPositionZ()); + // xinef: teleport pets if they are not unsummoned if (Pet* pet = plMover->GetPet()) { diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index dcef617a65..7ffb4065f8 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -726,9 +726,12 @@ void AuraEffect::ChangeAmount(int32 newAmount, bool mark, bool onStackOrReapply) std::list<AuraApplication*> effectApplications; GetApplicationList(effectApplications); - for (std::list<AuraApplication*>::const_iterator apptItr = effectApplications.begin(); apptItr != effectApplications.end(); ++apptItr) - if ((*apptItr)->HasEffect(GetEffIndex())) - HandleEffect(*apptItr, handleMask, false); + for (AuraApplication* aurApp : effectApplications) + if (aurApp->HasEffect(GetEffIndex())) + { + aurApp->GetTarget()->_RegisterAuraEffect(this, false); + HandleEffect(aurApp, handleMask, false); + } if (handleMask & AURA_EFFECT_HANDLE_CHANGE_AMOUNT) { @@ -739,9 +742,15 @@ void AuraEffect::ChangeAmount(int32 newAmount, bool mark, bool onStackOrReapply) CalculateSpellMod(); } - for (std::list<AuraApplication*>::const_iterator apptItr = effectApplications.begin(); apptItr != effectApplications.end(); ++apptItr) - if ((*apptItr)->HasEffect(GetEffIndex())) - HandleEffect(*apptItr, handleMask, true); + for (AuraApplication* aurApp : effectApplications) + if (aurApp->HasEffect(GetEffIndex())) + { + if (aurApp->GetRemoveMode() != AURA_REMOVE_NONE) + continue; + + aurApp->GetTarget()->_RegisterAuraEffect(this, true); + HandleEffect(aurApp, handleMask, true); + } } void AuraEffect::HandleEffect(AuraApplication* aurApp, uint8 mode, bool apply) @@ -5105,7 +5114,7 @@ void AuraEffect::HandleModRating(AuraApplication const* aurApp, uint8 mode, bool if (!target->IsPlayer()) return; - for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating) + for (uint8 rating = 0; rating < MAX_COMBAT_RATING; ++rating) if (GetMiscValue() & (1 << rating)) target->ToPlayer()->ApplyRatingMod(CombatRating(rating), GetAmount(), apply); } @@ -5121,7 +5130,7 @@ void AuraEffect::HandleModRatingFromStat(AuraApplication const* aurApp, uint8 mo return; // Just recalculate ratings - for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating) + for (uint8 rating = 0; rating < MAX_COMBAT_RATING; ++rating) if (GetMiscValue() & (1 << rating)) target->ToPlayer()->ApplyRatingMod(CombatRating(rating), 0, apply); } diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp index ca45356219..0615f39c00 100644 --- a/src/server/game/Spells/SpellInfoCorrections.cpp +++ b/src/server/game/Spells/SpellInfoCorrections.cpp @@ -5162,6 +5162,14 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->ProcCharges = 1; }); + ApplySpellFix({ + 56917, // To Icecrown Airship - Teleport to Airship (A) + 57417, // To Icecrown Airship - Teleport to Airship (H) + }, [](SpellInfo* spellInfo) + { + spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100 yards + }); + for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i) { SpellInfo* spellInfo = mSpellInfoMap[i]; diff --git a/src/server/scripts/Northrend/zone_crystalsong_forest.cpp b/src/server/scripts/Northrend/zone_crystalsong_forest.cpp index bdf394cad9..645d3c0224 100644 --- a/src/server/scripts/Northrend/zone_crystalsong_forest.cpp +++ b/src/server/scripts/Northrend/zone_crystalsong_forest.cpp @@ -15,52 +15,100 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "CombatAI.h" #include "CreatureScript.h" -#include "PassiveAI.h" #include "Player.h" #include "ScriptedCreature.h" -#include "SmartScriptMgr.h" +#include "SpellAuras.h" +#include "SpellScript.h" #include "Transport.h" #include "Vehicle.h" enum ePreparationsForWar { - NPC_HAMMERHEAD = 30585, - NPC_CLOUDBUSTER = 30470, - TRANSPORT_ORGRIMS_HAMMER = 192241, - TRANSPORT_THE_SKYBREAKER = 192242 + NPC_CLOUDBUSTER = 30470, + NPC_HAMMERHEAD = 30585, + TRANSPORT_ORGRIMS_HAMMER = 192241, + TRANSPORT_THE_SKYBREAKER = 192242, + SEAT_PLAYER = 0, + SPELL_FLIGHT = 48602, + SPELL_TO_ICECROWN_PLAYER_AURA_DISMOUNT_A = 56904, + SPELL_TO_ICECROWN_PLAYER_AURA_DISMOUNT_H = 57419, + SPELL_TO_ICECROWN_AIRSHIP_PLAYER_AURA_TELEPORT_TO_DALARAN = 57460, + SPELL_TO_ICECROWN_AIRSHIP_FROST_WYRM_WAITING_TO_SUMMON_AURA = 57498, + POINT_END = 16, + SPELL_TO_ICECROWN_AIRSHIP_AURA_DISMOUNT_RESPONSE = 56921, // unhandled - vehicle casts 50630 on self + SPELL_EJECT_ALL_PASSENGERS = 50630, + SPELL_TO_ICECROWN_AIRSHIP_TELEPORT_TO_AIRSHIP_A_FORCE_PLAYER_TO_CAST = 57554, + SPELL_TO_ICECROWN_AIRSHIP_TELEPORT_TO_AIRSHIP_H_FORCE_PLAYER_TO_CAST = 57556, + SPELL_TO_ICECROWN_AIRSHIP_TELEPORT_TO_AIRSHIP_A = 56917, + SPELL_TO_ICECROWN_AIRSHIP_TELEPORT_TO_AIRSHIP_H = 57417, }; -struct npc_preparations_for_war_vehicle : public NullCreatureAI +struct npc_preparations_for_war_vehicle : public VehicleAI { - npc_preparations_for_war_vehicle(Creature* creature) : NullCreatureAI(creature) { } - - uint8 pointId; - uint32 searchForShipTimer; - uint32 transportEntry; + explicit npc_preparations_for_war_vehicle(Creature* creature) : VehicleAI(creature), searchForShipTimer(0), transportEntry(me->GetEntry() == NPC_CLOUDBUSTER ? TRANSPORT_THE_SKYBREAKER : TRANSPORT_ORGRIMS_HAMMER) + { + if (transportEntry == TRANSPORT_THE_SKYBREAKER) + { + // 30476 - [DND] Icecrown Flight To Airship Bunny (A) + passenger_x = 31.41805; + passenger_y = 0.126893; + passenger_z = 41.69821; + } + else // TRANSPORT_ORGRIMS_HAMMER + { + // 30588 - [DND] Icecrown Flight To Airship Bunny (H) + passenger_x = -18.10283; + passenger_y = -0.042108; + passenger_z = 45.31725; + } + } - void InitializeAI() override + void PassengerBoarded(Unit* who, int8 /*seatId*/, bool apply) override { - me->GetMotionMaster()->MovePath(me->GetEntry(), FORCED_MOVEMENT_NONE, PathSource::SMART_WAYPOINT_MGR); + if (apply) + { + DoCastSelf(SPELL_TO_ICECROWN_AIRSHIP_PLAYER_AURA_TELEPORT_TO_DALARAN, true); + DoCastSelf(SPELL_FLIGHT, true); + DoCastSelf(me->GetEntry() == NPC_CLOUDBUSTER ? SPELL_TO_ICECROWN_PLAYER_AURA_DISMOUNT_A : SPELL_TO_ICECROWN_PLAYER_AURA_DISMOUNT_H , true); + DoCastSelf(SPELL_TO_ICECROWN_AIRSHIP_FROST_WYRM_WAITING_TO_SUMMON_AURA, true); + me->GetMotionMaster()->MovePath(me->GetEntry(), FORCED_MOVEMENT_NONE, PathSource::SMART_WAYPOINT_MGR); + } + else + who->RemoveAurasDueToSpell(VEHICLE_SPELL_PARACHUTE); // maybe vehicle / seat flag should be responsible for parachute gain? + } - NullCreatureAI::InitializeAI(); - pointId = 0; - searchForShipTimer = 0; - transportEntry = (me->GetEntry() == NPC_HAMMERHEAD ? TRANSPORT_ORGRIMS_HAMMER : TRANSPORT_THE_SKYBREAKER); + void MovementInform(uint32 type, uint32 id) override + { + if (type == ESCORT_MOTION_TYPE && id == POINT_END) + searchForShipTimer = 3000; } - void MovementInform(uint32 type, uint32 /*id*/) override + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override { - if (type == ESCORT_MOTION_TYPE) - if (++pointId == 17) // path size - searchForShipTimer = 3000; + switch (spell->Id) + { + case SPELL_TO_ICECROWN_AIRSHIP_AURA_DISMOUNT_RESPONSE: + break; + case SPELL_TO_ICECROWN_AIRSHIP_TELEPORT_TO_AIRSHIP_A_FORCE_PLAYER_TO_CAST: + case SPELL_TO_ICECROWN_AIRSHIP_TELEPORT_TO_AIRSHIP_H_FORCE_PLAYER_TO_CAST: + { + uint32 teleportSpell = (spell->Id == SPELL_TO_ICECROWN_AIRSHIP_TELEPORT_TO_AIRSHIP_A_FORCE_PLAYER_TO_CAST) + ? SPELL_TO_ICECROWN_AIRSHIP_TELEPORT_TO_AIRSHIP_A + : SPELL_TO_ICECROWN_AIRSHIP_TELEPORT_TO_AIRSHIP_H; + DoCastSelf(teleportSpell, true); // hack: cast on self to avoid visual glitch on player when ejecting and teleporting on transport + DoCastSelf(SPELL_EJECT_ALL_PASSENGERS, true); + me->DespawnOrUnsummon(0s); + break; + } + default: + break; + } } void UpdateAI(uint32 diff) override { - // horde 7.55f, -0.09, 34.44, 3.13, +20 - // ally 45.18f, 0.03, 40.09, 3.14 +5 - if (searchForShipTimer) { searchForShipTimer += diff; @@ -68,37 +116,14 @@ struct npc_preparations_for_war_vehicle : public NullCreatureAI { searchForShipTimer = 1; TransportsContainer const& transports = me->GetMap()->GetAllTransports(); - for (TransportsContainer::const_iterator itr = transports.begin(); itr != transports.end(); ++itr) + for (auto const transport : transports) { - if ((*itr)->GetEntry() == transportEntry) + if (transport->GetEntry() == transportEntry) { - float x, y, z; - if (transportEntry == TRANSPORT_ORGRIMS_HAMMER) - { - x = 7.55f; - y = -0.09f; - z = 54.44f; - } - else - { - x = 45.18f; - y = 0.03f; - z = 45.09f; - } + float x = passenger_x, y = passenger_y, z = passenger_z; + transport->CalculatePassengerPosition(x, y, z); - (*itr)->CalculatePassengerPosition(x, y, z); - - if (me->GetDistance2d(x, y) < 10.0f) - { - me->DespawnOrUnsummon(1s); - if (Vehicle* vehicle = me->GetVehicleKit()) - if (Unit* passenger = vehicle->GetPassenger(0)) - { - passenger->NearTeleportTo(x, y, z - (transportEntry == TRANSPORT_ORGRIMS_HAMMER ? 19.0f : 4.0f), M_PI); - passenger->RemoveAurasDueToSpell(VEHICLE_SPELL_PARACHUTE); // maybe vehicle / seat flag should be responsible for parachute gain? - } - } - else + if (me->GetDistance2d(x, y) > 20.0f) // dismount trigger (56905, 57420) range is 30 me->GetMotionMaster()->MovePoint(0, x, y, z, FORCED_MOVEMENT_NONE, 0.f, 0.f, false, false); break; } @@ -106,6 +131,10 @@ struct npc_preparations_for_war_vehicle : public NullCreatureAI } } } +private: + float passenger_x, passenger_y, passenger_z; + uint32 searchForShipTimer; + uint32 transportEntry; }; /******************************************************* diff --git a/src/server/scripts/Northrend/zone_howling_fjord.cpp b/src/server/scripts/Northrend/zone_howling_fjord.cpp index fc28598ec2..928a0a71e8 100644 --- a/src/server/scripts/Northrend/zone_howling_fjord.cpp +++ b/src/server/scripts/Northrend/zone_howling_fjord.cpp @@ -66,109 +66,6 @@ public: } }; -// The cleansing -enum TurmoilTexts -{ - SAY_TURMOIL_0 = 0, - SAY_TURMOIL_1 = 1, - SAY_TURMOIL_HALF_HP = 2, - SAY_TURMOIL_DEATH = 3, -}; - -class npc_your_inner_turmoil : public CreatureScript -{ -public: - npc_your_inner_turmoil() : CreatureScript("npc_your_inner_turmoil") { } - - struct npc_your_inner_turmoilAI : public ScriptedAI - { - npc_your_inner_turmoilAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 timer; - short phase; - bool health50; - - void Reset() override - { - timer = 0; - phase = 0; - health50 = false; - } - - void UpdateAI(uint32 diff) override - { - if (timer >= 6000 && phase < 2) - { - phase++; - setphase(phase); - timer = 0; - } - - timer += diff; - - DoMeleeAttackIfReady(); - } - - void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override - { - if (HealthBelowPct(50) && !health50) - { - if (TempSummon const* tempSummon = me->ToTempSummon()) - { - if (WorldObject* summoner = tempSummon->GetSummonerUnit()) - { - Talk(SAY_TURMOIL_HALF_HP, summoner); - } - } - - health50 = true; - } - } - - void JustDied(Unit* /*killer*/) override - { - if (TempSummon const* tempSummon = me->ToTempSummon()) - { - if (WorldObject* summoner = tempSummon->GetSummonerUnit()) - { - Talk(SAY_TURMOIL_DEATH, summoner); - } - } - } - - void setphase(short newPhase) - { - Unit* summoner = me->ToTempSummon() ? me->ToTempSummon()->GetSummonerUnit() : nullptr; - if (!summoner || !summoner->IsPlayer()) - return; - - switch (newPhase) - { - case 1: - Talk(SAY_TURMOIL_0, summoner->ToPlayer()); - return; - case 2: - { - Talk(SAY_TURMOIL_1, summoner->ToPlayer()); - me->SetLevel(summoner->GetLevel()); - me->SetFaction(FACTION_MONSTER); - if (me->GetExactDist(summoner) < 50.0f) - { - me->UpdatePosition(summoner->GetPositionX(), summoner->GetPositionY(), summoner->GetPositionZ(), 0.0f, true); - summoner->CastSpell(me, 50218, true); // clone caster - AttackStart(summoner); - } - } - } - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_your_inner_turmoilAI(creature); - } -}; - /*###### ## npc_apothecary_hanes ######*/ @@ -457,13 +354,145 @@ class spell_hawk_hunting : public SpellScript } }; +/*###### +## Quest 11317, 11322: The Cleansing +######*/ + +enum TheCleansing +{ + SPELL_CLEANSING_SOUL = 43351, + SPELL_SUMMON_INNER_TURMOIL = 50167, + SPELL_RECENT_MEDITATION = 61720, + SPELL_MIRROR_IMAGE_AURA = 50218, + + QUEST_THE_CLEANSING_H = 11317, + QUEST_THE_CLEANSING_A = 11322 +}; + +// 43365 - The Cleansing: Shrine Cast +class spell_the_cleansing_shrine_cast : public SpellScript +{ + PrepareSpellScript(spell_the_cleansing_shrine_cast); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_RECENT_MEDITATION, SPELL_CLEANSING_SOUL }) && + sObjectMgr->GetQuestTemplate(QUEST_THE_CLEANSING_H) && + sObjectMgr->GetQuestTemplate(QUEST_THE_CLEANSING_A); + } + + SpellCastResult CheckCast() + { + // Error is correct for quest check but may be not correct for aura and this may be a wrong place to send error + if (Player* target = GetExplTargetUnit()->ToPlayer()) + { + if (target->HasAura(SPELL_RECENT_MEDITATION) || (!(target->GetQuestStatus(QUEST_THE_CLEANSING_H) == QUEST_STATUS_INCOMPLETE || + target->GetQuestStatus(QUEST_THE_CLEANSING_A) == QUEST_STATUS_INCOMPLETE))) + { + Spell::SendCastResult(target, GetSpellInfo(), 0, SPELL_FAILED_FIZZLE); + return SPELL_FAILED_FIZZLE; + } + } + return SPELL_CAST_OK; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_CLEANSING_SOUL, true); + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_the_cleansing_shrine_cast::CheckCast); + OnEffectHitTarget += SpellEffectFn(spell_the_cleansing_shrine_cast::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +// 43351 - Cleansing Soul +class spell_the_cleansing_cleansing_soul : public AuraScript +{ + PrepareAuraScript(spell_the_cleansing_cleansing_soul); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SUMMON_INNER_TURMOIL, SPELL_RECENT_MEDITATION }); + } + + void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->SetStandState(UNIT_STAND_STATE_SIT); + } + + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->SetStandState(UNIT_STAND_STATE_STAND); + target->CastSpell(target, SPELL_SUMMON_INNER_TURMOIL, true); + target->CastSpell(target, SPELL_RECENT_MEDITATION, true); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_the_cleansing_cleansing_soul::AfterApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_the_cleansing_cleansing_soul::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + +// 50217 - The Cleansing: Script Effect Player Cast Mirror Image +class spell_the_cleansing_mirror_image_script_effect : public SpellScript +{ + PrepareSpellScript(spell_the_cleansing_mirror_image_script_effect); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MIRROR_IMAGE_AURA }); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_MIRROR_IMAGE_AURA, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_the_cleansing_mirror_image_script_effect::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +// 50238 - The Cleansing: Your Inner Turmoil's On Death Cast on Master +class spell_the_cleansing_on_death_cast_on_master : public SpellScript +{ + PrepareSpellScript(spell_the_cleansing_on_death_cast_on_master); + + bool Validate(SpellInfo const* spellInfo) override + { + return ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()) }); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Unit* caster = GetCaster()) + if (TempSummon* casterSummon = caster->ToTempSummon()) + if (Unit* summoner = casterSummon->GetSummonerUnit()) + summoner->CastSpell(summoner, GetSpellInfo()->Effects[EFFECT_0].CalcValue(), true); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_the_cleansing_on_death_cast_on_master::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + void AddSC_howling_fjord() { new npc_attracted_reef_bull(); - new npc_your_inner_turmoil(); new npc_apothecary_hanes(); new npc_plaguehound_tracker(); new npc_razael_and_lyana(); RegisterCreatureAI(npc_rodin_lightning_enabler); RegisterSpellScript(spell_hawk_hunting); + RegisterSpellScript(spell_the_cleansing_shrine_cast); + RegisterSpellScript(spell_the_cleansing_cleansing_soul); + RegisterSpellScript(spell_the_cleansing_mirror_image_script_effect); + RegisterSpellScript(spell_the_cleansing_on_death_cast_on_master); } diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp index 5c208f1187..836469a3e8 100644 --- a/src/server/scripts/Northrend/zone_storm_peaks.cpp +++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp @@ -915,72 +915,40 @@ public: } }; -class npc_hyldsmeet_protodrake : public CreatureScript +enum HyldsmeetProtoDrake { - enum NPCs - { - NPC_HYLDSMEET_DRAKERIDER = 29694 - }; + NPC_HYLDSMEET_DRAKERIDER = 29694 +}; -public: - npc_hyldsmeet_protodrake() : CreatureScript("npc_hyldsmeet_protodrake") { } +struct npc_hyldsmeet_protodrake : public CreatureAI +{ + explicit npc_hyldsmeet_protodrake(Creature* creature) : CreatureAI(creature), _accessoryRespawnTimer(0) { } - class npc_hyldsmeet_protodrakeAI : public CreatureAI + void PassengerBoarded(Unit* who, int8 /*seat*/, bool apply) override { - public: - npc_hyldsmeet_protodrakeAI(Creature* creature) : CreatureAI(creature), _accessoryRespawnTimer(0), _vehicleKit(creature->GetVehicleKit()) { } - - void PassengerBoarded(Unit* who, int8 /*seat*/, bool apply) override - { - if (apply) - { - class DelayedTransportPositionOffsets : public BasicEvent - { - public: - DelayedTransportPositionOffsets(Unit* owner) : _owner(owner) { } - - bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override - { - _owner->m_movementInfo.transport.pos.Relocate(-3.5f, 0.f, -0.2f, 0.f); - return true; - } - - private: - Unit* _owner; - }; - - if (who->IsPlayer()) - who->m_Events.AddEventAtOffset(new DelayedTransportPositionOffsets(who), 500ms); - - return; - } + if (apply) + return; - if (who->GetEntry() == NPC_HYLDSMEET_DRAKERIDER) - _accessoryRespawnTimer = 5 * MINUTE * IN_MILLISECONDS; - } + if (who->GetEntry() == NPC_HYLDSMEET_DRAKERIDER) + _accessoryRespawnTimer = 5 * MINUTE * IN_MILLISECONDS; + } - void UpdateAI(uint32 diff) override + void UpdateAI(uint32 diff) override + { + //! We need to manually reinstall accessories because the vehicle itself is friendly to players, + //! so EnterEvadeMode is never triggered. The accessory on the other hand is hostile and killable. + Vehicle* vehicleKit = me->GetVehicleKit(); + if (_accessoryRespawnTimer && _accessoryRespawnTimer <= diff && vehicleKit) { - //! We need to manually reinstall accessories because the vehicle itself is friendly to players, - //! so EnterEvadeMode is never triggered. The accessory on the other hand is hostile and killable. - if (_accessoryRespawnTimer && _accessoryRespawnTimer <= diff && _vehicleKit) - { - _vehicleKit->InstallAllAccessories(true); - _accessoryRespawnTimer = 0; - } - else - _accessoryRespawnTimer -= diff; + vehicleKit->InstallAllAccessories(true); + _accessoryRespawnTimer = 0; } - - private: - uint32 _accessoryRespawnTimer; - Vehicle* _vehicleKit; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_hyldsmeet_protodrakeAI(creature); + else + _accessoryRespawnTimer -= diff; } + +private: + uint32 _accessoryRespawnTimer; }; enum CloseRift @@ -1215,7 +1183,7 @@ void AddSC_storm_peaks() new npc_brunnhildar_prisoner(); new npc_freed_protodrake(); new npc_icefang(); - new npc_hyldsmeet_protodrake(); + RegisterCreatureAI(npc_hyldsmeet_protodrake); RegisterSpellScript(spell_close_rift_aura); new npc_vehicle_d16_propelled_delivery(); RegisterSpellScript(spell_q12823_remove_collapsing_cave_aura); diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index c6f90e153e..85a12610da 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -443,15 +443,16 @@ class spell_dru_enrage : public AuraScript void RecalculateBaseArmor() { + // Recalculate modifies the list while we're iterating through it, so let's copy it instead Unit::AuraEffectList const& auras = GetTarget()->GetAuraEffectsByType(SPELL_AURA_MOD_BASE_RESISTANCE_PCT); - for (Unit::AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i) + std::vector<AuraEffect*> aurEffs(auras.begin(), auras.end()); + + for (AuraEffect* aurEff : aurEffs) { - SpellInfo const* spellInfo = (*i)->GetSpellInfo(); + SpellInfo const* spellInfo = aurEff->GetSpellInfo(); // Dire- / Bear Form (Passive) if (spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && spellInfo->SpellFamilyFlags.HasFlag(0x0, 0x0, 0x2)) - { - (*i)->RecalculateAmount(); - } + aurEff->RecalculateAmount(); } } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index f36f2d2234..38f669693f 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -5673,6 +5673,29 @@ class spell_gen_bm_on : public SpellScript } }; +class spell_gen_whisper_to_controller : public SpellScript +{ + PrepareSpellScript(spell_gen_whisper_to_controller); + + bool Validate(SpellInfo const* spellInfo) override + { + return sObjectMgr->GetBroadcastText(uint32(spellInfo->GetEffect(EFFECT_0).CalcValue())); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Unit* caster = GetCaster()) + if (TempSummon* casterSummon = caster->ToTempSummon()) + if (Player* target = casterSummon->GetSummonerUnit()->ToPlayer()) + casterSummon->Unit::Whisper(uint32(GetEffectValue()), target, false); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_gen_whisper_to_controller::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + void AddSC_generic_spell_scripts() { RegisterSpellScript(spell_silithyst); @@ -5846,4 +5869,5 @@ void AddSC_generic_spell_scripts() RegisterSpellScript(spell_gen_invis_on); RegisterSpellScript(spell_gen_bm_on); RegisterSpellScript(spell_gen_bm_off); + RegisterSpellScript(spell_gen_whisper_to_controller); } diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 870cc73850..4e1b563333 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -247,28 +247,6 @@ class spell_q10525_vision_guide : public AuraScript } }; -class spell_q11322_q11317_the_cleansing : public AuraScript -{ - PrepareAuraScript(spell_q11322_q11317_the_cleansing) - - void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* ar = GetCaster(); - if (ar && ar->ToPlayer()) - { - if (ar->ToPlayer()->GetQuestStatus(11317) == QUEST_STATUS_INCOMPLETE || ar->ToPlayer()->GetQuestStatus(11322) == QUEST_STATUS_INCOMPLETE) - ar->SummonCreature(27959, 3032.0f, -5095.0f, 723.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - - ar->SetStandState(UNIT_STAND_STATE_SIT); - } - } - - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_q11322_q11317_the_cleansing::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - class spell_q10714_on_spirits_wings : public SpellScript { PrepareSpellScript(spell_q10714_on_spirits_wings); @@ -2499,7 +2477,6 @@ void AddSC_quest_spell_scripts() RegisterSpellScript(spell_q12014_steady_as_a_rock); RegisterSpellAndAuraScriptPair(spell_q11026_a11051_banish_the_demons, spell_q11026_a11051_banish_the_demons_aura); RegisterSpellScript(spell_q10525_vision_guide); - RegisterSpellScript(spell_q11322_q11317_the_cleansing); RegisterSpellScript(spell_q10714_on_spirits_wings); RegisterSpellScript(spell_q10720_the_smallest_creature); RegisterSpellScript(spell_q13086_last_line_of_defence); diff --git a/src/server/shared/Network/AsyncAcceptor.h b/src/server/shared/Network/AsyncAcceptor.h index f91c2ca37e..71c58ed937 100644 --- a/src/server/shared/Network/AsyncAcceptor.h +++ b/src/server/shared/Network/AsyncAcceptor.h @@ -20,6 +20,7 @@ #include "IpAddress.h" #include "Log.h" +#include "Systemd.h" #include <atomic> #include <boost/asio/ip/tcp.hpp> #include <functional> @@ -33,10 +34,20 @@ class AsyncAcceptor public: typedef void(*AcceptCallback)(tcp::socket&& newSocket, uint32 threadIndex); - AsyncAcceptor(Acore::Asio::IoContext& ioContext, std::string const& bindIp, uint16 port) : + AsyncAcceptor(Acore::Asio::IoContext& ioContext, std::string const& bindIp, uint16 port, bool supportSocketActivation = false) : _acceptor(ioContext), _endpoint(Acore::Net::make_address(bindIp), port), - _socket(ioContext), _closed(false), _socketFactory([this](){ return DefaultSocketFactory(); }) + _socket(ioContext), _closed(false), _socketFactory([this](){ return DefaultSocketFactory(); }), + _supportSocketActivation(supportSocketActivation) { + int const listen_fd = get_listen_fd(); + if (_supportSocketActivation && listen_fd > 0) + { + LOG_DEBUG("network", "Using socket from systemd socket activation"); + boost::system::error_code errorCode; + _acceptor.assign(boost::asio::ip::tcp::v4(), listen_fd, errorCode); + if (errorCode) + LOG_WARN("network", "Failed to assign socket {}", errorCode.message()); + } } template<class T> @@ -72,27 +83,31 @@ public: bool Bind() { boost::system::error_code errorCode; - _acceptor.open(_endpoint.protocol(), errorCode); - if (errorCode) + // with socket activation the acceptor is already open and bound + if (!_acceptor.is_open()) { - LOG_INFO("network", "Failed to open acceptor {}", errorCode.message()); - return false; - } + _acceptor.open(_endpoint.protocol(), errorCode); + if (errorCode) + { + LOG_INFO("network", "Failed to open acceptor {}", errorCode.message()); + return false; + } #if AC_PLATFORM != AC_PLATFORM_WINDOWS - _acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true), errorCode); - if (errorCode) - { - LOG_INFO("network", "Failed to set reuse_address option on acceptor {}", errorCode.message()); - return false; - } + _acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true), errorCode); + if (errorCode) + { + LOG_INFO("network", "Failed to set reuse_address option on acceptor {}", errorCode.message()); + return false; + } #endif - _acceptor.bind(_endpoint, errorCode); - if (errorCode) - { - LOG_INFO("network", "Could not bind to {}:{} {}", _endpoint.address().to_string(), _endpoint.port(), errorCode.message()); - return false; + _acceptor.bind(_endpoint, errorCode); + if (errorCode) + { + LOG_INFO("network", "Could not bind to {}:{} {}", _endpoint.address().to_string(), _endpoint.port(), errorCode.message()); + return false; + } } _acceptor.listen(ACORE_MAX_LISTEN_CONNECTIONS, errorCode); @@ -124,6 +139,7 @@ private: tcp::socket _socket; std::atomic<bool> _closed; std::function<std::pair<tcp::socket*, uint32>()> _socketFactory; + bool _supportSocketActivation; }; template<class T> diff --git a/src/server/shared/Network/SocketMgr.h b/src/server/shared/Network/SocketMgr.h index dc0c5e6f5f..085e4e2380 100644 --- a/src/server/shared/Network/SocketMgr.h +++ b/src/server/shared/Network/SocketMgr.h @@ -19,6 +19,7 @@ #define SocketMgr_h__ #include "AsyncAcceptor.h" +#include "Config.h" #include "Errors.h" #include "NetworkThread.h" #include <boost/asio/ip/tcp.hpp> @@ -42,7 +43,8 @@ public: std::unique_ptr<AsyncAcceptor> acceptor; try { - acceptor = std::make_unique<AsyncAcceptor>(ioContext, bindIp, port); + bool supportSocketActivation = sConfigMgr->GetOption<bool>("Network.UseSocketActivation", false); + acceptor = std::make_unique<AsyncAcceptor>(ioContext, bindIp, port, supportSocketActivation); } catch (boost::system::system_error const& err) { |
