public static void Handle(int nSkillID, byte nSLV, Character c, CInPacket p)
        {
            //COutPacket::COutPacket(&oPacket, 103);
            //v33 = 1;
            //v15 = get_update_time();
            //COutPacket::Encode4(&oPacket, v15);
            //COutPacket::Encode4(&oPacket, pSkill->nSkillID);
            //v16 = nSLV;
            //COutPacket::Encode1(&oPacket, nSLV);
            //v17 = (unsigned __int16 *)((int(__thiscall *)(IVecCtrlOwnerVtbl * *, ZRef < CharacterData > *))v3->vfptr->GetPos)(
            //                               &v3->vfptr,
            //                               &result);
            //COutPacket::Encode2(&oPacket, *v17);
            //v18 = ((int(__thiscall *)(IVecCtrlOwnerVtbl * *, char *))v3->vfptr->GetPos)(&v3->vfptr, &v31);
            //COutPacket::Encode2(&oPacket, *(_WORD*)(v18 + 4));
            //CClientSocket::SendPacket(TSingleton < CClientSocket >::ms_pInstance, &oPacket);

            // position of aura?
            var x = p.Decode2();
            var y = p.Decode2();

            var bLeft = x < c.Position.X;

            c.Skills.Cast(nSkillID, bLeft);
        }
예제 #2
0
        public static void Handle(int nSkillID, byte nSLV, Character c, CInPacket p)
        {
            // Recv [CP_UserSkillUseRequest] [67 00] [D0 B3 75 10] [A6 C7 C9 01] [01] [C0 F7 8D 00] [39 FE] [DF FF] [00]

            //COutPacket::COutPacket(&oPacket, 103);
            //v50 = 3;
            //v36 = get_update_time();
            //COutPacket::Encode4(&oPacket, v36);
            //COutPacket::Encode4(&oPacket, pSkill->nSkillID);
            //COutPacket::Encode1(&oPacket, nSLV);
            //COutPacket::Encode4(&oPacket, (unsigned int)cd);
            //COutPacket::Encode2(&oPacket, pt.x);
            //COutPacket::Encode2(&oPacket, pt.y);
            //COutPacket::Encode1(&oPacket, bLeft);
            //CClientSocket::SendPacket(TSingleton < CClientSocket >::ms_pInstance, &oPacket);

            var dwMobID = p.Decode4();
            var ptX     = p.Decode2();
            var ptY     = p.Decode2();
            var bLeft   = p.Decode1() > 0;

            if (c.Skills.Cast(nSkillID, bLeft))
            {
                new UserEffectPacket(UserEffect.SkillUse)
                {
                    nSkillID = nSkillID,
                    nSLV     = nSLV,
                    bLeft    = bLeft,
                    ptX      = ptX,
                    ptY      = ptY,
                }.BroadcastEffect(c, false);

                // TODO spawn monster lol
            }
        }
예제 #3
0
        private void Handle_UserChangeSlotPositionRequest(WvsGameClient c, CInPacket p)
        {
            var tick     = p.Decode4();
            var type     = p.Decode1(); // inventory
            var src      = p.Decode2();
            var dst      = p.Decode2();
            var quantity = p.Decode2();

            Logger.Write(LogLevel.Debug, "UserChangeSlotPositionRequest Src {0}, Dst {1} Type {2} Qty {3}", src, dst, type, quantity);

            if (src < 0 && dst > 0)
            {
                CInventoryManipulator.UnEquip(c, src, dst); //check
            }
            else if (dst < 0)
            {
                CInventoryManipulator.Equip(c, src, dst); //check
            }
            else if (dst == 0)
            {
                CInventoryManipulator.Drop(c, type, src, quantity);
            }
            else
            {
                CInventoryManipulator.Move(c, type, src, dst); //check
            }
        }
예제 #4
0
        private void Handle_UserSelectNpc(WvsGameClient c, CInPacket p)
        {
            var dwNpcId = p.Decode4();
            var nPosX   = p.Decode2();
            var nPosY   = p.Decode2();

            if (c.NpcScript != null)
            {
                Logger.Write(LogLevel.Warning, "Npc script already in progress?");
            }

            var field = c.GetCharField();
            var npc   = field.Npcs.Get(dwNpcId);

            if (npc != null)
            {
                //if (npc.hasShop())
                //{
                //    chr.setConversation(1);
                //    npc.sendShop(c);
                //}
                //else
                {
                    c.NpcScript = NpcScript.GetScript(npc.Id, c);
                    c.NpcScript.Execute();
                }
            }
            else
            {
                Logger.Write(LogLevel.Warning, "Unable to find NPC {0}", dwNpcId);
            }
        }
예제 #5
0
        public static TagPoint DecodePos(this CInPacket packet)
        {
            var x = packet.Decode2();
            var y = packet.Decode2();

            return(new TagPoint(x, y));
        }
예제 #6
0
        private void Handle_UserTransferFieldRequest(WvsGameClient c, CInPacket p)
        {
            if (p.Available == 0)
            {
                //Cash Shop Related
                return;
            }

            //TODO: Portal count checks
            //TODO: XY rect checks
            //TODO: Keep track if player spawns when entering a field

            var portalCount = p.Decode1(); //CField::GetFieldKey(v20);
            var destination = p.Decode4(); //
            var portalName  = p.DecodeString();
            var x           = p.Decode2();
            var y           = p.Decode2();
            //var extra = p.DecodeBuffer(3); idk | prem | chase

            var portal =
                c.GetCharField()
                .Portals
                .GetByName(portalName);

            if (portal == null)
            {
                Logger.Write(LogLevel.Warning, "Client tried to enter non existant portal {0}", portalName);
            }
            else
            {
                c.UsePortal(portal);
            }
        }
예제 #7
0
        public static void Handle(int nSkillID, byte nSLV, Character c, CInPacket p)
        {
            //COutPacket::COutPacket(&oPacket, 103);
            //v30 = 1;
            //v21 = get_update_time();
            //COutPacket::Encode4(&oPacket, v21);
            //COutPacket::Encode4(&oPacket, pSkill->nSkillID);
            //COutPacket::Encode1(&oPacket, v16);
            //v22 = (unsigned __int16 *)(*(int(__thiscall * *)(int, char *))(*(_DWORD*)v10 + 16))(v10, &v28);
            //COutPacket::Encode2(&oPacket, *v22);
            //v23 = (*(int(__thiscall * *)(int, CUserLocal * *))(*(_DWORD*)v10 + 16))(v10, &v24);
            //COutPacket::Encode2(&oPacket, *(_WORD*)(v23 + 4));
            //CClientSocket::SendPacket(TSingleton < CClientSocket >::ms_pInstance, &oPacket);

            var x = p.Decode2();
            var y = p.Decode2();

            var bLeft = x < c.Position.X;

            if (c.Skills.Cast(nSkillID, bLeft, true)) // todo handle this skill
            {
                var cGate = new COpenGate(c.dwId)
                {
                    Position = new CMovePath {
                        X = x, Y = y
                    }                                                             // TODO distance check
                };

                var gate1 = c.Field.OpenGates1[c.dwId];
                var gate2 = c.Field.OpenGates2[c.dwId];

                if (gate1 is null)
                {
                    c.Field.OpenGates1.Add(cGate);
                }
                else if (gate2 is null)
                {
                    c.Field.OpenGates2.Add(cGate);
                }
                else if (gate1.StartTime > gate2.StartTime)
                {
                    c.Field.OpenGates2.Remove(cGate.dwCharacterID);
                    c.Field.OpenGates2.Add(cGate);
                }
                else
                {
                    c.Field.OpenGates1.Remove(cGate.dwCharacterID);
                    c.Field.OpenGates1.Add(cGate);
                }

                new UserEffectPacket(Common.Types.UserEffect.SkillUse)
                {
                    nSkillID = nSkillID,
                    nSLV     = nSLV,
                    bLeft    = (c.Position.MoveAction & 1) != 0
                }.BroadcastEffect(c, false);
            }
        }
예제 #8
0
        public void OpenGate(CInPacket p)
        {
            var field = Parent.Field;

            var dwOwnerID = p.Decode4();
            var nX        = p.Decode2();
            var nY        = p.Decode2();
            var bFirst    = p.Decode1() != 0;

            (bFirst ? field.OpenGates1 : field.OpenGates2)
            .OnOpenGate(Parent, dwOwnerID);

            Enable();
        }
        public static void Handle(int nSkillID, byte nSLV, Character c, CInPacket p)
        {
            //      COutPacket::COutPacket(&oPacket, 103);
            //v36 = 2;
            //v25 = get_update_time();
            //      COutPacket::Encode4(&oPacket, v25);
            //COutPacket::Encode4(&oPacket, pSkill->nSkillID);
            //COutPacket::Encode1(&oPacket, v20);
            //v26 = (unsigned __int16 *)(*(int (__thiscall**) (int, char*))(*(_DWORD*) v15 + 16))(v15, &v34);
            //COutPacket::Encode2(&oPacket, *v26);
            //v27 = (*(int (__thiscall**) (int, CUserLocal**))(*(_DWORD*) v15 + 16))(v15, &v30);
            //COutPacket::Encode2(&oPacket, *(_WORD*) (v27 + 4));
            //CClientSocket::SendPacket(TSingleton<CClientSocket>::ms_pInstance, &oPacket);

            var x = p.Decode2();
            var y = p.Decode2();

            if (c.Field.Template.Town)
            {
                return;
            }
            if (c.Field.MapId / 1000000 % 100 == 9)
            {
                return;
            }
            if (c.Field.Template.HasMysticDoorLimit())
            {
                return;
            }

            return;             // TODO fix this f*****g shit

            if (!c.Skills.Cast(nSkillID, true, true))
            {
                return;
            }

            c.Field.TownPortals.CreateTownPortal(c, nSkillID, x, y, Math.Min(120 * 1000, 20 * nSLV * 1000)); // TODO get time value from skill

            c.Party?.BroadcastLoadParty();                                                                   // TODO send the proper packet instead of this whole thing

            new UserEffectPacket(Common.Types.UserEffect.SkillUse)
            {
                nSkillID = nSkillID,
                nSLV     = nSLV,
                bLeft    = (c.Position.MoveAction & 1) != 0
            }.BroadcastEffect(c, false);
        }
        public static void Handle(int nSkillID, byte nSLV, Character character, CInPacket p)
        {
            //          COutPacket::COutPacket(&oPacket, 103);
            //          LOBYTE(v37) = 2;
            //          v23 = get_update_time();
            //          COutPacket::Encode4(&oPacket, v23);
            //          COutPacket::Encode4(&oPacket, pSkill->nSkillID);
            //          COutPacket::Encode1(&oPacket, nSLV);
            //          v24 = adwUserID.a;
            //          if (adwUserID.a)
            //              v25 = *(adwUserID.a - 1);
            //          else
            //              LOBYTE(v25) = 0;
            //          COutPacket::Encode1(&oPacket, v25);
            //          v26 = 0;
            //          if (ZArray < unsigned long>::GetCount(&adwUserID) )
            //{
            //              do
            //                  COutPacket::Encode4(&oPacket, v24[v26++]);
            //              while (v26 < ZArray < unsigned long>::GetCount(&adwUserID) );
            //          }
            //          COutPacket::Encode2(&oPacket, (unsigned __int16)cd);
            //          CClientSocket::SendPacket(TSingleton < CClientSocket >::ms_pInstance, &oPacket);

            var v25 = p.Decode1();

            var ZArray = p.DecodeIntArray(v25);

            var cd = p.Decode2();
        }
예제 #11
0
        private void DecodeAttackInfo(CInPacket p)
        {
            for (int i = 0; i < nMobCount; i++)
            {
                var info = new AttackEntry();

                info.dwMobID = p.Decode4();

                info.nHitAction  = p.Decode1();
                info.nForeAction = p.Decode1();                //  COutPacket::Encode1(&v468, v376->nForeAction & 0x7F | (v181 << 7));
                info.nFrameIdx   = p.Decode1();

                // v218 = CMob::GetCurTemplate(v378->pMob)
                //    && (v166 = CMob::GetTemplate(v378->pMob), v166 != CMob::GetCurTemplate(v378->pMob));
                // v167 = (_BYTE)v218 << 7;

                info.CalcDamageStatIndex = p.Decode1(); // COutPacket::Encode1(&v460, v168 & 0x7F | v167);

                p.Skip(8);                              // position info

                info.tDelay = p.Decode2();

                for (int j = 0; j < nDamagePerMob; j++)
                {
                    info.aDamage[j] = Math.Max(0, p.Decode4());

                    //Log.Debug($"[Damaging Mob] dwMobID: {info.dwMobID} aDamage: {info.aDamage[j]}");
                }

                p.Skip(4);                 // CMob::GetCrc

                aAttackInfo[i] = info;
            }
        }
예제 #12
0
        public static void Handle_UserShopRequest(WvsGameClient c, CInPacket p)
        {
            if (c.ActiveShop is null)
            {
                c.Character.SendMessage("Unable to find active shop. Please re-open the shop or report this to staff.");
                return;
            }

            switch ((ShopReq)p.Decode1())             // nOperation
            {
            case ShopReq.Buy:
            {
                var nPos         = p.Decode2();                         //Item index within the npc shop lol
                var dwTemplateID = p.Decode4();
                var nCount       = p.Decode2();

                BuyItem(c.Character, nPos, dwTemplateID, nCount);
                break;
            }

            case ShopReq.Sell:
            {
                var nSlot        = p.Decode2();                          //Item inventory index
                var dwTemplateID = p.Decode4();
                var nCount       = p.Decode2();

                SellItem(c.Character, nSlot, dwTemplateID, nCount);

                break;
            }

            case ShopReq.Recharge:
            {
                var nSlot = p.Decode2();

                RechargeItem(c.Character, nSlot);
                break;
            }

            case ShopReq.Close:
            {
                Close(c.Character);
                break;
            }
            }
        }
예제 #13
0
        /**
         * Die packet:
         * Recv [CP_UserTransferFieldRequest] [29 00] [01] [00 00 00 00] 00 00 00 01 00 // last bytes possibly related to death-items
         * Portal to other map packet:
         * Recv [CP_UserTransferFieldRequest] [29 00] [01] [FF FF FF FF] [06 00] [65 61 73 74 30 30] [4D 06] [C7 01] 00 00 00
         */
        public static void Field(WvsGameClient c, CInPacket p)
        {
            //void __thiscall CUser::OnTransferFieldRequest(CUser *this, int bLoopback, CInPacket *iPacket)

            //Exit Cash Shop -> Not used in WvsGame
            if (p.Available == 0)
            {
                return;
            }

            //TODO: Portal count checks
            //TODO: XY rect checks to ensure player is on portal when activating it
            //TODO: Keep track if player spawns when entering a field

            var bFieldKey   = p.Decode1();           //CField::GetFieldKey(v20);
            var dwField     = p.Decode4();
            var sPortalName = p.DecodeString();

            if (c.Character.Stats.nHP <= 0)
            {
                c.Character.Field.OnUserWarpDie(c.Character);
            }
            else if (sPortalName.Length > 0)                // not death
            {
                var x = p.Decode2();
                var y = p.Decode2();

                p.Decode1();                 // used to be bTownPortal
                var bPremium = p.Decode1();
                var bChase   = p.Decode1();

                if (bChase > 0)
                {
                    var nTargetPosition_X = p.Decode4();
                    var nTargetPosition_Y = p.Decode4();
                }

                c.Character.Field.OnUserEnterPortal(c.Character, sPortalName);
            }
            else             // gm warp command
            {
                // TODO admin checks
                // tp to desired field
            }
        }
예제 #14
0
        public void HandleAddItem(CInPacket p, Character pChar)
        {
            if (dwFirstLockerId == pChar.dwId || !acceptedInvite)
            {
                return;
            }

            var nTI         = (InventoryType)p.Decode1();
            var nCurInvSlot = p.Decode2(); // in inventory
            var nCount      = p.Decode2();
            var nTargetSlot = p.Decode1(); // in trade window

            var pItem = InventoryManipulator.GetItem(pChar, nTI, nCurInvSlot);

            var tempInv = GetTempInv(pChar);

            if (pItem is null || !tempInv.CanAddToSlot(nTargetSlot))
            {
                return;
            }

            if (ItemConstants.is_treat_singly(pItem.nItemID))
            {
                nCount = -1; // negative amount clears the slot
            }
            else
            {
                nCount = Math.Min(pItem.nNumber, Math.Abs(nCount));
            }

            InventoryManipulator.RemoveFrom(pChar, nTI, nCurInvSlot, nCount);

            if (pItem is GW_ItemSlotBundle pBundle && !pBundle.IsRechargeable)
            {
                pItem         = pItem.DeepCopy();
                pItem.nNumber = nCount;
            }

            var pTempItem = new TempItem(pItem, nCurInvSlot, nTargetSlot);

            tempInv.Add(pTempItem);

            Parent.SendPacket(AddItemPacket(pTempItem, !IsOwner(pChar)));
            Partner.SendPacket(AddItemPacket(pTempItem, IsOwner(pChar)));
        }
예제 #15
0
        private void Handle_CheckUserLimit(WvsLoginClient c, CInPacket p)
        {
            var nWorldID = p.Decode2();

            if (nWorldID == 0) //Scania
            {
                c.SendPacket(CPacket.CLogin.CheckUserLimit(0));
            }
        }
예제 #16
0
        // all movement update handlers should be calling this from now on
        public int UpdateMovePath(COutPacket oPacket, CInPacket iPacket)
        {
            X  = iPacket.Decode2();            //ZtlSecureTear_m_x
            Y  = iPacket.Decode2();            //ZtlSecureTear_m_y
            VX = iPacket.Decode2();            //ZtlSecureTear_m_vx
            VY = iPacket.Decode2();            //ZtlSecureTear_m_vy

            oPacket.Encode2(X);
            oPacket.Encode2(Y);
            oPacket.Encode2(VX);
            oPacket.Encode2(VY);

            var elems = DecodePath(iPacket);

            EncodePath(oPacket, elems);

            return(elems.Length);
        }
예제 #17
0
        //-----------------------------------------------------------------------------
        private void Handle_ClientDumpLog(WvsLoginClient c, CInPacket p)
        {
            //Thank you to Mordred for this handler!

            var callType         = p.Decode2();
            var errorCode        = p.Decode4();
            var backupBufferSize = p.Decode2();
            var rawSeq           = p.Decode4();
            var type             = p.Decode2();
            var backupBuffer     = p.DecodeBuffer(backupBufferSize - 6);

            var callTypeName = Enum.GetName(typeof(CrashCallType), callType);
            var logTypeName  = Enum.GetName(typeof(SendOps), type);

            Logger.Write(LogLevel.Trace,
                         "RawSeq: {0} CallType: {1} ErrorCode: {2} BackupBufferSize: {3} Type: {4} - {5} Packet: {6}",
                         rawSeq, callTypeName, errorCode, backupBufferSize,
                         type, logTypeName,
                         Constants.GetString(backupBuffer)
                         );
        }
예제 #18
0
        public void AddItem(CInPacket p)
        {
            var nTI             = (InventoryType)p.Decode1();
            var nPOS            = p.Decode2();
            var nBundles        = Math.Max((short)1, p.Decode2());
            var nPricePerBundle = Math.Max((short)1, p.Decode2());
            var nPrice          = Math.Max(1, p.Decode4());

            var pItem = InventoryManipulator.GetItem(Parent, nTI, nPOS);

            if (pItem is null)
            {
                Parent.SendMessage("item is null u fucc");
                return;
            }

            var nQuantityRequested = -1; // negative so its removed completely from inventory

            if (!ItemConstants.is_treat_singly(pItem.nItemID))
            {
                nQuantityRequested = nBundles * nPricePerBundle;

                if (pItem.nNumber < nQuantityRequested)
                {
                    return; // f*****g retard
                }
            }

            InventoryManipulator.RemoveFrom(Parent, nTI, nPOS, (short)nQuantityRequested);
            Inventory.Add(new TempItem(pItem, nPrice, nPricePerBundle, nBundles));

            Refresh(Parent);

            Parent.SendMessage($"Bundles: {nBundles}, PricePerBundle: {nPricePerBundle}, Price: {nPrice}");

            // TODO packet editing checks
        }
예제 #19
0
        public void Handle(TClient c, CInPacket p)
        {
            var opCode = p.Decode2();

            if (m_handlers.TryGetValue(opCode, out var handler))
            {
                if (handler.RequireLogin && !c.LoggedIn)
                {
                    c.Disconnect();
                }
                else
                {
                    handler.Handler(c, p);
                }
            }
        }
예제 #20
0
        public void Hit(Character c, CInPacket p)
        {
            // CReactorPool::FindHitReactor
            // CReactorPool::FindSkillReactor

            var bSkillReactor = p.Decode4() != 0;

            if (bSkillReactor)
            {
                return;                            // TODO handle this
            }
            var dwHitOption  = p.Decode4();        // v4->dwHitOption = v13 & 1 | 2 * CUser::IsOnFoothold(v3);
            var tActionDelay = p.Decode2();
            var nSkillID     = p.Decode4();        // for skill reactors?? idk yet

            OnHitReactor(c, tActionDelay, 0);      // TODO event idx
        }
예제 #21
0
        private void Handle_CashShopCheckCouponRequest(WvsShopClient c, CInPacket p)
        {
            p.Decode2();             // something

            var code = p.DecodeString();

            var coupon = new CouponCode(code, c);

            if (coupon.Invalid)
            {
                c.SendPacket(CPacket.CCashShop.CouponFail(CashItemFailed.InvalidCoupon));
            }
            else if (coupon.Used)
            {
                c.SendPacket(CPacket.CCashShop.CouponFail(CashItemFailed.UsedCoupon));
            }
            else if (coupon.IncorrectAccount)
            {
                c.SendPacket(CPacket.CCashShop.CouponFail(CashItemFailed.NotAvailableCoupon));
            }
            else if (coupon.Expired)
            {
                c.SendPacket(CPacket.CCashShop.CouponFail(CashItemFailed.ExpiredCoupon));
            }
            else if (coupon.Items != null && !InventoryManipulator.HasSpace(c.Character, coupon.Items))
            {
                c.SendPacket(CPacket.CCashShop.CouponFail(CashItemFailed.NoEmptyPos));                 // TODO fix this
            }
            else
            {
                if (coupon.Items != null)
                {
                    foreach (var item in coupon.Items)
                    {
                        InventoryManipulator.InsertInto(c.Character, MasterManager.CreateItem(item, false));
                        CPacket.CCashShop.CouponAddItem(item);
                    }
                }

                c.Account.AccountData.NX_Prepaid += coupon.NX;
                coupon.Dispose();
                c.Account.Save();
            }

            c.EnableActions();
        }
        // note: uses another header (0x69) than regular skill req (0x67)
        public static void Handle(WvsGameClient c, CInPacket p)
        {
            //COutPacket::COutPacket(&oPacket, 105);
            //v71 = 10;
            //COutPacket::Encode4(&oPacket, v5);
            //COutPacket::Encode1(&oPacket, nSLV);
            //COutPacket::Encode2(&oPacket, v4->m_nOneTimeAction & 0x7FFF | ((unsigned __int16)v4->m_nMoveAction << 15));
            //COutPacket::Encode1(&oPacket, v57);
            //if (v5 == 33101005)
            //    COutPacket::Encode4(&oPacket, v4->m_dwSwallowMobID);
            //CClientSocket::SendPacket(TSingleton < CClientSocket >::ms_pInstance, &oPacket);

            var nSkillID     = p.Decode4();
            var nSLV         = p.Decode1();
            var nMoveAction  = p.Decode2();
            var nActionSpeed = p.Decode1();

            var pSkill = c.Character.Skills.Get(nSkillID, true);

            if (pSkill is null)
            {
                return;
            }

            if (nSkillID == (int)Skills.WILDHUNTER_SWALLOW)
            {
                var dwSwallowMobId = p.Decode4();

                var pMob = c.Character.Field.Mobs[dwSwallowMobId];

                if (pMob is object && !GameConstants.is_not_swallowable_mob(pMob.nMobTemplateId))
                {
                    if (!pMob.TrySwallowMob(c.Character))
                    {
                        return;
                    }
                }
            }

            c.Character.Field.Broadcast(UserSkillPrepare(c.Character.dwId, nSkillID, pSkill.nSLV, nMoveAction, nActionSpeed), c);
        }
예제 #23
0
        public static void Handle(int nSkillID, byte nSLV, Character character, CInPacket p)
        {
            //COutPacket::COutPacket(&oPacket, 0x67);
            //v24 = 0;
            //v13 = get_update_time();
            //COutPacket::Encode4(&oPacket, v13);
            //COutPacket::Encode4(&oPacket, v9->nSkillID);
            //v14 = nSLV;
            //COutPacket::Encode1(&oPacket, nSLV);
            //v15 = CUserLocal::FindParty(v3, v9, v14, &nCount);
            //COutPacket::Encode1(&oPacket, v15);
            //COutPacket::Encode2(&oPacket, 0);
            //CWvsContext::SetExclRequestSent(pCtx, 1);
            //CClientSocket::SendPacket(TSingleton < CClientSocket >::ms_pInstance, &oPacket);

            var nCount    = p.Decode1(); // we arent really interested in this rn
            var zeroshort = p.Decode2(); // unused??

            // character.Skills.Cast(nSkillID, false);
            // two packets are sent from cleric heal: SkillUseRequest and MagicAttack
            // since we cast the spell from the attack handler we dont need to process it again here
        }
예제 #24
0
        private void Handle_MobMove(WvsGameClient c, CInPacket p)
        {
            int dwMobId = p.Decode4();

            var nMobCtrlSN = p.Decode2();
            var v7         = p.Decode1();               //v85 = nDistance | 4 * (v184 | 2 * ((unsigned __int8)retaddr | 2 * v72)); [ CONFIRMED ]

            var pOldSplit           = (v7 & 0xF0) != 0; //this is a type of CFieldSplit
            var bMobMoveStartResult = (v7 & 0xF) != 0;

            var pCurSplit         = p.Decode1();
            var bIllegealVelocity = p.Decode4();
            var v8 = p.Decode1();

            var bCheatedRandom   = (v8 & 0xF0) != 0;
            var bCheatedCtrlMove = (v8 & 0xF) != 0;

            p.Decode4(); //Loopy Decode 1
            p.Decode4(); //Loopy Decode 2

            p.DecodeBuffer(16);

            var movePath = p.DecodeBuffer(p.Available);

            //if (pMob->m_pController->pUser != pCtrl
            //    && (!pOldSplit
            //        || pMob->m_bNextAttackPossible
            //        || !CLifePool::ChangeMobController(&v5->m_lifePool, pCtrl->m_dwCharacterID, pMob, 1)))
            //{
            //    CMob::SendChangeControllerPacket(v9, v10, 0);
            //    return;
            //}

            c.SendPacket(CPacket.MobMoveAck(dwMobId, nMobCtrlSN, bMobMoveStartResult, 0, 0, 0));

            var mobMove = CPacket.MobMove(dwMobId, bMobMoveStartResult, pCurSplit, bIllegealVelocity, movePath);

            c.GetCharField().Broadcast(mobMove, c);
        }
예제 #25
0
        public void RemoveItem(CInPacket p)
        {
            // Recv [CP_MiniRoom] [90 00] [26] 01 00

            var nShopSlot = p.Decode2();

            var tItem = Inventory.GetAndRemove(nShopSlot);

            if (tItem is null)
            {
                // do nothing
            }
            else if (InventoryManipulator.CountFreeSlots(Parent, tItem.Item.InvType) <= 0)
            {
                Parent.SendMessage("Please make room in your inventory.");
            }
            else
            {
                InventoryManipulator.InsertInto(Parent, tItem.Item);
            }

            Refresh(Parent);
        }
예제 #26
0
        public static void CreateCharacter(WvsLoginClient c, CInPacket p)
        {
            var newChar = Default();

            // create explorer:   Recv [CP_CreateNewCharacter] 16 00 06 00 70 6F 6F 70 69 65 01 00 00 00 00 00 24 4E 00 00 [4E 75 00 00] [03 00 00 00] [03 00 00 00] [86 DE 0F 00] [2F 2D 10 00] [85 5B 10 00] [8B DE 13 00] [00]
            // create resistance: Recv [CP_CreateNewCharacter] 16 00 06 00 64 6F 6F 64 6F 6F 00 00 00 00 00 00 84 4E 00 00 [30 75 00 00] [07 00 00 00] [01 00 00 00] [47 06 10 00] [00 00 00 00] [74 5D 10 00] [8C DE 13 00] [00]

            newChar.Stats.sCharacterName = p.DecodeString();

            var job = (short)p.Decode4();

            newChar.Stats.nJob = GameConstants.GetRealJobFromCreation(job);

            bool subJob = p.Decode2() > 0;                   //whether dual blade = 1 or adventurer = 0

            newChar.Stats.nSubJob = (short)(subJob ? 1 : 0); // doing it this way to reduce potential packet editing fuckery

            newChar.Stats.nFace = p.Decode4();
            var hairColor = p.Decode4();

            newChar.Stats.nHair = p.Decode4() + hairColor;
            newChar.Stats.nSkin = (byte)p.Decode4();

            var top    = p.Decode4();
            var bottom = p.Decode4();
            var shoes  = p.Decode4();
            var weapon = p.Decode4();

            newChar.Stats.nGender = p.Decode1();

            if (newChar.Stats.nSubJob == 1)
            {
                newChar.Stats.nJob = 400; // thief job
            }

            newChar.Stats.dwPosMap = GameConstants.GetStartingMap(newChar.Stats.nJob, newChar.Stats.nSubJob);

            newChar.Look.CopyStats(newChar.Stats);

            // TODO validate these against wz files
            newChar.Look.aEquip[5]  = top;
            newChar.Look.aEquip[6]  = bottom;
            newChar.Look.aEquip[7]  = shoes;
            newChar.Look.aEquip[11] = weapon;

            newChar.Insert(c.Account.ID);

            // create empty entries in mapping tables
            InitDefaultMappings(newChar.Stats.dwCharacterID);

            if (newChar.Stats.dwCharacterID < 0)
            {
                c.SendPacket(CreateCharacterPacket(false, null));
            }
            else
            {
                // add equips  // todo figure out if overalls have their own slot ID
                MasterManager.CreateNormalStatEquip(top)
                .SaveToDB(newChar.Stats.dwCharacterID, (short)(bottom > 0 ? -5 : -5));

                if (bottom > 0) // will be zero if its a champ that starts with an overall
                {
                    MasterManager.CreateNormalStatEquip(bottom)
                    .SaveToDB(newChar.Stats.dwCharacterID, -6);
                }

                MasterManager.CreateNormalStatEquip(shoes)
                .SaveToDB(newChar.Stats.dwCharacterID, -7);

                MasterManager.CreateNormalStatEquip(weapon)
                .SaveToDB(newChar.Stats.dwCharacterID, -11);

                var nWhitePot    = 2000002;
                var nManaPot     = 2000006;
                var nPotQuantity = (short)100;

                var item1 = MasterManager.CreateItem(nWhitePot) as GW_ItemSlotBundle;
                item1.nNumber = nPotQuantity;

                item1.SaveToDB(newChar.Stats.dwCharacterID, 1);

                var item2 = MasterManager.CreateItem(nManaPot) as GW_ItemSlotBundle;
                item2.nNumber = nPotQuantity;

                item2.SaveToDB(newChar.Stats.dwCharacterID, 2);

                c.SendPacket(CreateCharacterPacket(true, newChar));
            }
        }
예제 #27
0
        public static void OnQuestRequest(WvsGameClient c, CInPacket p)
        {
            if (c.Character.Stats.nHP <= 0)
            {
                return;
            }

            var nType    = (QuestRequestType)p.Decode1();
            var nQuestId = p.Decode2();
            var pQuest   = MasterManager.QuestTemplates[nQuestId];

            if (pQuest is null)
            {
                //c.Character.SendMessage($"Unable to find quest ID {nQuestId}.");
                return;
            }

            var dwNpcTemplateID = 0;

            if (nType != QuestRequestType.LostItem && nType != QuestRequestType.ResignQuest)
            {
                dwNpcTemplateID = p.Decode4();

                var npcTemplate = MasterManager.NpcTemplates[dwNpcTemplateID];

                // TODO check for if NPC should be in the same map as the player
                //if (!c.Character.Field.Npcs.Contains(dwNpcTemplateID))
                //{
                //	c.Character.SendMessage($"Unable to find NPC {nQuestId} in current field.");
                //	// return;
                //}

                if (!pQuest.AutoStart)
                {
                    var ptUserPosX = p.Decode2();
                    var ptUserPosY = p.Decode2();

                    // TODO quest location check
                    // if ( abs(v16) > 1200 || (v8 = *(v20 + 136) - pTemplate, v17 = *(v20 + 132), abs(v8) > 800) )
                    // tick AB
                }
            }

            switch (nType)
            {
            case QuestRequestType.LostItem:
                c.Character.Quests.OnLostQuestItem(p, nQuestId);
                break;

            case QuestRequestType.AcceptQuest:
                c.Character.Quests.OnAcceptQuest(p, nQuestId, dwNpcTemplateID);
                break;

            case QuestRequestType.CompleteQuest:
                c.Character.Quests.OnCompleteQuest(p, nQuestId, dwNpcTemplateID, false);
                break;

            case QuestRequestType.ResignQuest:
                c.Character.Quests.OnResignQuest(p, nQuestId);
                break;

            case QuestRequestType.OpeningScript:
                c.Character.Quests.OnScriptLinkedQuest(nQuestId, dwNpcTemplateID, 0);
                break;

            case QuestRequestType.CompleteScript:
                c.Character.Quests.OnScriptLinkedQuest(nQuestId, dwNpcTemplateID, 1);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(nType));
            }
        }
예제 #28
0
        //nType:
        //
        public static MapleAttackNew Parse(CInPacket p, int nType)
        {
            MapleAttackNew ret = new MapleAttackNew();

            p.Skip(8); // -1

            ret.tByte1        = p.Decode1();
            ret.nDamagePerMob = (byte)(ret.tByte1 & 0xF);
            ret.nMobCount     = (byte)((ret.tByte1 >> 4) & 0xF);

            p.Skip(8); //-1

            var v11 = p.Decode4();

            ret.nSkillID = v11;
            p.Skip(1); // 0.94
            p.Skip(4); // 0.74
            p.Skip(4); // 0.74
            p.Skip(8); // 0.88 (0)

            //is_keydown_skill
            if (v11 == 2121001 || v11 == 2221001 || v11 == 2321001 || v11 == 3221001 || v11 == 3121004)
            {
                ret.tKeyDown = p.Decode4();
            }
            else
            {
                ret.tKeyDown = -1;
            }

            /*
             * switch (ret.skill)
             * {
             *  case 5101004: // Corkscrew
             *  case 15101003: // Cygnus corkscrew
             *  case 5201002: // Grenade
             *  case 14111006: // Poison bomb
             *  case 4341002: // Final Cut
             *  case 4341003: // Monster Bomb
             *      ret.charge = p.Decode4();
             *      break;
             *  default:
             *      ret.charge = 0;
             *      break;
             * }
             */

            p.Decode1(); //  bFinalAfterSlashBlast | 8 * bShadowPartner | 16 * v674 | 32 * (nSerialAttackSkillID != 0) | ((_BYTE)v683 << 7));

            ret.tByte2  = p.Decode2();
            ret.bLeft   = (ret.tByte2 >> 15) & 1;
            ret.nAction = ret.tByte2 & 0x7FFF;
            p.Skip(4); //CRC i think
            ret.nAttackActionType = p.Decode1();
            ret.nAttackSpeed      = p.Decode1();

            ret.tAttackTime = p.Decode4();
            p.Skip(4); //bmage?

            //More decode for bullets here

            //if (ret.skill == 4211006)
            //{ // Meso Explosion
            //    return parseMesoExplosion(lea, ret);
            //}

            for (int i = 0; i < ret.nMobCount; i++)
            {
                var info = new AttackInfo();

                info.dwMobID = p.Decode4();

                //COutPacket::Encode1(&oPacket, v567->nHitAction);
                //todo fill the reste in
                p.Skip(14);

                for (int j = 0; j < ret.nDamagePerMob; j++)
                {
                    info.aDamage[j] = p.Decode4();

                    Logger.Write(LogLevel.Debug, "Attack Mob {0} Dmg {1}", info.dwMobID, info.aDamage[j]);
                }

                p.Skip(4); // CRC of monster [Wz Editing]

                ret.aAttackInfo[i] = info;
            }

            //ret.position = p.DecodePos();

            //if greneade read pos

            return(ret);
        }
예제 #29
0
        public static void Handle_UserSkillLearnItemUseRequest(WvsGameClient c, CInPacket p)
        {
            int   dwTickCount = p.Decode4();
            short nPOS        = p.Decode2();
            int   nItemID     = p.Decode4();

            c.Character.Action.Enable();

            if (c.Character.Stats.nHP <= 0)
            {
                return;
            }

            if (InventoryManipulator.GetItem(c.Character, ItemConstants.GetInventoryType(nItemID), nPOS) is GW_ItemSlotBundle item &&
                item.Template is ConsumeItemTemplate template)
            {
                var jobroot = Math.Floor(c.Character.Stats.nJob * 0.01);                 // 3500 -> 35

                var bUsed         = false;
                var bSuccess      = false;
                var bIsMasterBook = item.nItemID / 10000 == 229;

                foreach (var skillId in template.SkillData)
                {
                    var skillJob  = (int)Math.Floor(skillId / 10000f); // 35111010 -> 3511
                    var skillRoot = (int)Math.Floor(skillJob / 100f);  // 3511 -> 35

                    if (skillRoot == jobroot)                          // this can only be true once
                    {
                        if (skillJob > c.Character.Stats.nJob)
                        {
                            break;
                        }

                        var skill = c.Character.Skills.FirstOrDefault(s => s.nSkillID == skillId);

                        if (bIsMasterBook)
                        {
                            if (skill is null || skill.nSLV < template.ReqSkillLevel || skill.CurMastery >= template.MasterLevel)
                            {
                                return;
                            }
                        }
                        else
                        {
                            if (skill != null && skill.CurMastery > 0)
                            {
                                break;
                            }
                        }

                        bUsed = true;

                        if (template.SuccessRate != 100)
                        {
                            if (Constants.Rand.Next() % 100 > template.SuccessRate)
                            {
                                break;
                            }
                        }

                        c.Character.Modify.Skills(mod => mod.AddEntry(skillId, s => s.CurMastery = (byte)template.MasterLevel));
                        bSuccess = true;
                        break;
                    }
                }

                if (bUsed)
                {
                    InventoryManipulator.RemoveFrom(c.Character, item.InvType, nPOS);                     // always remove
                }

                c.Character.Field.Broadcast(CPacket.SkillLearnItemResult(c.dwCharId, bIsMasterBook, bUsed, bSuccess));
            }
        }
예제 #30
0
        public static void Handle_SkillUseRequest(WvsGameClient c, CInPacket p)
        {
            // Recv [CP_UserSkillUseRequest] [67 00] [86 1E 31 2F] [9B BA 3E 00] [14] 02 12 27 00 00 23 27 00 00 C2 01
            var dwTickCount = p.Decode4();
            var nSkillID    = p.Decode4();
            var nSLV        = p.Decode1();

            var pSkill = c.Character.Skills.Get(nSkillID, true);

            // do validation here so we dont need to validate in called functions
            if (pSkill is null || nSLV > pSkill.nSLV)
            {
                return;
            }

            if (SkillLogic.IsMobCaptureSkill(nSkillID))
            {
                ActiveSkill_MobCapture.Handle(nSkillID, nSLV, c.Character, p);
            }
            else if (SkillLogic.IsSummonCapturedMobSkill(nSkillID))
            {
                ActiveSkill_SummonMonster.Handle(nSkillID, nSLV, c.Character, p);
            }
            else if (SkillLogic.IsHookAndHitSkill(nSkillID))
            {
                ActiveSkill_HookAndHit.Handle(nSkillID, nSLV, c.Character, p);
            }
            else if (SkillLogic.IsSmokeShellSkill(nSkillID))
            {
                ActiveSkill_SmokeShell.Handle(nSkillID, nSLV, c.Character, p);
            }
            else if (SkillLogic.IsDamageMeterSkill(nSkillID, c.Character.Stats.nJob))
            {
                ActiveSkill_DamageMeter.Handle(nSkillID, nSLV, c.Character, p);
            }
            else if (SkillLogic.IsFlyingSkill(nSkillID, c.Character.Stats.nJob))
            {
                ActiveSkill_Flying.Handle(nSkillID, nSLV, c.Character, p);
            }
            else if (SkillLogic.IsClericHealSkill(nSkillID))
            {
                ActiveSkill_Heal.Handle(nSkillID, nSLV, c.Character, p);
            }
            else if (SkillLogic.IsOpenGateSkill(nSkillID))
            {
                ActiveSkill_OpenGate.Handle(nSkillID, nSLV, c.Character, p);
            }
            else if (SkillLogic.IsRecoveryAura(nSkillID))
            {
                ActiveSkill_RecoveryAura.Handle(nSkillID, nSLV, c.Character, p);
            }
            else if (SkillLogic.IsMysticDoorSkill(nSkillID, c.Character.Stats.nJob) || nSkillID == (int)Skills.PRIEST_MYSTIC_DOOR)
            {
                ActiveSkill_TownPortal.Handle(nSkillID, nSLV, c.Character, p);
            }
            else if (SkillLogic.IsStatChangeAdminSkill(nSkillID, c.Character.Stats.nJob))
            {
                ActiveSkill_StatChangeAdmin.Handle(nSkillID, nSLV, c.Character, p);
            }
            else if (pSkill.Template.IsSummonSkill && nSkillID != (int)Skills.BMAGE_REVIVE)
            {
                ActiveSkill_Summon.Handle(nSkillID, nSLV, c.Character, p);
            }
            else
            {
                var bLeft = false;

                if (pSkill.Template.is_antirepeat_buff_skill)
                {
                    var x = p.Decode2();
                    var y = p.Decode2();

                    bLeft = x < c.Character.Position.X;
                }

                //  Recv [CP_UserSkillUseRequest] [67 00] [4B 5E 91 0B] [CD 14 F9 01] 14

                var nSpiritJavelinItemID = 0;
                if (nSkillID == (int)Skills.NIGHTLORD_SPIRIT_JAVELIN)       //Spirit Claw
                {
                    nSpiritJavelinItemID = p.Decode4();                     //nSpiritJavelinItemID
                }
                if (pSkill.Template.is_event_vehicle_skill)
                {
                    p.Skip(1);                     // dwAffectedMemberBitmap

                    if (nSkillID == 2311001)
                    {
                        p.Skip(2);                         // tDelay
                    }
                }

                var nRemaining = p.Available - 2;

                if (nRemaining > 0)
                {
                    p.Skip(nRemaining);
                }

                //if (nRemaining > 0)
                //{
                //    var nMobCount = p.Decode1(); // nMobCount
                //    for (int i = 0; i < nMobCount; i++)
                //    {
                //        p.Decode4(); // adwMobID
                //    }
                //}

                var tDelay = p.Available >= 2 ? p.Decode2() : (short)0;                 // tDelay

                if (nSkillID == 0 || c.Character.Skills.Cast(nSkillID, bLeft, false, nSpiritJavelinItemID))
                {
                    new UserEffectPacket(UserEffect.SkillUse)
                    {
                        nSkillID = nSkillID,
                        nSLV     = nSLV
                    }.BroadcastEffect(c.Character, false);
                }
            }

            c.Character.Action.Enable();
        }