From cfdbca6f12c3bd80fbb0b02ff5825e13eec432cf Mon Sep 17 00:00:00 2001 From: KimLS Date: Mon, 20 Mar 2017 00:22:50 -0700 Subject: [PATCH] Fix for unreliable packets (kind of a hack but it works) being flagged as corrupt --- common/net/daybreak_connection.cpp | 18 ++++++++++++-- common/net/daybreak_connection.h | 4 ++-- common/net/eqstream.cpp | 5 +++- zone/attack.cpp | 2 +- zone/client.cpp | 2 +- zone/merc.cpp | 4 ++-- zone/mob.cpp | 2 +- zone/mob_ai.cpp | 38 +++++++----------------------- zone/net.cpp | 4 ++-- zone/special_attacks.cpp | 38 +++++++++++++++--------------- 10 files changed, 56 insertions(+), 61 deletions(-) diff --git a/common/net/daybreak_connection.cpp b/common/net/daybreak_connection.cpp index 3e668c549..2b86bb301 100644 --- a/common/net/daybreak_connection.cpp +++ b/common/net/daybreak_connection.cpp @@ -837,6 +837,11 @@ bool EQ::Net::DaybreakConnection::PacketCanBeEncoded(Packet &p) const return false; } + auto zero = p.GetInt8(0); + if (zero != 0) { + return true; + } + auto opcode = p.GetInt8(1); if (opcode == OP_SessionRequest || opcode == OP_SessionResponse || opcode == OP_OutOfSession) { return false; @@ -1177,7 +1182,16 @@ void EQ::Net::DaybreakConnection::InternalSend(Packet &p) if (PacketCanBeEncoded(p)) { DynamicPacket out; - out.PutPacket(0, p); + + if (p.GetUInt8(0) != 0) { + out.PutUInt8(0, 0); + out.PutUInt8(1, OP_Combined); + out.PutUInt8(2, p.Length()); + out.PutPacket(3, p); + } + else { + out.PutPacket(0, p); + } for (int i = 0; i < 2; ++i) { switch (m_encode_passes[i]) { @@ -1242,7 +1256,7 @@ void EQ::Net::DaybreakConnection::InternalSend(Packet &p) void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id, bool reliable) { if (!reliable) { - auto max_raw_size = m_max_packet_size - m_crc_bytes; + auto max_raw_size = 0xFFU - m_crc_bytes; if (p.Length() > max_raw_size) { InternalQueuePacket(p, stream_id, true); return; diff --git a/common/net/daybreak_connection.h b/common/net/daybreak_connection.h index c874411a8..782a23fd2 100644 --- a/common/net/daybreak_connection.h +++ b/common/net/daybreak_connection.h @@ -221,8 +221,8 @@ namespace EQ encode_passes[0] = DaybreakEncodeType::EncodeNone; encode_passes[1] = DaybreakEncodeType::EncodeNone; port = 0; - hold_size = 384; - hold_length_ms = 10; + hold_size = 448; + hold_length_ms = 25; simulated_in_packet_loss = 0; simulated_out_packet_loss = 0; tic_rate_hertz = 60.0; diff --git a/common/net/eqstream.cpp b/common/net/eqstream.cpp index a366fe1a2..6d02fdd57 100644 --- a/common/net/eqstream.cpp +++ b/common/net/eqstream.cpp @@ -81,7 +81,10 @@ void EQ::Net::EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req) break; } - m_connection->QueuePacket(out); + if (ack_req) + m_connection->QueuePacket(out); + else + m_connection->QueuePacket(out, 0, false); } } diff --git a/zone/attack.cpp b/zone/attack.cpp index 01e1a13e4..58b3e9541 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -136,7 +136,7 @@ bool Mob::AttackAnimation(EQEmu::skills::SkillType &skillinuse, int Hand, const if (Hand == EQEmu::inventory::slotSecondary) // DW anim type = animDualWield; - DoAnim(type); + DoAnim(type, 0, false); return true; } diff --git a/zone/client.cpp b/zone/client.cpp index 2146337bc..5146d7cb1 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -8647,7 +8647,7 @@ void Client::QuestReward(Mob* target, uint32 copper, uint32 silver, uint32 gold, if (exp > 0) AddEXP(exp); - QueuePacket(outapp, false, Client::CLIENT_CONNECTED); + QueuePacket(outapp, true, Client::CLIENT_CONNECTED); safe_delete(outapp); } diff --git a/zone/merc.cpp b/zone/merc.cpp index 5f8ea59ea..0f04d5b6f 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -4484,7 +4484,7 @@ void Merc::DoClassAttacks(Mob *target) { if(level >= RuleI(Combat, NPCBashKickLevel)){ if(zone->random.Int(0, 100) > 25) //tested on live, warrior mobs both kick and bash, kick about 75% of the time, casting doesn't seem to make a difference. { - DoAnim(animKick); + DoAnim(animKick, 0, false); int32 dmg = GetBaseSkillDamage(EQEmu::skills::SkillKick); if (GetWeaponDamage(target, (const EQEmu::ItemData*)nullptr) <= 0) @@ -4496,7 +4496,7 @@ void Merc::DoClassAttacks(Mob *target) { } else { - DoAnim(animTailRake); + DoAnim(animTailRake, 0, false); int32 dmg = GetBaseSkillDamage(EQEmu::skills::SkillBash); if (GetWeaponDamage(target, (const EQEmu::ItemData*)nullptr) <= 0) diff --git a/zone/mob.cpp b/zone/mob.cpp index cc76519fa..f73c42ef1 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2131,7 +2131,7 @@ void Mob::SendTargetable(bool on, Client *specific_target) { entity_list.QueueClients(this, outapp); } else if (specific_target->IsClient()) { - specific_target->CastToClient()->QueuePacket(outapp, false); + specific_target->CastToClient()->QueuePacket(outapp); } safe_delete(outapp); } diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index f6e6fa019..f46008519 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -345,7 +345,7 @@ bool NPC::AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgain } bool EntityList::AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float iRange, uint32 iSpellTypes) { - if((iSpellTypes&SpellTypes_Detrimental) != 0) { + if((iSpellTypes & SpellTypes_Detrimental) != 0) { //according to live, you can buff and heal through walls... //now with PCs, this only applies if you can TARGET the target, but // according to Rogean, Live NPCs will just cast through walls/floors, no problem.. @@ -374,41 +374,19 @@ bool EntityList::AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float float iRange2 = iRange*iRange; - float t1, t2, t3; - - //Only iterate through NPCs for (auto it = npc_list.begin(); it != npc_list.end(); ++it) { NPC* mob = it->second; - - //Since >90% of mobs will always be out of range, try to - //catch them with simple bounding box checks first. These - //checks are about 6X faster than DistNoRoot on my athlon 1Ghz - t1 = mob->GetX() - caster->GetX(); - t2 = mob->GetY() - caster->GetY(); - t3 = mob->GetZ() - caster->GetZ(); - //cheap ABS() - if(t1 < 0) - t1 = 0 - t1; - if(t2 < 0) - t2 = 0 - t2; - if(t3 < 0) - t3 = 0 - t3; - if (t1 > iRange - || t2 > iRange - || t3 > iRange - || DistanceSquared(mob->GetPosition(), caster->GetPosition()) > iRange2 - //this call should seem backwards: - || !mob->CheckLosFN(caster) - || mob->GetReverseFactionCon(caster) >= FACTION_KINDLY - ) { + + if (mob->GetReverseFactionCon(caster) >= FACTION_KINDLY) { continue; } - //since we assume these are beneficial spells, which do not - //require LOS, we just go for it. - // we have a winner! - if((iSpellTypes & SpellType_Buff) && !RuleB(NPC, BuffFriends)){ + if (DistanceSquared(caster->GetPosition(), mob->GetPosition()) > iRange2) { + continue; + } + + if ((iSpellTypes & SpellType_Buff) && !RuleB(NPC, BuffFriends)) { if (mob != caster) iSpellTypes = SpellType_Heal; } diff --git a/zone/net.cpp b/zone/net.cpp index 5e581a63f..3b5768d8b 100644 --- a/zone/net.cpp +++ b/zone/net.cpp @@ -435,7 +435,7 @@ int main(int argc, char** argv) { std::unique_ptr eqsm; std::chrono::time_point frame_prev = std::chrono::system_clock::now(); - EQ::Timer process_timer(15, true, [&](EQ::Timer* t) { + EQ::Timer process_timer(32, true, [&](EQ::Timer* t) { //Advance the timer to our current point in time Timer::SetCurrentTime(); @@ -447,7 +447,7 @@ int main(int argc, char** argv) { if (!eqsf_open && Config->ZonePort != 0) { Log.Out(Logs::General, Logs::Zone_Server, "Starting EQ Network server on port %d", Config->ZonePort); - EQ::Net::EQStreamManagerOptions opts(Config->ZonePort, false, false); + EQ::Net::EQStreamManagerOptions opts(Config->ZonePort, false, true); eqsm.reset(new EQ::Net::EQStreamManager(opts)); eqsf_open = true; diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index 1d40eae55..42d53026c 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -302,7 +302,7 @@ void Client::OPCombatAbility(const CombatAbility_Struct *ca_atk) if (GetTarget() != this) { CheckIncreaseSkill(EQEmu::skills::SkillBash, GetTarget(), 10); - DoAnim(animTailRake); + DoAnim(animTailRake, 0, false); int32 ht = 0; if (GetWeaponDamage(GetTarget(), GetInv().GetItem(EQEmu::inventory::slotSecondary)) <= 0 && @@ -324,7 +324,7 @@ void Client::OPCombatAbility(const CombatAbility_Struct *ca_atk) CheckIncreaseSkill(EQEmu::skills::SkillFrenzy, GetTarget(), 10); int AtkRounds = 1; int32 max_dmg = GetBaseSkillDamage(EQEmu::skills::SkillFrenzy, GetTarget()); - DoAnim(anim2HSlashing); + DoAnim(anim2HSlashing, 0, false); max_dmg = mod_frenzy_damage(max_dmg); @@ -359,7 +359,7 @@ void Client::OPCombatAbility(const CombatAbility_Struct *ca_atk) break; if (GetTarget() != this) { CheckIncreaseSkill(EQEmu::skills::SkillKick, GetTarget(), 10); - DoAnim(animKick); + DoAnim(animKick, 0, false); int32 ht = 0; if (GetWeaponDamage(GetTarget(), GetInv().GetItem(EQEmu::inventory::slotFeet)) <= 0) @@ -452,40 +452,40 @@ int Mob::MonkSpecialAttack(Mob *other, uint8 unchecked_type) skill_type = EQEmu::skills::SkillFlyingKick; max_dmg = GetBaseSkillDamage(skill_type); min_dmg = 0; // revamped FK formula is missing the min mod? - DoAnim(animFlyingKick); + DoAnim(animFlyingKick, 0, false); reuse = FlyingKickReuseTime; break; case EQEmu::skills::SkillDragonPunch: skill_type = EQEmu::skills::SkillDragonPunch; max_dmg = GetBaseSkillDamage(skill_type); itemslot = EQEmu::inventory::slotHands; - DoAnim(animTailRake); + DoAnim(animTailRake, 0, false); reuse = TailRakeReuseTime; break; case EQEmu::skills::SkillEagleStrike: skill_type = EQEmu::skills::SkillEagleStrike; max_dmg = GetBaseSkillDamage(skill_type); itemslot = EQEmu::inventory::slotHands; - DoAnim(animEagleStrike); + DoAnim(animEagleStrike, 0, false); reuse = EagleStrikeReuseTime; break; case EQEmu::skills::SkillTigerClaw: skill_type = EQEmu::skills::SkillTigerClaw; max_dmg = GetBaseSkillDamage(skill_type); itemslot = EQEmu::inventory::slotHands; - DoAnim(animTigerClaw); + DoAnim(animTigerClaw, 0, false); reuse = TigerClawReuseTime; break; case EQEmu::skills::SkillRoundKick: skill_type = EQEmu::skills::SkillRoundKick; max_dmg = GetBaseSkillDamage(skill_type); - DoAnim(animRoundKick); + DoAnim(animRoundKick, 0, false); reuse = RoundKickReuseTime; break; case EQEmu::skills::SkillKick: skill_type = EQEmu::skills::SkillKick; max_dmg = GetBaseSkillDamage(skill_type); - DoAnim(animKick); + DoAnim(animKick, 0, false); reuse = KickReuseTime; break; default: @@ -604,7 +604,7 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime) hate = base_damage; DoSpecialAttackDamage(other, EQEmu::skills::SkillBackstab, base_damage, 0, hate, ReuseTime); - DoAnim(anim1HPiercing); + DoAnim(anim1HPiercing, 0, false); } // assassinate [No longer used for regular assassinate 6-29-14] @@ -617,7 +617,7 @@ void Mob::RogueAssassinate(Mob* other) }else{ other->Damage(this, -5, SPELL_UNKNOWN, EQEmu::skills::SkillBackstab); } - DoAnim(anim1HPiercing); //piercing animation + DoAnim(anim1HPiercing, 0, false); //piercing animation } void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { @@ -1595,7 +1595,7 @@ void NPC::DoClassAttacks(Mob *target) { case WARRIOR: case WARRIORGM:{ if(level >= RuleI(Combat, NPCBashKickLevel)){ if(zone->random.Roll(75)) { //tested on live, warrior mobs both kick and bash, kick about 75% of the time, casting doesn't seem to make a difference. - DoAnim(animKick); + DoAnim(animKick, 0, false); int32 dmg = GetBaseSkillDamage(EQEmu::skills::SkillKick); if (GetWeaponDamage(target, (const EQEmu::ItemData*)nullptr) <= 0) @@ -1606,7 +1606,7 @@ void NPC::DoClassAttacks(Mob *target) { did_attack = true; } else { - DoAnim(animTailRake); + DoAnim(animTailRake, 0, false); int32 dmg = GetBaseSkillDamage(EQEmu::skills::SkillBash); if (GetWeaponDamage(target, (const EQEmu::ItemData*)nullptr) <= 0) @@ -1622,7 +1622,7 @@ void NPC::DoClassAttacks(Mob *target) { case BERSERKER: case BERSERKERGM:{ int AtkRounds = 1; int32 max_dmg = GetBaseSkillDamage(EQEmu::skills::SkillFrenzy); - DoAnim(anim2HSlashing); + DoAnim(anim2HSlashing, 0, false); if (GetClass() == BERSERKER) { int chance = GetLevel() * 2 + GetSkill(EQEmu::skills::SkillFrenzy); @@ -1645,7 +1645,7 @@ void NPC::DoClassAttacks(Mob *target) { case BEASTLORD: case BEASTLORDGM: { //kick if(level >= RuleI(Combat, NPCBashKickLevel)){ - DoAnim(animKick); + DoAnim(animKick, 0, false); int32 dmg = GetBaseSkillDamage(EQEmu::skills::SkillKick); if (GetWeaponDamage(target, (const EQEmu::ItemData*)nullptr) <= 0) @@ -1661,7 +1661,7 @@ void NPC::DoClassAttacks(Mob *target) { case SHADOWKNIGHT: case SHADOWKNIGHTGM: case PALADIN: case PALADINGM:{ if(level >= RuleI(Combat, NPCBashKickLevel)){ - DoAnim(animTailRake); + DoAnim(animTailRake, 0, false); int32 dmg = GetBaseSkillDamage(EQEmu::skills::SkillBash); if (GetWeaponDamage(target, (const EQEmu::ItemData*)nullptr) <= 0) @@ -1760,7 +1760,7 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte) if (skill_to_use == EQEmu::skills::SkillBash) { if (ca_target!=this) { - DoAnim(animTailRake); + DoAnim(animTailRake, 0, false); if (GetWeaponDamage(ca_target, GetInv().GetItem(EQEmu::inventory::slotSecondary)) <= 0 && GetWeaponDamage(ca_target, GetInv().GetItem(EQEmu::inventory::slotShoulders)) <= 0) dmg = DMG_INVULNERABLE; @@ -1779,7 +1779,7 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte) if (skill_to_use == EQEmu::skills::SkillFrenzy) { CheckIncreaseSkill(EQEmu::skills::SkillFrenzy, GetTarget(), 10); int AtkRounds = 1; - DoAnim(anim2HSlashing); + DoAnim(anim2HSlashing, 0, false); ReuseTime = (FrenzyReuseTime - 1) / HasteMod; @@ -1806,7 +1806,7 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte) if (skill_to_use == EQEmu::skills::SkillKick){ if(ca_target!=this){ - DoAnim(animKick); + DoAnim(animKick, 0, false); if (GetWeaponDamage(ca_target, GetInv().GetItem(EQEmu::inventory::slotFeet)) <= 0) dmg = DMG_INVULNERABLE;