Example #1
0
        public static void ApplyAttack(AttackInfo attack, MapleCharacter player, int maxDamagePerMonster,
                                       int attackCount)
        {
            //应用攻击
            player.AntiCheatTracker.ResetHpRegen();
            //player.resetAfkTimer();
            player.AntiCheatTracker.CheckAttack(attack.Skill);

            ISkill          theSkill     = null;
            MapleStatEffect attackEffect = null;

            if (attack.Skill != 0)
            {
                theSkill     = SkillFactory.GetSkill(attack.Skill);
                attackEffect = attack.GetAttackEffect(player, theSkill);
                if (attackEffect == null)
                {
                    AutobanManager.Instance.Autoban(player.Client, $"使用了没有的技能ID:{attack.Skill}");
                }
                else if (attack.Skill != 2301002)
                {
                    if (player.IsAlive)
                    {
                        attackEffect.ApplyTo(player);
                    }
                    else
                    {
                        player.Client.Send(PacketCreator.EnableActions());
                    }
                }
            }

            if (!player.IsAlive)
            {
                player.AntiCheatTracker.RegisterOffense(CheatingOffense.AttackingWhileDead);
                return;
            }

            if (attackCount != attack.NumDamage && attack.Skill != 4211006 && attack.NumDamage != attackCount * 2)
            {
                player.AntiCheatTracker.RegisterOffense(CheatingOffense.MismatchingBulletcount,
                                                        attack.NumDamage + "/" + attackCount);
                return;
            }

            var totDamage = 0;
            var map       = player.Map;

            if (attack.Skill == 4211006)
            {
                // meso explosion
                long delay = 0;
                foreach (var oned in attack.AllDamage)
                {
                    var mapobject = map.Mapobjects[oned.Item1];
                    if (mapobject != null && mapobject.GetType() == MapleMapObjectType.Item)
                    {
                        var mapitem = (MapleMapItem)mapobject;
                        if (mapitem.Meso > 0)
                        {
                            lock (mapitem)
                            {
                                if (mapitem.IsPickedUp)
                                {
                                    return;
                                }
                                TimerManager.Instance.RunOnceTask(() =>
                                {
                                    map.RemoveMapObject(mapitem);
                                    map.BroadcastMessage(PacketCreator.RemoveItemFromMap(mapitem.ObjectId, 4, 0),
                                                         mapitem.Position);
                                    mapitem.IsPickedUp = true;
                                }, delay);
                                delay += 100;
                            }
                        }
                        else if (mapitem.Meso == 0)
                        {
                            player.AntiCheatTracker.RegisterOffense(CheatingOffense.EtcExplosion);
                            return;
                        }
                    }
                    else if (mapobject != null && mapobject.GetType() != MapleMapObjectType.Monster)
                    {
                        player.AntiCheatTracker.RegisterOffense(CheatingOffense.ExplodingNonexistant);
                        return; // etc explosion, exploding nonexistant things, etc.
                    }
                }
            }

            foreach (var oned in attack.AllDamage)
            {
                var monster = map.GetMonsterByOid(oned.Item1);

                if (monster != null)
                {
                    var totDamageToOneMonster = 0;
                    foreach (var eachd in oned.Item2)
                    {
                        totDamageToOneMonster += eachd;
                    }
                    totDamage += totDamageToOneMonster;


                    player.CheckMonsterAggro(monster);
                    if (totDamageToOneMonster > attack.NumDamage + 1)
                    {
                        var dmgCheck = player.AntiCheatTracker.CheckDamage(totDamageToOneMonster);
                        if (dmgCheck > 5 && totDamageToOneMonster < 99999 && monster.Id < 9500317 &&
                            monster.Id > 9500319)
                        {
                            player.AntiCheatTracker
                            .RegisterOffense(CheatingOffense.SameDamage,
                                             dmgCheck + " times: " + totDamageToOneMonster);
                        }
                    }
                    // �?测单次攻击�?�,这里不会�?!
                    if (player.IsGm || player.Job == MapleJob.Ares && player.Level <= 10)
                    {
                        //log.info("这里不进行操�?");
                    }
                    else
                    {
                        if (player.Level < 10)
                        {
                            if (totDamageToOneMonster > 10000)
                            {
                                AutobanManager.Instance.BroadcastMessage(player.Client,
                                                                         player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " +
                                                                         player.Level + ")");
                                //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")");
                                return;
                            }
                        }
                        if (player.Level < 20)
                        {
                            if (totDamageToOneMonster > 20000)
                            {
                                AutobanManager.Instance.BroadcastMessage(player.Client,
                                                                         player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " +
                                                                         player.Level + ")");
                                //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")");
                                return;
                            }
                        }
                        if (player.Level < 30)
                        {
                            if (totDamageToOneMonster > 30000)
                            {
                                AutobanManager.Instance.BroadcastMessage(player.Client,
                                                                         player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " +
                                                                         player.Level + ")");
                                //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")");
                                return;
                            }
                        }
                        if (player.Level < 50)
                        {
                            if (totDamageToOneMonster > 50000)
                            {
                                AutobanManager.Instance.BroadcastMessage(player.Client,
                                                                         player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " +
                                                                         player.Level + ")");
                                //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")");
                                return;
                            }
                        }
                        if (player.Level < 70)
                        {
                            if (totDamageToOneMonster > 150000)
                            {
                                AutobanManager.Instance.BroadcastMessage(player.Client,
                                                                         player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " +
                                                                         player.Level + ")");
                                //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")");
                                return;
                            }
                        }
                        if (player.Level < 150)
                        {
                            if (totDamageToOneMonster > 350000)
                            {
                                AutobanManager.Instance.BroadcastMessage(player.Client,
                                                                         player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " +
                                                                         player.Level + ")");
                                //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")");
                                return;
                            }
                        }
                    }

                    CheckHighDamage(player, monster, attack, theSkill, attackEffect, totDamageToOneMonster,
                                    maxDamagePerMonster);
                    var distance = player.Position.DistanceSquare(monster.Position);
                    if (distance > 400000.0)
                    {
                        // 600^2, 550 is approximatly the range of ultis
                        player.AntiCheatTracker.RegisterOffense(CheatingOffense.AttackFarawayMonster,
                                                                Math.Sqrt(distance).ToString(CultureInfo.InvariantCulture));
                    } //遥远的�?�物袭击

                    if (attack.Skill == 5111004)
                    {
                        // 能量转换
                        var edrain = SkillFactory.GetSkill(5111004);
                        var gainhp = (int)
                                     (totDamage * (double)edrain.GetEffect(player.GetSkillLevel(edrain)).X / 100.0);
                        gainhp     = Math.Min(monster.MaxHp, Math.Min(gainhp, player.MaxHp / 2));
                        player.Hp += (short)gainhp;
                    }
                    else if (attack.Skill == 15100004)
                    {
                        //光�?�拳
                        var edrain = SkillFactory.GetSkill(15100004);
                        var gainhp = (int)
                                     (totDamage * (double)edrain.GetEffect(player.GetSkillLevel(edrain)).X / 100.0);
                        gainhp     = Math.Min(monster.MaxHp, Math.Min(gainhp, player.MaxHp / 2));
                        player.Hp += (short)gainhp;
                    }

                    if (!monster.ControllerHasAggro)
                    {
                        if (monster.GetController() == player)
                        {
                            monster.ControllerHasAggro = true;
                        }
                        else
                        {
                            monster.SwitchController(player, true);
                        }
                    }
                    if (attack.Skill == 2301002 && !monster.Stats.IsUndead)
                    {
                        player.AntiCheatTracker.RegisterOffense(CheatingOffense.HealAttackingUndead); //医治攻击亡灵
                        return;
                    }
                    // Pickpocket
                    if ((attack.Skill == 4001334 || attack.Skill == 4201005 || attack.Skill == 0 ||
                         attack.Skill == 4211002 || attack.Skill == 4211004) &&
                        player.GetBuffedValue(MapleBuffStat.Pickpocket) != null)
                    {
                        HandlePickPocket(player, monster, oned);
                    }
                    if (attack.Skill == 21100005)
                    {
                        // 生命吸收21100005
                        var drain  = SkillFactory.GetSkill(21100005);
                        var gainhp =
                            (int)
                            (totDamageToOneMonster *
                             (double)drain.GetEffect(player.GetSkillLevel(drain)).X / 100.0);
                        gainhp     = Math.Min(monster.MaxHp, Math.Min(gainhp, player.MaxHp / 2));
                        player.Hp += (short)gainhp;
                    }
                    if (attack.Skill == 4101005)
                    {
                        // 生命吸收21100005
                        var drain  = SkillFactory.GetSkill(4101005);
                        var gainhp =
                            (int)
                            (totDamageToOneMonster *
                             (double)drain.GetEffect(player.GetSkillLevel(drain)).X / 100.0);
                        gainhp     = Math.Min(monster.MaxHp, Math.Min(gainhp, player.MaxHp / 2));
                        player.Hp += (short)gainhp;
                    }
                    if (attack.Skill == 14101006)
                    {
                        // 吸血
                        var drain  = SkillFactory.GetSkill(14101006);
                        var gainhp =
                            (int)
                            (totDamageToOneMonster *
                             (double)drain.GetEffect(player.GetSkillLevel(drain)).X / 100.0);
                        gainhp     = Math.Min(monster.MaxHp, Math.Min(gainhp, player.MaxHp / 2));
                        player.Hp += (short)gainhp;
                    }
                    if (player.GetBuffedValue(MapleBuffStat.Hamstring) != null)
                    {
                        var hamstring = SkillFactory.GetSkill(3121007); //降低速度的击�?�?
                        if (hamstring.GetEffect(player.GetSkillLevel(hamstring)).MakeChanceResult())
                        {
                            var monsterStatusEffect =
                                new MonsterStatusEffect(
                                    new Dictionary <MonsterStatus, int>
                            {
                                {
                                    MonsterStatus.Speed,
                                    hamstring.GetEffect(player.GetSkillLevel(hamstring)).X
                                }
                            }, hamstring, false);
                            monster.ApplyStatus(player, monsterStatusEffect, false,
                                                hamstring.GetEffect(player.GetSkillLevel(hamstring)).Y *1000);
                        }
                    }

                    if (player.GetBuffedValue(MapleBuffStat.Blind) != null)
                    {
                        //刺眼�?
                        var blind = SkillFactory.GetSkill(3221006);
                        if (blind.GetEffect(player.GetSkillLevel(blind)).MakeChanceResult())
                        {
                            var monsterStatusEffect =
                                new MonsterStatusEffect(
                                    new Dictionary <MonsterStatus, int>
                            {
                                {
                                    MonsterStatus.Acc,
                                    blind.GetEffect(player.GetSkillLevel(blind)).X
                                }
                            }
                                    , blind, false);
                            monster.ApplyStatus(player, monsterStatusEffect, false,
                                                blind.GetEffect(player.GetSkillLevel(blind)).Y *1000);
                        }
                    }

                    if (player.Job == MapleJob.Whiteknight)
                    {
                        int[] charges = { 1211005, 1211006 }; //寒冰钝器
                        foreach (var charge in charges)
                        {
                            var chargeSkill = SkillFactory.GetSkill(charge);

                            if (player.IsBuffFrom(MapleBuffStat.WkCharge, chargeSkill))
                            {
                                var iceEffectiveness = monster.GetEffectiveness(Element.Ice);
                                if (totDamageToOneMonster > 0 && iceEffectiveness == ElementalEffectiveness.Normal ||
                                    iceEffectiveness == ElementalEffectiveness.Weak)
                                {
                                    var chargeEffect =
                                        chargeSkill.GetEffect(player.GetSkillLevel(chargeSkill));
                                    var monsterStatusEffect =
                                        new MonsterStatusEffect(
                                            new Dictionary <MonsterStatus, int> {
                                        { MonsterStatus.Freeze, 1 }
                                    },
                                            chargeSkill, false);
                                    monster.ApplyStatus(player, monsterStatusEffect, false, chargeEffect.Y * 2000);
                                }
                                break;
                            }
                        }
                    }
                    var venomNl = SkillFactory.GetSkill(4120005); //武器用毒�?
                    if (player.GetSkillLevel(venomNl) <= 0)
                    {
                        venomNl = SkillFactory.GetSkill(14110004); //武器用毒�?
                    }
                    var venomShadower = SkillFactory.GetSkill(4220005);
                    if (player.GetSkillLevel(venomNl) > 0)
                    {
                        var venomEffect = venomNl.GetEffect(player.GetSkillLevel(venomNl));
                        for (var i = 0; i < attackCount; i++)
                        {
                            if (venomEffect.MakeChanceResult())
                            {
                                if (monster.VenomMultiplier < 3)
                                {
                                    monster.VenomMultiplier += 1;
                                    var monsterStatusEffect =
                                        new MonsterStatusEffect(
                                            new Dictionary <MonsterStatus, int> {
                                        { MonsterStatus.Poison, 1 }
                                    },
                                            venomNl, false);
                                    monster.ApplyStatus(player, monsterStatusEffect, false, venomEffect.Duration,
                                                        true);
                                }
                            }
                        }
                    }
                    else if (player.GetSkillLevel(venomShadower) > 0)
                    {
                        var venomEffect = venomShadower.GetEffect(player.GetSkillLevel(venomShadower));
                        for (var i = 0; i < attackCount; i++)
                        {
                            if (venomEffect.MakeChanceResult())
                            {
                                if (monster.VenomMultiplier < 3)
                                {
                                    monster.VenomMultiplier += 1;
                                    var monsterStatusEffect =
                                        new MonsterStatusEffect(
                                            new Dictionary <MonsterStatus, int> {
                                        { MonsterStatus.Poison, 1 }
                                    },
                                            venomShadower, false);
                                    monster.ApplyStatus(player, monsterStatusEffect, false, venomEffect.Duration,
                                                        true);
                                }
                            }
                        }
                    }
                    if (totDamageToOneMonster > 0 && attackEffect != null && attackEffect.MonsterStatus.Any())
                    {
                        if (attackEffect.MakeChanceResult())
                        {
                            var monsterStatusEffect =
                                new MonsterStatusEffect(attackEffect.MonsterStatus, theSkill, false);
                            monster.ApplyStatus(player, monsterStatusEffect, attackEffect.IsPoison(),
                                                attackEffect.Duration);
                        }
                    }
                    if (attack.IsHh && !monster.IsBoss)
                    {
                        map.DamageMonster(player, monster, monster.Hp - 1);
                    }
                    else if (attack.IsHh && monster.IsBoss)
                    {
                        var weaponItem = player.Inventorys[MapleInventoryType.Equipped.Value].Inventory[0xF5]; //装备
                        MapleItemInformationProvider.Instance.GetWeaponType(weaponItem.ItemId);
                    }
                    else
                    {
                        map.DamageMonster(player, monster, totDamageToOneMonster);
                    }
                }
            }
            if (totDamage > 1)
            {
                player.AntiCheatTracker.SetAttacksWithoutHit(player.AntiCheatTracker.GetAttacksWithoutHit() + 1);
                int offenseLimit;
                if (attack.Skill != 3121004)
                {
                    //暴风箭雨
                    offenseLimit = 100;
                }
                else
                {
                    offenseLimit = 300;
                }
                if (player.AntiCheatTracker.GetAttacksWithoutHit() > offenseLimit)
                {
                    player.AntiCheatTracker
                    .RegisterOffense(CheatingOffense.AttackWithoutGettingHit,
                                     player.AntiCheatTracker.GetAttacksWithoutHit().ToString());
                }
                //没有受到撞击攻击
                //if (player.hasEnergyCharge())
                //{
                //    player.increaseEnergyCharge(attack.numAttacked);
                //}
            }
        }