diff --git a/CHANGELOG.md b/CHANGELOG.md index 10d49541e..88680e6dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +## [22.62.1] 1/27/2025 + +### Memory Leak + +* Revert "Change raw pointer to unique_ptr to avoid potential leak in dbg stream" ([#4616](https://github.com/EQEmu/Server/pull/4616)) @Akkadius 2025-01-27 + +### Performance + +* Re-use ClientUpdate packet memory ([#4619](https://github.com/EQEmu/Server/pull/4619)) @Akkadius 2025-01-27 +* Re-use OP_Animation packet ([#4621](https://github.com/EQEmu/Server/pull/4621)) @Akkadius 2025-01-27 +* Re-use OP_Damage packet memory ([#4625](https://github.com/EQEmu/Server/pull/4625)) @Akkadius 2025-01-27 +* Re-use OP_HPUpdate packet memory ([#4622](https://github.com/EQEmu/Server/pull/4622)) @Akkadius 2025-01-27 +* Re-use OP_PlayerStateAdd packet memory ([#4626](https://github.com/EQEmu/Server/pull/4626)) @Akkadius 2025-01-27 +* Re-use OP_SendFindableNPCs packet memory ([#4623](https://github.com/EQEmu/Server/pull/4623)) @Akkadius 2025-01-27 + +### Repop + +* Make #repop instant ([#4620](https://github.com/EQEmu/Server/pull/4620)) @Akkadius 2025-01-27 + ## [22.62.0] 1/26/2025 ### Bazaar diff --git a/common/net/daybreak_connection.cpp b/common/net/daybreak_connection.cpp index 6af6576b1..0fefc9982 100644 --- a/common/net/daybreak_connection.cpp +++ b/common/net/daybreak_connection.cpp @@ -500,9 +500,10 @@ void EQ::Net::DaybreakConnection::ProcessQueue() break; } - auto &packet = iter->second; + auto packet = iter->second; stream->packet_queue.erase(iter); ProcessDecodedPacket(*packet); + delete packet; } } } @@ -512,8 +513,9 @@ void EQ::Net::DaybreakConnection::RemoveFromQueue(int stream, uint16_t seq) auto s = &m_streams[stream]; auto iter = s->packet_queue.find(seq); if (iter != s->packet_queue.end()) { - auto &packet = iter->second; + auto packet = iter->second; s->packet_queue.erase(iter); + delete packet; } } @@ -525,7 +527,7 @@ void EQ::Net::DaybreakConnection::AddToQueue(int stream, uint16_t seq, const Pac DynamicPacket *out = new DynamicPacket(); out->PutPacket(0, p); - s->packet_queue.emplace(std::make_pair(seq, std::unique_ptr(out))); + s->packet_queue.emplace(std::make_pair(seq, out)); } } diff --git a/common/net/daybreak_connection.h b/common/net/daybreak_connection.h index 2561f91a4..c2c714813 100644 --- a/common/net/daybreak_connection.h +++ b/common/net/daybreak_connection.h @@ -201,7 +201,7 @@ namespace EQ uint16_t sequence_in; uint16_t sequence_out; - std::map> packet_queue; + std::map packet_queue; DynamicPacket fragment_packet; uint32_t fragment_current_bytes; diff --git a/common/version.h b/common/version.h index 19a7bf16f..4ad0bb533 100644 --- a/common/version.h +++ b/common/version.h @@ -25,7 +25,7 @@ // Build variables // these get injected during the build pipeline -#define CURRENT_VERSION "22.62.0-dev" // always append -dev to the current version for custom-builds +#define CURRENT_VERSION "22.62.1-dev" // always append -dev to the current version for custom-builds #define LOGIN_VERSION "0.8.0" #define COMPILE_DATE __DATE__ #define COMPILE_TIME __TIME__ diff --git a/package.json b/package.json index 64fa8fb46..91084bc77 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eqemu-server", - "version": "22.62.0", + "version": "22.62.1", "repository": { "type": "git", "url": "https://github.com/EQEmu/Server.git" diff --git a/zone/attack.cpp b/zone/attack.cpp index 3b4d20799..cc61f83ce 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -2564,16 +2564,12 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy const uint8 killed_level = GetLevel(); if (GetClass() == Class::LDoNTreasure) { // open chest - auto outapp = new EQApplicationPacket(OP_Animation, sizeof(Animation_Struct)); - - auto a = (Animation_Struct*) outapp->pBuffer; - + static EQApplicationPacket p(OP_Animation, sizeof(Animation_Struct)); + auto a = (Animation_Struct*) p.pBuffer; a->spawnid = GetID(); a->action = 0x0F; a->speed = 10; - - entity_list.QueueCloseClients(this, outapp); - safe_delete(outapp); + entity_list.QueueCloseClients(this, &p); } auto app = new EQApplicationPacket(OP_Death, sizeof(Death_Struct)); @@ -3412,15 +3408,15 @@ void Mob::DamageShield(Mob* attacker, bool spell_ds) { attacker->Damage(this, -DS, spellid, EQ::skills::SkillAbjuration/*hackish*/, false); //we can assume there is a spell now - auto outapp = new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct)); - CombatDamage_Struct* cds = (CombatDamage_Struct*)outapp->pBuffer; - cds->target = attacker->GetID(); - cds->source = GetID(); - cds->type = spellbonuses.DamageShieldType; - cds->spellid = 0x0; - cds->damage = DS; - entity_list.QueueCloseClients(this, outapp); - safe_delete(outapp); + + static EQApplicationPacket p(OP_Damage, sizeof(CombatDamage_Struct)); + auto b = (CombatDamage_Struct *) p.pBuffer; + b->target = attacker->GetID(); + b->source = GetID(); + b->type = spellbonuses.DamageShieldType; + b->spellid = 0x0; + b->damage = DS; + entity_list.QueueCloseClients(this, &p); } else if (DS > 0 && !spell_ds) { //we are healing the attacker... @@ -4537,8 +4533,8 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons //send damage packet... if (!iBuffTic) { //buff ticks do not send damage, instead they just call SendHPUpdate(), which is done above - auto outapp = new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct)); - CombatDamage_Struct* a = (CombatDamage_Struct*)outapp->pBuffer; + static EQApplicationPacket p(OP_Damage, sizeof(CombatDamage_Struct)); + auto a = (CombatDamage_Struct *) p.pBuffer; a->target = GetID(); if (!attacker) { @@ -4619,7 +4615,7 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons if (!FromDamageShield) { entity_list.QueueCloseClients( attacker, /* Sender */ - outapp, /* packet */ + &p, /* packet */ false, /* Skip Sender */ ((IsValidSpell(spell_id)) ? RuleI(Range, SpellMessages) : RuleI(Range, DamageMessages)), 0, /* don't skip anyone on spell */ @@ -4693,11 +4689,11 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons filter = FilterMyMisses; if (attacker->IsClient()) { - attacker->CastToClient()->QueuePacket(outapp, true, CLIENT_CONNECTED, filter); + attacker->CastToClient()->QueuePacket(&p, true, CLIENT_CONNECTED, filter); } else { entity_list.QueueCloseClients( attacker, /* Sender */ - outapp, /* packet */ + &p, /* packet */ false, /* Skip Sender */ ( IsValidSpell(spell_id) ? @@ -4752,7 +4748,7 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons a->type = DamageTypeSpell; entity_list.QueueCloseClients( this, /* Sender */ - outapp, /* packet */ + &p, /* packet */ false, /* Skip Sender */ range, /* distance packet travels at the speed of sound */ 0, /* don't skip anyone on spell */ @@ -4763,7 +4759,7 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons else { //I dont think any filters apply to damage affecting us if (IsClient()) { - CastToClient()->QueuePacket(outapp); + CastToClient()->QueuePacket(&p); } // Send normal message to observers @@ -4773,7 +4769,7 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons if (!owner || (owner && !owner->IsClient())) { entity_list.QueueCloseClients( this, /* Sender */ - outapp, /* packet */ + &p, /* packet */ true, /* Skip Sender */ range, /* distance packet travels at the speed of sound */ (IsValidSpell(spell_id) && skill_used != EQ::skills::SkillTigerClaw) ? 0 : skip, @@ -4783,8 +4779,6 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons } } } - - safe_delete(outapp); } else { //else, it is a buff tic... diff --git a/zone/aura.cpp b/zone/aura.cpp index 28fe7f15b..17c12abdd 100644 --- a/zone/aura.cpp +++ b/zone/aura.cpp @@ -735,21 +735,22 @@ bool Aura::Process() if (movement_type == AuraMovement::Follow && GetPosition() != owner->GetPosition() && movement_timer.Check()) { m_Position = owner->GetPosition(); - auto app = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - auto spu = (PlayerPositionUpdateServer_Struct *) app->pBuffer; + + static EQApplicationPacket packet(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); + auto spu = (PlayerPositionUpdateServer_Struct *) packet.pBuffer; + MakeSpawnUpdate(spu); auto it = spawned_for.begin(); while (it != spawned_for.end()) { auto client = entity_list.GetClientByID(*it); if (client) { - client->QueuePacket(app); + client->QueuePacket(&packet); ++it; } else { it = spawned_for.erase(it); } } - safe_delete(app); } // TODO: waypoints? diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 4d0d9b6f8..ac571add9 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4856,11 +4856,10 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { auto boat_delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, EQ10toFloat(ppu->delta_heading)); cmob->SetDelta(boat_delta); - auto outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - PlayerPositionUpdateServer_Struct *ppus = (PlayerPositionUpdateServer_Struct *) outapp->pBuffer; + static EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); + auto *ppus = (PlayerPositionUpdateServer_Struct *) outapp.pBuffer; cmob->MakeSpawnUpdate(ppus); - entity_list.QueueCloseClients(cmob, outapp, true, 300, this, false); - safe_delete(outapp); + entity_list.QueueCloseClients(cmob, &outapp, true, 300, this, false); /* Update the boat's position on the server, without sending an update */ cmob->GMMove(ppu->x_pos, ppu->y_pos, ppu->z_pos, EQ12toFloat(ppu->heading)); @@ -5034,15 +5033,15 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { m_Position.w = new_heading; /* Broadcast update to other clients */ - auto outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - PlayerPositionUpdateServer_Struct *position_update = (PlayerPositionUpdateServer_Struct *) outapp->pBuffer; + static EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); + PlayerPositionUpdateServer_Struct *position_update = (PlayerPositionUpdateServer_Struct *) outapp.pBuffer; MakeSpawnUpdate(position_update); if (gm_hide_me) { - entity_list.QueueClientsStatus(this, outapp, true, Admin(), AccountStatus::Max); + entity_list.QueueClientsStatus(this, &outapp, true, Admin(), AccountStatus::Max); } else { - entity_list.QueueCloseClients(this, outapp, true, RuleI(Range, ClientPositionUpdates), nullptr, true); + entity_list.QueueCloseClients(this, &outapp, true, RuleI(Range, ClientPositionUpdates), nullptr, true); } @@ -5051,12 +5050,10 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { Raid *raid = GetRaid(); if (raid) { - raid->QueueClients(this, outapp, true, true, (RuleI(Range, ClientPositionUpdates) * -1)); + raid->QueueClients(this, &outapp, true, true, (RuleI(Range, ClientPositionUpdates) * -1)); } else if (group) { - group->QueueClients(this, outapp, true, true, (RuleI(Range, ClientPositionUpdates) * -1)); + group->QueueClients(this, &outapp, true, true, (RuleI(Range, ClientPositionUpdates) * -1)); } - - safe_delete(outapp); } if (zone->watermap) { @@ -16776,13 +16773,12 @@ bool Client::CanTradeFVNoDropItem() void Client::SendMobPositions() { - auto p = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - auto *s = (PlayerPositionUpdateServer_Struct *) p->pBuffer; + static EQApplicationPacket p(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); + auto *s = (PlayerPositionUpdateServer_Struct *) p.pBuffer; for (auto &m: entity_list.GetMobList()) { m.second->MakeSpawnUpdate(s); - QueuePacket(p, false); + QueuePacket(&p, false); } - safe_delete(p); } struct RecordKillCheck { diff --git a/zone/entity.cpp b/zone/entity.cpp index 1ec17ad64..198ddf710 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -5312,15 +5312,12 @@ void EntityList::SendFindableNPCList(Client *c) return; } - auto outapp = new EQApplicationPacket(OP_SendFindableNPCs, sizeof(FindableNPC_Struct)); - - FindableNPC_Struct *fnpcs = (FindableNPC_Struct *)outapp->pBuffer; - - fnpcs->Unknown109 = 0x16; - fnpcs->Unknown110 = 0x06; - fnpcs->Unknown111 = 0x24; - - fnpcs->Action = 0; + static EQApplicationPacket p(OP_SendFindableNPCs, sizeof(FindableNPC_Struct)); + auto b = (FindableNPC_Struct*) p.pBuffer; + b->Unknown109 = 0x16; + b->Unknown110 = 0x06; + b->Unknown111 = 0x24; + b->Action = 0; auto it = npc_list.begin(); while (it != npc_list.end()) { @@ -5328,50 +5325,47 @@ void EntityList::SendFindableNPCList(Client *c) NPC *n = it->second; if (n->IsFindable()) { - fnpcs->EntityID = n->GetID(); - strn0cpy(fnpcs->Name, n->GetCleanName(), sizeof(fnpcs->Name)); - strn0cpy(fnpcs->LastName, n->GetLastName(), sizeof(fnpcs->LastName)); - fnpcs->Race = n->GetRace(); - fnpcs->Class = n->GetClass(); + b->EntityID = n->GetID(); + strn0cpy(b->Name, n->GetCleanName(), sizeof(b->Name)); + strn0cpy(b->LastName, n->GetLastName(), sizeof(b->LastName)); + b->Race = n->GetRace(); + b->Class = n->GetClass(); - c->QueuePacket(outapp); + c->QueuePacket(&p); } } ++it; } - safe_delete(outapp); } void EntityList::UpdateFindableNPCState(NPC *n, bool Remove) { - if (!n || !n->IsFindable()) + if (!n || !n->IsFindable()) { return; + } - auto outapp = new EQApplicationPacket(OP_SendFindableNPCs, sizeof(FindableNPC_Struct)); + static EQApplicationPacket p(OP_SendFindableNPCs, sizeof(FindableNPC_Struct)); + auto b = (FindableNPC_Struct *) p.pBuffer; + b->Unknown109 = 0x16; + b->Unknown110 = 0x06; + b->Unknown111 = 0x24; - FindableNPC_Struct *fnpcs = (FindableNPC_Struct *)outapp->pBuffer; - - fnpcs->Unknown109 = 0x16; - fnpcs->Unknown110 = 0x06; - fnpcs->Unknown111 = 0x24; - - fnpcs->Action = Remove ? 1: 0; - fnpcs->EntityID = n->GetID(); - strn0cpy(fnpcs->Name, n->GetCleanName(), sizeof(fnpcs->Name)); - strn0cpy(fnpcs->LastName, n->GetLastName(), sizeof(fnpcs->LastName)); - fnpcs->Race = n->GetRace(); - fnpcs->Class = n->GetClass(); + b->Action = Remove ? 1 : 0; + b->EntityID = n->GetID(); + strn0cpy(b->Name, n->GetCleanName(), sizeof(b->Name)); + strn0cpy(b->LastName, n->GetLastName(), sizeof(b->LastName)); + b->Race = n->GetRace(); + b->Class = n->GetClass(); auto it = client_list.begin(); while (it != client_list.end()) { Client *c = it->second; - if (c && (c->ClientVersion() >= EQ::versions::ClientVersion::SoD)) - c->QueuePacket(outapp); + if (c && (c->ClientVersion() >= EQ::versions::ClientVersion::SoD)) { + c->QueuePacket(&p); + } ++it; } - - safe_delete(outapp); } void EntityList::HideCorpses(Client *c, uint8 CurrentMode, uint8 NewMode) diff --git a/zone/mob.cpp b/zone/mob.cpp index 2d3013230..e5b82af12 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -125,7 +125,7 @@ Mob::Mob( tmHidden(-1), mitigation_ac(0), m_specialattacks(eSpecialAttacks::None), - attack_anim_timer(500), + attack_anim_timer(100), position_update_melee_push_timer(500), hate_list_cleanup_timer(6000), m_scan_close_mobs_timer(6000), @@ -1522,16 +1522,12 @@ void Mob::SendHPUpdate(bool force_update_all) last_hp ); - auto client_packet = new EQApplicationPacket(OP_HPUpdate, sizeof(SpawnHPUpdate_Struct)); - auto *hp_packet_client = (SpawnHPUpdate_Struct *) client_packet->pBuffer; - - hp_packet_client->cur_hp = static_cast(CastToClient()->GetHP() - itembonuses.HP); - hp_packet_client->spawn_id = GetID(); - hp_packet_client->max_hp = CastToClient()->GetMaxHP() - itembonuses.HP; - - CastToClient()->QueuePacket(client_packet); - - safe_delete(client_packet); + static EQApplicationPacket p(OP_HPUpdate, sizeof(SpawnHPUpdate_Struct)); + auto b = (SpawnHPUpdate_Struct*) p.pBuffer; + b->cur_hp = static_cast(CastToClient()->GetHP() - itembonuses.HP); + b->spawn_id = GetID(); + b->max_hp = CastToClient()->GetMaxHP() - itembonuses.HP; + CastToClient()->QueuePacket(&p); ResetHPUpdateTimer(); @@ -3545,24 +3541,21 @@ void Mob::DoAnim(const int animation_id, int animation_speed, bool ackreq, eqFil return; } - auto outapp = new EQApplicationPacket(OP_Animation, sizeof(Animation_Struct)); - auto *a = (Animation_Struct *) outapp->pBuffer; - + static EQApplicationPacket p(OP_Animation, sizeof(Animation_Struct)); + auto a = (Animation_Struct*) p.pBuffer; a->spawnid = GetID(); a->action = animation_id; a->speed = animation_speed ? animation_speed : 10; entity_list.QueueCloseClients( this, /* Sender */ - outapp, /* Packet */ + &p, /* Packet */ false, /* Ignore Sender */ RuleI(Range, Anims), 0, /* Skip this mob */ ackreq, /* Packet ACK */ filter /* eqFilterType filter */ ); - - safe_delete(outapp); } void Mob::ShowBuffs(Client* c) { @@ -7725,28 +7718,26 @@ bool Mob::CanRaceEquipItem(uint32 item_id) void Mob::SendAddPlayerState(PlayerState new_state) { - auto app = new EQApplicationPacket(OP_PlayerStateAdd, sizeof(PlayerState_Struct)); - auto ps = (PlayerState_Struct *)app->pBuffer; + static EQApplicationPacket p(OP_PlayerStateAdd, sizeof(PlayerState_Struct)); + auto b = (PlayerState_Struct *) p.pBuffer; - ps->spawn_id = GetID(); - ps->state = static_cast(new_state); + b->spawn_id = GetID(); + b->state = static_cast(new_state); - AddPlayerState(ps->state); - entity_list.QueueClients(nullptr, app); - safe_delete(app); + AddPlayerState(b->state); + entity_list.QueueClients(nullptr, &p); } void Mob::SendRemovePlayerState(PlayerState old_state) { - auto app = new EQApplicationPacket(OP_PlayerStateRemove, sizeof(PlayerState_Struct)); - auto ps = (PlayerState_Struct *)app->pBuffer; + static EQApplicationPacket p(OP_PlayerStateRemove, sizeof(PlayerState_Struct)); + auto b = (PlayerState_Struct *) p.pBuffer; - ps->spawn_id = GetID(); - ps->state = static_cast(old_state); + b->spawn_id = GetID(); + b->state = static_cast(old_state); - RemovePlayerState(ps->state); - entity_list.QueueClients(nullptr, app); - safe_delete(app); + RemovePlayerState(b->state); + entity_list.QueueClients(nullptr, &p); } int32 Mob::GetMeleeMitigation() { diff --git a/zone/mob_movement_manager.cpp b/zone/mob_movement_manager.cpp index 661c046a1..ea0eb5ad2 100644 --- a/zone/mob_movement_manager.cpp +++ b/zone/mob_movement_manager.cpp @@ -824,8 +824,8 @@ void MobMovementManager::SendCommandToClients( return; } - EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - auto *spu = (PlayerPositionUpdateServer_Struct *) outapp.pBuffer; + static EQApplicationPacket p(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); + auto *spu = (PlayerPositionUpdateServer_Struct *) p.pBuffer; FillCommandStruct(spu, mob, delta_x, delta_y, delta_z, delta_heading, anim); @@ -862,7 +862,7 @@ void MobMovementManager::SendCommandToClients( } } - c->QueuePacket(&outapp, false); + c->QueuePacket(&p, false); c->m_last_seen_mob_position[mob->GetID()] = mob->GetPosition(); } } @@ -924,7 +924,7 @@ void MobMovementManager::SendCommandToClients( } } - c->QueuePacket(&outapp, false); + c->QueuePacket(&p, false); c->m_last_seen_mob_position[mob->GetID()] = mob->GetPosition(); } } diff --git a/zone/npc.cpp b/zone/npc.cpp index 7210dee79..0e3572858 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -3824,13 +3824,12 @@ int NPC::GetRolledItemCount(uint32 item_id) void NPC::SendPositionToClients() { - auto p = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - auto *s = (PlayerPositionUpdateServer_Struct *) p->pBuffer; + static EQApplicationPacket p(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); + auto *s = (PlayerPositionUpdateServer_Struct *) p.pBuffer; for (auto &c: entity_list.GetClientList()) { MakeSpawnUpdate(s); - c.second->QueuePacket(p, false); + c.second->QueuePacket(&p, false); } - safe_delete(p); } void NPC::HandleRoambox() diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index f71dbe31a..1e1e7c71c 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -533,6 +533,7 @@ bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList &spa ); spawn2_list.Insert(new_spawn); + new_spawn->Process(); } LogInfo("Loaded [{}] spawn2 entries", Strings::Commify(l.size())); diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 5bd2484b3..910298ce1 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -953,9 +953,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove auto action_packet = new EQApplicationPacket(OP_Action, sizeof(Action_Struct)); Action_Struct* action = (Action_Struct*) action_packet->pBuffer; - auto message_packet = - new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct)); - CombatDamage_Struct *cd = (CombatDamage_Struct *)message_packet->pBuffer; + + static EQApplicationPacket p(OP_Damage, sizeof(CombatDamage_Struct)); + auto cd = (CombatDamage_Struct *) p.pBuffer; action->target = GetID(); action->source = caster ? caster->GetID() : GetID(); @@ -978,16 +978,15 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove caster->CastToClient()->QueuePacket(action_packet); } - CastToClient()->QueuePacket(message_packet); + CastToClient()->QueuePacket(&p); if (caster && caster->IsClient() && caster != this) { - caster->CastToClient()->QueuePacket(message_packet); + caster->CastToClient()->QueuePacket(&p); } CastToClient()->SetBindPoint(spells[spell_id].base_value[i] - 1); Save(); safe_delete(action_packet); - safe_delete(message_packet); } else { if (!zone->CanBind()) { MessageString(Chat::SpellFailure, CANNOT_BIND); @@ -1002,9 +1001,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove auto action_packet = new EQApplicationPacket( OP_Action, sizeof(Action_Struct)); Action_Struct* action = (Action_Struct*) action_packet->pBuffer; - auto message_packet = new EQApplicationPacket( - OP_Damage, sizeof(CombatDamage_Struct)); - CombatDamage_Struct *cd = (CombatDamage_Struct *)message_packet->pBuffer; + + static EQApplicationPacket p(OP_Damage, sizeof(CombatDamage_Struct)); + auto cd = (CombatDamage_Struct *) p.pBuffer; action->target = GetID(); action->source = caster ? caster->GetID() : GetID(); @@ -1027,24 +1026,23 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove caster->CastToClient()->QueuePacket(action_packet); } - CastToClient()->QueuePacket(message_packet); + CastToClient()->QueuePacket(&p); if (caster->IsClient() && caster != this) { - caster->CastToClient()->QueuePacket(message_packet); + caster->CastToClient()->QueuePacket(&p); } CastToClient()->SetBindPoint(spells[spell_id].base_value[i] - 1); Save(); safe_delete(action_packet); - safe_delete(message_packet); } } else { auto action_packet = new EQApplicationPacket(OP_Action, sizeof(Action_Struct)); Action_Struct* action = (Action_Struct*) action_packet->pBuffer; - auto message_packet = new EQApplicationPacket( - OP_Damage, sizeof(CombatDamage_Struct)); - CombatDamage_Struct *cd = (CombatDamage_Struct *)message_packet->pBuffer; + + static EQApplicationPacket p(OP_Damage, sizeof(CombatDamage_Struct)); + auto cd = (CombatDamage_Struct *) p.pBuffer; action->target = GetID(); action->source = caster ? caster->GetID() : GetID(); @@ -1067,16 +1065,15 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove caster->CastToClient()->QueuePacket(action_packet); } - CastToClient()->QueuePacket(message_packet); + CastToClient()->QueuePacket(&p); if (caster->IsClient() && caster != this) { - caster->CastToClient()->QueuePacket(message_packet); + caster->CastToClient()->QueuePacket(&p); } CastToClient()->SetBindPoint(spells[spell_id].base_value[i] - 1); Save(); safe_delete(action_packet); - safe_delete(message_packet); } } } diff --git a/zone/spells.cpp b/zone/spells.cpp index 43ffbca1d..f845f6f04 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -4713,8 +4713,8 @@ bool Mob::SpellOnTarget( } } - message_packet = new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct)); - CombatDamage_Struct *cd = (CombatDamage_Struct *)message_packet->pBuffer; + static EQApplicationPacket p(OP_Damage, sizeof(CombatDamage_Struct)); + auto cd = (CombatDamage_Struct *) p.pBuffer; cd->target = action->target; cd->source = action->source; cd->type = action->type; @@ -4732,7 +4732,7 @@ bool Mob::SpellOnTarget( ) { entity_list.QueueCloseClients( spelltar, /* Sender */ - message_packet, /* Packet */ + &p, /* Packet */ false, /* Ignore Sender */ RuleI(Range, SpellMessages), 0, /* Skip this mob */ @@ -4742,7 +4742,6 @@ bool Mob::SpellOnTarget( } safe_delete(action_packet); - safe_delete(message_packet); /* Bug: When an HP buff with a heal effect is applied for first time, the heal portion of the effect heals the client and