Fix for unreliable packets (kind of a hack but it works) being flagged as corrupt

This commit is contained in:
KimLS 2017-03-20 00:22:50 -07:00
parent db210ba70e
commit cfdbca6f12
10 changed files with 56 additions and 61 deletions

View File

@ -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;
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;

View File

@ -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;

View File

@ -81,7 +81,10 @@ void EQ::Net::EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req)
break;
}
if (ack_req)
m_connection->QueuePacket(out);
else
m_connection->QueuePacket(out, 0, false);
}
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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)

View File

@ -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);
}

View File

@ -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;
}

View File

@ -435,7 +435,7 @@ int main(int argc, char** argv) {
std::unique_ptr<EQ::Net::EQStreamManager> eqsm;
std::chrono::time_point<std::chrono::system_clock> 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;

View File

@ -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;