Example #1
0
        public static void Handle(PacketReader packet, MapleClient c)
        {
            if (packet.Length >= 2)
            {
                if (ServerConstants.PrintPackets)
                {
                    ServerConsole.Info("Receiving: {0}", Functions.ByteArrayToStr(packet.ToArray()));
                }
                RecvHeader header = (RecvHeader)packet.ReadHeader();

                if (header <= RecvHeader.ErrorCode)
                {
                    switch (header)
                    {
                        #region Miscellaneous
                    case RecvHeader.ErrorCode:
                        ErrorCodeHandler.Handle(c, packet);
                        break;

                    case RecvHeader.BlackCipher:
                        BlackCipherHandler.Handle(packet.ReadInt(), c);
                        break;

                    case RecvHeader.HandShake:
                        ReceiveHandShakeHandler.Handle(c, packet);
                        break;

                    case RecvHeader.CrashReport:
                        break;

                    case RecvHeader.Pong:
                        PongHandler.Handle(c);
                        break;

                        #endregion
                        #region Login Server
                    case RecvHeader.EnteredLoginScreen:
                        EnteredLoginScreenHandler.Handle(c);
                        break;

                    case RecvHeader.ClientLoaded:
                        ClientLoadedHandler.Handle(c);
                        break;

                    case RecvHeader.ShowServerList:
                    case RecvHeader.ReShowServerList:
                        ServerlistRequestHandler.Handle(c);
                        break;

                    case RecvHeader.WorldSelect:
                        WorldSelectHandler.Handle(packet.ReadShort(), c);
                        break;

                    case RecvHeader.CheckCharacterName:
                        CheckCharnameHandler.Handle(c, packet.ReadMapleString());
                        break;

                    case RecvHeader.CreateCharacter:
                        CreateCharHandler.Handle(c, packet);
                        break;

                    case RecvHeader.DeleteCharacter:
                        DeleteCharacterHandler.Handle(c, packet);
                        break;

                    case RecvHeader.SetAccountPic:
                        SetAccountPicHandler.Handle(c, packet);
                        break;

                    case RecvHeader.ChooseCharacterWithPic:
                        ChooseCharWithPicHandler.Handle(c, packet);
                        break;

                    case RecvHeader.EnterMap:
                        CharacterLoginHandler.Handle(c, packet);
                        break;

                    case RecvHeader.AccountLogin:
                        LoginAccountHandler.Handle(c, packet);
                        break;

                    case RecvHeader.ChooseChannel:
                        ChooseChannelHandler.Handle(c, packet);
                        break;

                        #endregion
                    default:
#if DEBUG
                        ServerConsole.Debug("Unhandled recv packet: {0}", Functions.ByteArrayToStr(packet.ToArray()));
#endif
                        break;
                    }
                }
                else
                {
                    if (c.Account?.Character?.Map == null)
                    {
                        return;
                    }
                    switch (header)
                    {
                        #region GameServer
                    // Spam packets:
                    case RecvHeader.ClickDialog:
                    case RecvHeader.AttackSpam:
                    case RecvHeader.FinalPactEnd:
                        break;

                    case RecvHeader.PartyResponse:
                        PartyResponseHandler.Handle(c, packet);
                        break;

                    case RecvHeader.PartyOperation:
                        PartyHandler.Handle(c, packet);
                        break;

                    case RecvHeader.RequestRecommendedPartyMembers:
                        RecommendedPartyMembersHandler.Handle(c, packet);
                        break;

                    case RecvHeader.CharacterReceiveDamage:
                        CharacterReceiveDamage.Handle(c, packet);
                        break;

                    case RecvHeader.PlayerChat:
                        PlayerChatHandler.Handle(c, packet);
                        break;

                    case RecvHeader.SpecialChat:
                        SpecialChatHandler.Handle(c, packet);
                        break;

                    case RecvHeader.RequestWeeklyMapleStar:
                        WeeklyMapleStarHandler.Handle(c, packet);
                        return;

                    case RecvHeader.MoveCharacter:
                        MoveCharacterHandler.Handle(c, packet);
                        break;

                    case RecvHeader.EnterMapPortal:
                        EnterMapPortalHandler.Handle(c, packet);
                        break;

                    case RecvHeader.EnterDoor:
                        EnterDoorHandler.Handle(c, packet);
                        break;

                    case RecvHeader.MoveMob:
                        MoveMobHandler.Handle(c, packet);
                        break;

                    case RecvHeader.NpcChat:
                        NpcChatHandler.Handle(c, packet);
                        break;

                    case RecvHeader.NpcShopAction:
                        NpcShopActionHandler.Handle(c, packet);
                        break;

                    case RecvHeader.NpcAnimation:
                        NpcAnimationHandler.Handle(c, packet);
                        break;

                    case RecvHeader.NpcChatMore:
                        NpcChatMoreHandler.Handle(c, packet);
                        break;

                    case RecvHeader.FacialExpression:
                        FacialExpressionHandler.Handle(c, packet);
                        break;

                    case RecvHeader.MeleeAttack:
                        DealDamageHandler.HandleMelee(c, packet, header);
                        break;

                    case RecvHeader.RangedAttack:
                        DealDamageHandler.HandleRanged(c, packet);
                        break;

                    case RecvHeader.PassiveAttack:
                    case RecvHeader.MagicAttack:
                        DealDamageHandler.HandleMagic(c, packet);
                        break;

                    case RecvHeader.DistributeAp:
                        DistributeAPHandler.HandleSingle(c, packet);
                        break;

                    case RecvHeader.AutoAssignAp:
                        DistributeAPHandler.HandleDistribute(c, packet);
                        break;

                    case RecvHeader.DistributeSp:
                        DistributeSPHandler.Handle(c, packet);
                        break;

                    case RecvHeader.UseSkill:
                        UseSkillHandler.Handle(c, packet);
                        break;

                    case RecvHeader.MoveItem:
                        MoveItemHandler.Handle(c, packet);
                        break;

                    case RecvHeader.SlotMerge:
                        InventorySortHandler.HandleSlotMerge(c, packet);
                        break;

                    case RecvHeader.ItemSort:
                        InventorySortHandler.HandleItemSort(c, packet);
                        break;

                    case RecvHeader.ChangeChannel:
                        ChangeChannelHandler.Handle(c, packet);
                        break;

                    case RecvHeader.EnterCashShop:
                        EnterCSHandler.Handle(c, packet);
                        break;

                    case RecvHeader.AutoAggroMob:
                        AutoAggroHandler.Handle(c, packet);
                        break;

                    case RecvHeader.LootMapItem:
                        LootItemHandler.HandlePlayer(c, packet);
                        break;

                    case RecvHeader.RegenerateHpMp:
                        RegenerateHPMPHandler.Handle(c, packet);
                        break;

                    case RecvHeader.ChangeKeybind:
                        KeybindHandler.HandleKeyMapChange(c, packet);
                        break;

                    case RecvHeader.QuickSlotKeyMap:
                        KeybindHandler.HandleQuickSlotKeysChange(c, packet);
                        break;

                    case RecvHeader.CancelBuff:
                        CancelBuffHandler.Handle(c, packet);
                        break;

                    case RecvHeader.CharacterInfoRequest:
                        CharacterInfoRequest.Handle(c, packet);
                        break;

                    case RecvHeader.QuestAction:
                        QuestActionHandler.Handle(c, packet);
                        break;

                    case RecvHeader.EnterMapPortalSpecial:
                        EnterMapPortalSpecialHandler.Handle(c, packet);
                        break;

                    case RecvHeader.GuildAction:
                        GuildActionHandler.Handle(c, packet);
                        break;

                    case RecvHeader.DropMeso:
                        DropMesoHandler.Handle(c, packet);
                        break;

                    case RecvHeader.Trade:
                        TradeHandler.Handle(c, packet);
                        break;

                    case RecvHeader.UseConsumable:
                        UseItemHandler.Handle(c, packet);
                        break;

                    case RecvHeader.UseReturnScroll:
                        UseItemHandler.HandleReturnScroll(c, packet);
                        break;

                    case RecvHeader.UseEquipScroll:
                        UseScrollHandler.HandleRegularEquipScroll(c, packet);
                        break;

                    case RecvHeader.UseSpecialEquipScroll:
                        UseScrollHandler.HandleSpecialEquipScroll(c, packet);
                        break;

                    case RecvHeader.UseEquipEnhancementScroll:
                        UseScrollHandler.HandleEquipEnhancementScroll(c, packet);
                        break;

                    case RecvHeader.UseCashItem:
                        UseSpecialItemHandler.Handle(c, packet);
                        break;

                    case RecvHeader.UsePotentialScroll:
                        UseScrollHandler.HandlePotentialScroll(c, packet);
                        break;

                    case RecvHeader.UseBonusPotentialScroll:
                        UseScrollHandler.HandleBonusPotentialScroll(c, packet);
                        break;

                    case RecvHeader.UseCube:
                        UseScrollHandler.HandleCube(c, packet);
                        break;

                    case RecvHeader.UseMagnifyGlass:
                        UseMagnifyingGlassHandler.Handle(c, packet);
                        break;

                    case RecvHeader.SetSkillMacro:
                        SetSkillMacroHandler.Handle(c, packet);
                        break;

                    case RecvHeader.ProffesionReactorAction:
                        ProfessionReactorActionHandler.Handle(c, packet);
                        break;

                    case RecvHeader.ProffesionReactorDestroy:
                        ProfessionReactorActionHandler.HandleDestroy(c, packet);
                        break;

                    case RecvHeader.ReactorAction:
                        ReactorActionHandler.Handle(c, packet);
                        break;

                    case RecvHeader.CraftDone:
                        CraftHandler.HandleCraftDone(c, packet);
                        break;

                    case RecvHeader.CraftEffect:
                        CraftHandler.HandleCraftEffect(c, packet);
                        break;

                    case RecvHeader.CraftMake:
                        CraftHandler.HandleCraftMake(c, packet);
                        break;

                    case RecvHeader.CraftUnk:
                        CraftHandler.HandleUnk(c, packet);
                        break;

                    case RecvHeader.GainAranCombo:
                        AranComboHandler.HandleGain(c);
                        break;

                    case RecvHeader.DecayAranCombo:
                        AranComboHandler.HandleDecay(c);
                        break;

                    case RecvHeader.BlackBlessing:
                        BlackBlessingHandler.Handle(c);
                        break;

                    case RecvHeader.RequestHyperskillInfo:
                        HyperskillInfoRequestHandler.Handle(c, packet);
                        return;

                    case RecvHeader.SkillSwipe:
                        StealSkillHandler.HandleSkillSwipe(c, packet);
                        break;

                    case RecvHeader.ChooseStolenSkill:
                        StealSkillHandler.HandleChooseSkill(c, packet);
                        break;

                    case RecvHeader.StealSkill:
                        StealSkillHandler.HandleStealSkill(c, packet);
                        break;

                    case RecvHeader.MessengerOperation:
                        MapleMessengerHandler.Handle(c, packet);
                        break;

                    case RecvHeader.MoveSummon:
                        SummonHandler.HandleMove(c, packet);
                        break;

                    case RecvHeader.SummonAttack:
                        SummonHandler.HandleAttack(c, packet);
                        break;

                    case RecvHeader.SummonUseSkill:
                        SummonHandler.HandleSkill(c, packet);
                        break;

                    case RecvHeader.RemoveSummon:
                        SummonHandler.HandleRemove(c, packet);
                        break;

                    case RecvHeader.FindPlayer:
                        FindPlayerHandler.Handle(c, packet);
                        break;

                    case RecvHeader.BuddyOperation:
                        BuddyOperationHandler.Handle(c, packet);
                        break;

                    case RecvHeader.UseGoldenHammer:
                        UseGoldenHammerHandler.Handle(c, packet);
                        break;

                        #endregion
                        #region CashShop
                    case RecvHeader.CashshopSelect:
                        CashShop.Select(c, packet);
                        break;

                        #endregion
                    default:
#if DEBUG
                        ServerConsole.Debug("Unhandled recv packet: {0}", Functions.ByteArrayToStr(packet.ToArray()));
#endif
                        c.Account.Character.EnableActions();
                        break;
                    }
                }
            }
        }
        public static bool CheckAndApplySkillEffect(MapleCharacter chr, int skillId, WzCharacterSkill wzCharacterSkill, int skillLevel = -1, int numTargets = 0, int numAttacks = 0)
        {
            if (skillLevel == -1)
            {
                skillLevel = chr.GetSkillLevel(skillId);
            }

            if (wzCharacterSkill == null)
            {
                wzCharacterSkill = DataBuffer.GetCharacterSkillById(skillId);
                if (wzCharacterSkill == null)
                {
                    return(false);
                }
            }

            if (wzCharacterSkill.HasFixedLevel && JobConstants.JobCanLearnSkill(skillId, chr.Job))
            {
                skillLevel = 1;
            }

            if (chr.IsPhantom) //check stolen skill level
            {
                PhantomSystem resource         = (PhantomSystem)chr.Resource;
                int           chosenSkillIndex = resource.GetChosenSkillIndex(skillId);
                if (chosenSkillIndex > -1)
                {
                    int impeccableMemory = PhantomSystem.GetStealSkill(chosenSkillIndex + 1);
                    skillLevel = Math.Min(chr.GetSkillLevel(impeccableMemory), chr.GetSkillLevel(skillId));
                }
            }


            if (skillLevel == 0 || (chr.HasSkillOnCooldown(skillId)))
            {
                string text = "Player tried using skill " + skillId + " while level 0 or on cooldown.";
                ServerConsole.Warning(text);
                FileLogging.Log("./LinkedSkills.txt", text);
                return(false);
            }

            SkillEffect effect = wzCharacterSkill.GetEffect((byte)skillLevel);

            if (effect == null)
            {
                return(false);
            }

            bool shadowPartner = false;

            if (numTargets > 0)
            {
                int attackCount = effect.AttackCount;
                if (chr.IsLuminous ||
                    (chr.IsBandit && chr.HasBuff(ChiefBandit.SHADOW_PARTNER)) ||
                    (chr.IsAssassin && chr.HasBuff(Hermit.SHADOW_PARTNER)) ||
                    (chr.IsNightWalker && chr.HasBuff(NightWalker3.SHADOW_PARTNER)))
                {
                    attackCount  *= 2;
                    shadowPartner = true;
                }
                if (effect.MobCount < numTargets || attackCount < numAttacks)
                {
                    return(false);
                }
            }

            int bulletConsume;

            if (effect.Info.TryGetValue(CharacterSkillStat.bulletConsume, out bulletConsume))
            {
                if (shadowPartner)
                {
                    bulletConsume *= 2;
                }
                if (!DealDamageHandler.HandleRangedAttackAmmoUsage(chr, bulletConsume))
                {
                    ServerConsole.Warning("Character with job: " + chr.Job + " tried using a skill with bulletCount: " + bulletConsume + " but doesn't have the bullets!");
                    return(false);
                }
            }

            if (chr.Mp < effect.MpCon)
            {
                return(false);
            }
            else
            {
                chr.AddMP(-effect.MpCon);
            }

            int hpCon;

            if (effect.Info.TryGetValue(CharacterSkillStat.hpCon, out hpCon))
            {
                if (chr.Hp < hpCon)
                {
                    return(false);
                }
                chr.AddHP(-hpCon);
            }

            #region Manual skill handlers and checks
            if (chr.IsAran && effect.Info.ContainsKey(CharacterSkillStat.aranComboCon))
            {
                if (!AranSystem.HandleComboUsage(chr, effect.Info[CharacterSkillStat.aranComboCon]))
                {
                    return(false);
                }
            }
            else if (chr.IsLuminous && chr.Job >= JobConstants.LUMINOUS2 && effect.Info.ContainsKey(CharacterSkillStat.gauge))
            {
                LuminousSystem.HandleGaugeGain(chr, skillId, effect.Info[CharacterSkillStat.gauge]);
            }

            switch (skillId)
            {
            case Berserker.EVIL_EYE_OF_DOMINATION:
            {
                Buff        evilEyeBuff = chr.GetBuff(Spearman.EVIL_EYE);
                MapleSummon evilEye     = chr.GetSummon(Spearman.EVIL_EYE);
                if (evilEyeBuff == null || evilEye == null)
                {
                    return(false);
                }
                uint timeUsed        = (uint)((DateTime.UtcNow.Subtract(evilEyeBuff.StartTime)).TotalMilliseconds);
                uint timeRemainingMS = (uint)evilEyeBuff.Duration - timeUsed;
                Buff newBuff         = new Buff(Spearman.EVIL_EYE, effect, timeRemainingMS, chr);
                if (evilEyeBuff.Stacks == Berserker.EVIL_EYE_OF_DOMINATION)
                {
                    newBuff.Stacks       = Spearman.EVIL_EYE;
                    evilEye.MovementType = SummonMovementType.Follow;
                }
                else
                {
                    newBuff.Stacks       = Berserker.EVIL_EYE_OF_DOMINATION;
                    evilEye.MovementType = SummonMovementType.CircleFollow;
                }
                chr.GiveBuff(newBuff);
                return(true);    //no other actions needed
            }

            case Berserker.EVIL_EYE_SHOCK:
            {
                MapleSummon evilEye = chr.GetSummon(Spearman.EVIL_EYE);
                if (evilEye == null)
                {
                    return(false);
                }
                List <MapleMonster> mobs = chr.Map.GetMobsInRange(new BoundingBox(evilEye.Position, wzCharacterSkill.TopLeft, wzCharacterSkill.BottomRight));
                if (mobs.Count > 0)
                {
                    int damage     = (int)((effect.Info[CharacterSkillStat.damage] / 100.0) * chr.Stats.GetDamage());
                    int stunProp   = effect.Info[CharacterSkillStat.prop];
                    int stunTime   = effect.Info[CharacterSkillStat.time] * 1000;
                    int mobCounter = 0;
                    foreach (MapleMonster mob in mobs)
                    {
                        mob.Damage(chr, damage);
                        if (mob.Alive)
                        {
                            if (Functions.MakeChance(stunProp))
                            {
                                mob.ApplyStatusEffect(skillId, MonsterBuffStat.STUN, 1, stunTime, chr);
                            }
                        }
                        mobCounter++;
                        if (mobCounter == 10)
                        {
                            break;
                        }
                    }
                }
                break;
            }

            case DarkKnight.SACRIFICE:
                if (!chr.RemoveSummon(Spearman.EVIL_EYE))
                {
                    return(false);
                }
                chr.CancelBuff(Spearman.EVIL_EYE);
                int healHpR = effect.Info[CharacterSkillStat.y];
                int heal    = (int)((healHpR / 100.0) * chr.Stats.MaxHp);
                chr.AddHP(heal);
                break;

            case LuminousBasics.SUNFIRE:
            case LuminousBasics.ECLIPSE:
            case LuminousBasics.EQUILIBRIUM2:
                LuminousSystem.HandleChangeDarkLight(chr, skillId);
                break;
            }
            #endregion

            #region Apply Cooldown

            bool skipCooldown = skillId == DarkKnight.GUNGNIRS_DESCENT && (chr.HasBuff(DarkKnight.SACRIFICE) || chr.HasBuff(DarkKnight.FINAL_PACT2));

            if (!skipCooldown)
            {
                int coolTime;
                if (effect.Info.TryGetValue(CharacterSkillStat.cooltime, out coolTime) && coolTime > 0)
                {
                    chr.AddCooldown(skillId, (uint)coolTime * 1000); //time in the wz is in seconds
                }
            }
            #endregion

            effect.ApplyEffect(chr, chr);

            if (wzCharacterSkill.IsBuff)
            {
                effect.ApplyBuffEffect(chr);
                chr.Map.BroadcastPacket(SkillEffect.Packets.ShowForeignSkillEffect(chr.Id, chr.Level, skillId, effect.Level), chr);
            }

            if (wzCharacterSkill.IsPartySkill)
            {
                if (chr.Party != null)
                {
                    List <MapleCharacter> partyMembersOnSameMap = chr.Party.GetCharactersOnMap(chr.Map, chr.Id);
                    if (partyMembersOnSameMap.Count > 0)
                    {
                        List <MapleCharacter> partyMembersInRange = chr.Map.GetCharactersInRange(effect.CalculateBoundingBox(chr.Position, chr.IsFacingLeft), partyMembersOnSameMap);
                        foreach (MapleCharacter partyMember in partyMembersInRange)
                        {
                            effect.ApplyEffect(chr, partyMember);
                            if (wzCharacterSkill.IsBuff)
                            {
                                effect.ApplyBuffEffect(partyMember);
                            }
                        }
                    }
                }
                else if (wzCharacterSkill.IsGmSkill && chr.IsStaff)
                {
                    var targets = chr.Map.GetCharactersInRange(effect.CalculateBoundingBox(chr.Position, chr.IsFacingLeft));
                    foreach (MapleCharacter target in targets.Where(x => x.Id != chr.Id))
                    {
                        effect.ApplyEffect(chr, target);
                        if (wzCharacterSkill.IsBuff)
                        {
                            effect.ApplyBuffEffect(target);
                        }
                    }
                }
            }
            return(true);
        }