예제 #1
0
        public static void Handle_SummonedHit(WvsGameClient c, CInPacket p)
        {
            int dwSummonedID = p.Decode4();
            var item         = c.Character.Field.Summons[dwSummonedID];

            if (item is null)
            {
                return;
            }

            var nAttackIdx = p.Decode1();
            var nDamage    = p.Decode4();
            var dwMobID    = p.Decode4();
            var bLeft      = p.Decode1();

            if (item.nCurHP <= 0 || item.Field.Mobs[dwMobID] is null || item.Field.Mobs[dwMobID].Stats.HP <= 0)
            {
                return;
            }

            item.Field.Broadcast(CPacket.CSummonedPool.SummonedHit(item, nAttackIdx, nDamage, dwMobID, bLeft));

            if (nDamage >= item.nCurHP)
            {
                item.nLeaveType = SummonLeaveType.LEAVE_TYPE_SUMMONED_DEAD;
                item.Field.Summons.Remove(item);
            }
            else
            {
                item.nCurHP -= (short)nDamage;
            }
        }
예제 #2
0
        public void OnUpdateRequest(CInPacket p)
        {
            var nReq = (MapTransferReq)p.Decode1();
            var bExt = p.Decode1() != 0;

            var pTransfer = bExt ? adwMapTransferEx : adwMapTransfer;

            switch (nReq)
            {
            case MapTransferReq.RegisterList:
            {
                var nFieldID = Parent.Field.MapId;
                if (Parent.Field.Template.HasTeleportItemLimit() || !AddLocation(pTransfer, nFieldID))
                {
                    Parent.SendPacket(CPacket.MapTransferResult(MapTransferRes.RegisterFail, bExt));
                }
                else
                {
                    Parent.SendPacket(CPacket.MapTransferResult(MapTransferRes.RegisterList, bExt, pTransfer));
                }
                break;
            }

            case MapTransferReq.DeleteList:
            {
                int nFieldID = p.Decode4();
                RemoveLocation(pTransfer, nFieldID);

                Parent.SendPacket(CPacket.MapTransferResult(MapTransferRes.DeleteList, bExt, pTransfer));
                break;
            }
            }
        }
예제 #3
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;
            }
        }
예제 #4
0
        public void Move(Character pUser, CInPacket p)
        {
            var dwNpcId = p.Decode4();
            var item    = this[dwNpcId];

            if (item == null)
            {
                return;
            }
            if (item.Controller != pUser)
            {
                return;                                       //TODO: Validate you require controller to move a npc
            }
            var act1 = p.Decode1();
            var act2 = p.Decode1();

            byte[] aMovePath = null;

            if (p.Available > 0)
            {
                aMovePath = p.DecodeBuffer(p.Available);
            }

            Field.Broadcast(CPacket.NpcMove(item, act1, act2, aMovePath));
        }
예제 #5
0
        // actually in CUserLocal::TryDoingMonsterMagnet
        // but that function is only called by the active which has the name of this class
        //
        public static void Handle(int nSkillID, byte nSLV, Character c, CInPacket p)
        {
            //            COutPacket::COutPacket(&oPacket, 103);
            //            LOBYTE(v115) = 2;
            //            v81 = get_update_time();
            //            COutPacket::Encode4(&oPacket, v81);
            //            COutPacket::Encode4(&oPacket, v76->nSkillID);
            //            COutPacket::Encode1(&oPacket, nSLV);
            //            v82 = nRange;
            //            COutPacket::Encode4(&oPacket, nRange);
            //            for (k = 0; k < v82; ++k)
            //            {
            //                if (apMob.a[k].p)
            //                {
            //                    v84 = apMob.a[k].p;
            //                    v94 = (int*)v84->_ZtlSecureTear_m_dwMobID_CS;
            //                    v85 = _ZtlSecureFuse < unsigned long> (v84->_ZtlSecureTear_m_dwMobID, (unsigned int)v94);
            //        }
            //    else
            //    {
            //      v85 = 0;
            //    }
            //    COutPacket::Encode4(&oPacket, v85);
            //    v86 = anMobMove[k];
            //    v87 = v86 == 3 || v86 == 4;
            //    COutPacket::Encode1(&oPacket, v87);
            //  }
            //COutPacket::Encode1(&oPacket, v71->m_nMoveAction & 1);
            //  CClientSocket::SendPacket(TSingleton<CClientSocket>::ms_pInstance, &oPacket);

            var nCount = p.Decode4();
            var apMob  = new int[nCount];

            for (var i = 0; i > nCount; i++)
            {
                apMob[i] = p.Decode4();
                var anMobMove = p.Decode1(); // i dont think we need this???
            }

            var bLeft = p.Decode1() > 0;

            if (c.Skills.Cast(nSkillID, bLeft))
            {
                new UserEffectPacket(UserEffect.SkillUse)
                {
                    nSkillID = nSkillID,
                    nSLV     = nSLV,
                    bLeft    = bLeft,
                    dwMobId  = nCount > 0 ? apMob[0] : 0,                    // idk
                }.BroadcastEffect(c, false);

                foreach (var dwMobId in apMob)
                {
                    if (c.Field.Mobs.TryGetValue(dwMobId, out CMob cMob))
                    {
                        cMob.TryApplySkillDamageStatus(c, nSkillID, nSLV, 0);                         // todo configure this
                    }
                }
            }
        }
예제 #6
0
        public static MapleAttack ParseBody(CInPacket p, Character c)
        {
            return(ParseMelee(p, c));            //TODO: Confirm below one day. Delta said melee works for this

            // Recv [CP_UserBodyAttack] [32 00] [01] [FF FF FF FF] [FF FF FF FF] [11] [FF FF FF FF] [FF FF FF FF] [CB F9 41 01] [00] [C3 C0 24 6A] [1F 46 7E D1] [9D D4 DD D5] [9D D4 DD D5] [00 00] 80 5F CF 88 C3 02 00 F9 9E D9 1F 00 00 00 00 2F 27 00 00 07 00 01 05 A9 00 8B 01 A5 00 8B 01 00 00 0B 00 00 00 B8 8D DB 27 B9 00 8B 01

            MapleAttack ret = new MapleAttack();

            p.Decode1();                                   // field key
            p.Decode4();                                   // pDrInfo.dr0
            p.Decode4();                                   // pDrInfo.dr1

            ret.nDamagePerMob = (byte)(p.Decode1() & 0xF); // nDamagePerMob | 0x10 * nRange

            p.Decode4();                                   // pDrInfo.dr2
            p.Decode4();                                   // pDrInfo.dr3

            ret.nSkillID = p.Decode4();

            ret.ValidateSkill(c);
            if (!ret.bValidAttack)
            {
                return(ret);
            }

            p.Decode1();             // cd->nCombatOrders
            p.Decode4();             // get_rand(pDrInfo.dr0, 0)
            p.Decode4();             // CCrc32::GetCrc32(pData, 4u, n, 0, 0)

            // todo lol

            return(null);
        }
예제 #7
0
        public void DecodeMovePath(byte[] movePath)
        {
            var iPacket = new CInPacket(movePath);

            Position.X = iPacket.Decode2();
            Position.X = iPacket.Decode2();
            var vx = iPacket.Decode2();
            var vy = iPacket.Decode2();

            var size = iPacket.Decode1();

            for (int i = 0; i < size; i++)
            {
                var cmd = iPacket.Decode1();

                if (cmd == 0)
                {
                    Position.X = iPacket.Decode2();
                    Position.Y = iPacket.Decode2();
                    var xwob = iPacket.Decode2();
                    var ywob = iPacket.Decode2();
                    Foothold = iPacket.Decode2();
                    var xoff = iPacket.Decode2();
                    var yoff = iPacket.Decode2();
                    Stance = iPacket.Decode1();
                    var duration = iPacket.Decode2();
                }
                else if (cmd == 1)
                {
                    var xmod = iPacket.Decode2();
                    var ymod = iPacket.Decode2();
                    Stance = iPacket.Decode1();
                    var duration = iPacket.Decode2();
                }
                //else if (cmd == 11)
                //{
                //    Position.X = iPacket.Decode2();
                //    Position.Y = iPacket.Decode2();
                //    var unk = iPacket.Decode2();
                //    Stance = iPacket.Decode1();
                //    var duration = iPacket.Decode2();
                //    Logger.Write(LogLevel.Debug, "SubMov 11 {0}", unk);
                //}
                //else if (cmd == 12) //jump down
                //else if (cmd == 2) //the knockback ( by mob after 27 )
                else if (cmd == 27) //When u get hit by a mob ur stance changes
                {
                    Stance = iPacket.Decode1();
                    var unk = iPacket.Decode2();
                }
                else
                {
                    //Logger.Write(LogLevel.Warning, "Unparsed Movement SubOp {0}", cmd);
                    break; //break loop because we didnt parse subop
                }
            }
        }
예제 #8
0
        public void OnPetPacket(RecvOps opCode, CInPacket p)
        {
            switch (opCode)
            {
            case RecvOps.CP_PetDropPickUpRequest:

                break;

            case RecvOps.CP_PetInteractionRequest:

                break;

            case RecvOps.CP_UserActivatePetRequest:

                break;

            case RecvOps.CP_UserDestroyPetItemRequest:

                break;

            default:
                var liPetLockerSN = p.Decode8();

                var item = Pets.FirstOrDefault(pet => pet.liPetLockerSN == liPetLockerSN);

                if (item is null)
                {
                    return;
                }

                switch (opCode)
                {
                case RecvOps.CP_PetMove:
                    item.Move(p);
                    break;

                case RecvOps.CP_PetStatChangeItemUseRequest:                                 //  CPet::OnNameChanged(v4, iPacket);
                    break;

                case RecvOps.CP_PetUpdateExceptionListRequest:
                    break;

                case RecvOps.CP_PetAction:
                case RecvOps.CP_PetActionCommand:

                    var tick    = p.Decode4();
                    var nType   = p.Decode1();
                    var nAction = p.Decode1();
                    var sMsg    = p.DecodeString();                                  // rebroadcasting this is bad practice

                    Parent.Field.Broadcast(item.PetActionCommand((PetActType)nType, nAction, true, true), Parent);

                    break;
                }
                break;
            }
        }
예제 #9
0
        public static void UserChat(WvsGameClient c, CInPacket p)
        {
            p.Decode4();
            var sText        = p.DecodeString();
            var bOnlyBalloon = p.Decode1() != 0;

            if (sText.Length >= sbyte.MaxValue)
            {
                return;
            }

            var handle = ServerApp.Container.Resolve <CommandHandle>();

            if (!handle.Execute(c.Character, sText))
            {
                var bAdmin = c.Account.AccountData.Admin > 0;
                CCurseProcess.ProcessString(sText, out var output);

                if (output.Length <= 0)
                {
                    return;
                }

                c.Character.Field.Broadcast(CPacket.UserChat(c.Character.dwId, output, bAdmin, bOnlyBalloon));
            }
        }
예제 #10
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
            }
        }
예제 #11
0
        private void Handle_UserMeleeAttack(WvsGameClient c, CInPacket p)
        {
            var m_bCurFieldKey = p.Decode1();

            var atkInfo = MapleAttackNew.Parse(p, 0);
            var field   = c.GetCharField();

            //This pocket is not working ;( - rt if u cried
            var v1 = CPacket.CloseRangeAttack(c.Character.CharId, atkInfo);

            field.Broadcast(v1, c);

            for (int i = 0; i < atkInfo.nMobCount; i++)
            {
                var info = atkInfo.aAttackInfo[i];

                var mob = field.Mobs.Get(info.dwMobID);

                int dmg = 0;

                for (int j = 0; j < atkInfo.nDamagePerMob; j++)
                {
                    dmg += info.aDamage[j];
                }

                mob.CurHp -= dmg;

                if (mob.CurHp <= 0)
                {
                    field.RemoveMob(c, mob);
                }
            }
        }
        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();
        }
예제 #13
0
        public static GW_ItemSlotBase Decode(CInPacket p)
        {
            var             type = p.Decode1();
            GW_ItemSlotBase ret  = null;

            if (type == 1)
            {
                ret = new GW_ItemSlotEquip();
            }

            if (type == 2)
            {
                ret = new GW_ItemSlotBundle();
            }

            if (type == 2)
            {
                ret = new GW_ItemSlotPet();
            }

            if (ret == null)
            {
                throw new Exception("Unknown item type");
            }

            ret.RawDecode(p);
            return(ret);
        }
예제 #14
0
        //========================

        public void OnRequestPacket(WvsGameClient c, CInPacket p)
        {
            var pChar  = c.Character;
            var opCode = (PartyOps)p.Decode1();

            switch (opCode)
            {
            case PartyOps.CreateParty:
                Create(pChar, p);
                break;

            case PartyOps.LeaveParty:
                Leave(pChar, p);
                break;

            //case PartyOps.JoinParty:
            //    Join(pChar, p);
            //    break;
            case PartyOps.InviteParty:
                Invite(pChar, p);
                break;

            case PartyOps.KickParty:
                Kick(pChar, p);
                break;

            case PartyOps.ChangePartyLeader:
                ChangePartyLeader(pChar, p);
                break;
            }
            c.Character.Action.Enable();
        }
예제 #15
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);
            }
        }
예제 #16
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
            }
        }
예제 #17
0
        public static void IncCharSlotCount(WvsShopClient c, CInPacket p)
        {
            // validate packet length
            if (p.Available < 9)
            {
                return;
            }

            p.Decode1();
            var cashType    = p.Decode4();
            var commodityId = p.Decode4();

            //Log.Debug("CASH COMMODITY ID: " + commodityId);

            if (!c.Account.HasCash((CashType)cashType, 6900) ||
                (c.Account.AccountData.CharacterSlots + 3) >
#if DEBUG
                27
#else
                Constants.MaxCharSlot
#endif
                )
            {
                c.SendPacket(CPacket.CCashShop.RequestFailPacket(CashItemOps.CashItemRes_Buy_Failed, CashItemFailed.PurchaseLimitOver));
            }
예제 #18
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
            }
        }
예제 #19
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)));
        }
예제 #20
0
        public static void Handle_GroupMessage(WvsGameClient c, CInPacket p)
        {
            // : [8C 00] [5B BE 87 0F] [01] [01] [69 04 00 00] [03 00] [61 73 64]

            var get_update_time = p.Decode4();
            var nChatTarget     = p.Decode1();
            var nMemberCnt      = p.Decode1();
            var aMemberList     = p.DecodeIntArray(nMemberCnt);
            var sText           = p.DecodeString();

            // [INFO] Recv [CP_GroupMessage] 8C 00 30 9F 4F 0F 01 01 69 04 00 00 05 00 61 73 64 77 64

            if (sText.Length >= sbyte.MaxValue)
            {
                c.Character.SendMessage("Chat message exceeded allowed length.");
                return;
            }

            MasterManager.Log.Debug("Text: " + sText);

            switch ((GroupMessageType)nChatTarget)
            {
            case GroupMessageType.BuddyChat:
                c.Character.Friends.HandleBuddyChat(sText, aMemberList);
                break;

            case GroupMessageType.PartyChat:
                c.Character.Party?.HandlePartyChat(c.Character.dwId, c.Character.Stats.sCharacterName, sText);
                break;

            case GroupMessageType.ExpeditionChat:
                // todo
                break;

            case GroupMessageType.GuildChat:
                // todo
                break;

            case GroupMessageType.AllianceChat:
                // todo
                break;
            }
        }
예제 #21
0
        private void Handle_SelectWorld(WvsLoginClient c, CInPacket p)
        {
            var nLoginType = p.Decode1();

            if (nLoginType != 2) // Invalid LoginType ( Not ClientLogin )
            {
                return;
            }

            var nWorldID   = p.Decode1();
            var nChannelId = p.Decode1();

            if (nWorldID != 0) //Invalid World ( Not Scania )
            {
                return;
            }

            var pCenter    = ServerApp.Container.Resolve <WvsCenter>();
            var nChannelNo = pCenter.WvsGames.Length;

            if (nChannelId >= nChannelNo) //Invalid Channel
            {
                return;
            }

            c.WorldID   = nWorldID;
            c.ChannelId = nChannelId;

            var aCharList = c.Account.LoadCharIdList();
            var aEntries  = new List <CharacterEntry>();

            foreach (var pItem in aCharList)
            {
                var pEntry = new CharacterEntry();
                pEntry.Load(pItem);

                aEntries.Add(pEntry);
            }

            var aFinalList = aEntries.OrderBy(pEntry => pEntry.Stats.dwCharacterID).ToArray();

            c.SendPacket(CPacket.CLogin.SelectWorldResult(aFinalList, c.Account.AccountData.CharacterSlots));
        }
예제 #22
0
        public static void Handle_Whisper(WvsGameClient c, CInPacket p)
        {
            // Recv [CP_Whisper] [8D 00] [05] [7C 9E D7 14] [05 00] [70 65 6E 69 73]
            var flag = p.Decode1(); //    COutPacket::Encode1((COutPacket *)&oPacket, ((v44 == 0) + 1) | 4);

            p.Decode4();            // tick
            var name = p.DecodeString();

            if (name.Length > 13)
            {
                return;
            }

            var pTargetUser = MasterManager.CharacterPool.Get(name, false);

            if (pTargetUser is null) // will not be null if char is in itc or cs
            {
                c.SendPacket(WhisperResult(name, false));
                return;
            }

            switch (flag) // todo make this an enumerator
            {
            case 5:       // /find command
            {
                var nTargetChannel = pTargetUser.ChannelID;
                if (MasterManager.CharacterPool.CharInCashShop(pTargetUser.dwId))
                {
                    c.SendPacket(FindResult(pTargetUser.Stats.sCharacterName, Actions.FindResult.CS));
                }
                else if (nTargetChannel == c.ChannelId)
                {
                    c.SendPacket(FindResult(pTargetUser.Stats.sCharacterName, Actions.FindResult.SameChannel, pTargetUser.Field.MapId));
                }
                else
                {
                    c.SendPacket(FindResult(pTargetUser.Stats.sCharacterName, Actions.FindResult.DifferentChannel, pTargetUser.ChannelID));
                }
            }
            break;

            case 6:     // whisper
            {
                var msg = p.DecodeString();

                if (msg.Length > 75)
                {
                    return;                          // PE or trying to find player
                }
                pTargetUser.SendPacket(WhisperMessage(c.Character.Stats.sCharacterName, c.Character.ChannelID, c.Character.Account?.AccountData.Admin > 0, msg));
                c.SendPacket(WhisperResult(c.Character.Stats.sCharacterName, true));
            }
            break;
            }
        }
예제 #23
0
        public static void EntrustedShopRequest(WvsGameClient c, CInPacket p)
        {
            var opCode = p.Decode1();

            if (opCode == 0)
            {
                var outP = new COutPacket(SendOps.LP_EntrustedShopCheckResult);
                outP.Encode1(0x07);
                c.SendPacket(outP);
            }
        }
        // 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);
        }
예제 #25
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);
        }
예제 #26
0
        public virtual void RawDecode(CInPacket p)
        {
            nItemID = p.Decode4();

            var v3 = p.Decode1() != 0;

            if (v3)
            {
                liCashItemSN = p.Decode8();
            }

            tDateExpire = DateTime.FromFileTimeUtc(p.Decode8());
        }
예제 #27
0
        public static void OnPacket(WvsGameClient c, CInPacket p)
        {
            var   chr      = c.Character;
            var   targetId = p.Decode4();
            short type     = p.Decode1();

            var targetChar = chr.Field.Users[targetId];

            if (targetChar is null || chr.dwId == targetId)
            {
                c.SendPacket(GivePopularityResult_Error(GivePopularityRes.InvalidCharacterID));
                return;
            }
예제 #28
0
        public virtual void RawDecode(CInPacket p)
        {
            nItemID = p.Decode4();

            var v3 = p.Decode1() != 0;

            if (v3)
            {
                liCashItemSN = p.Decode8();
            }

            dateExpire = p.Decode8();
        }
예제 #29
0
        /**
         * Client sends cash item SN.
         * We index cash items by their serial number.
         * WZ files indexes cash items by a commodity ID.
         * The commodity ID (~12000 total) is not used for anything.
         */
        public static void Buy(WvsShopClient c, CInPacket p)
        {
            // validate packet length
            if (p.Available < 9)
            {
                return;
            }

            p.Decode1();             // 00
            var cashType     = (CashType)p.Decode4();
            var nCommoditySN = p.Decode4();

            var commodityInfo = MasterManager.CommodityProvider[nCommoditySN];

            if (commodityInfo == null)
            {
                return;
            }
            if (!commodityInfo.OnSale)
            {
                return;                                    // TODO proper error code/response
            }
            var item = MasterManager.CreateCashCommodityItem(nCommoditySN);

            if (item is null)
            {
                return;
            }

            if (!c.Account.HasCash(cashType, item.NXCost))
            {
                return;                                                        // TODO proper error code/response
            }
            if (ItemConstants.IsPet(item.nItemID) &&
                InventoryManipulator.GetItemByCashSN(c.Character, InventoryType.Cash, item.SN).Item2 != null)
            {
                return;                 // cant have two of the same pet cuz it screws up our indexing
            }
            c.CashLocker.Add(item);
#if DEBUG
            c.Account.ModifyCash(cashType, 10000);
            Log.Info($"{commodityInfo.CashItemSN}");
#else
            c.Account.ModifyCash(cashType, -commodityInfo.Price);
#endif
            item.dwAccountID   = c.Account.ID;
            item.dwCharacterID = c.dwCharId;

            c.SendPacket(CPacket.CCashShop.BuyResponse(item));
            // do best items/limited goods handling here
        }
예제 #30
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();
        }