示例#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
        // 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
                    }
                }
            }
        }
示例#3
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));
            }
示例#4
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;
            }
        }
示例#5
0
        public void UserInfoRequest(Character c, CInPacket p)
        {
            var dwDickCount = p.Decode4();
            var nUserID     = p.Decode4();

            var pUser = this[nUserID];

            if (pUser != null)
            {
                c.SendPacket(pUser.CharacterInfo());
            }
        }
示例#6
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
        }
示例#7
0
        private void Handle_UserEmotion(WvsGameClient c, CInPacket p)
        {
            var nEmotion      = p.Decode4();
            var nDuration     = p.Decode4();
            var bByItemOption = p.Decode1();

            //if (emote > 7)
            //{
            //    int emoteid = 5159992 + emote;
            //    //TODO: As if i care check if the emote is in CS inventory, if not return
            //}

            c.GetCharField().Broadcast(CPacket.UserEmoticon(c.Character.CharId, nEmotion, nDuration, bByItemOption), c);
        }
示例#8
0
        private void Handle_UserMove(WvsGameClient c, CInPacket p)
        {
            var v1          = p.Decode8();
            var portalCount = p.Decode1(); //CField::GetFieldKey(v20);
            var v2          = p.Decode8();
            var mapCrc      = p.Decode4();
            var dwKey       = p.Decode4();
            var dwKeyCrc    = p.Decode4();

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

            c.Character.Position.DecodeMovePath(movePath);

            c.GetCharField().Broadcast(CPacket.UserMovement(c.Character.CharId, movePath), c);
        }
示例#9
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));
        }
示例#10
0
        public void OnPacket(RecvOps opCode, CInPacket p, Character c)
        {
            if (c.Stats.nHP <= 0)
            {
                return;
            }

            var dwID = p.Decode4();
            var item = this[dwID];

            if (item is null)
            {
                return;
            }

            switch (opCode)
            {
            case RecvOps.CP_ReactorHit:
                item.Hit(c, p);
                break;

            case RecvOps.CP_ReactorTouch:
                item.Touch(c, p);
                break;
            }
            var provider = ServerApp.Container.Resolve <ScriptManager>();
            var script   = provider.GetReactorScript
                               (item.sName, item, c.Socket, opCode == RecvOps.CP_ReactorHit);

            script.Execute();
        }
示例#11
0
        private void Handle_DeleteCharacter(WvsLoginClient c, CInPacket p)
        {
            var uid = p.Decode4();

            c.SendPacket(CPacket.DeleteCharacter(uid, 0));
            //Because I have no pin or pic the game wont let me dlete chars lol
        }
示例#12
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);
            }
        }
示例#13
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
            }
        }
示例#14
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;
            }
            }
        }
示例#15
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);
            }
        }
        public void OnCompleteQuest(CInPacket p, short nQuestID, int dwNpcTemplateID, bool bIsAutoComplete)
        {
            var nSelect = bIsAutoComplete ? -1 : p.Decode4();

            if (!CheckDemand(nQuestID, dwNpcTemplateID, 1))
            {
                Parent.SendPacket(CPacket.CQuestMan.UserQuestResult(QuestResultType.Failed_Unknown, null));
                return;
            }

            var nActCompleteResult = TryQuestAct(nQuestID, 1);

            if (nActCompleteResult == QuestResultType.Failed_Unknown)
            {
                return;
            }

            if (nActCompleteResult == QuestResultType.Success)
            {
                this[nQuestID].tCompleted = DateTime.Now;
                this[nQuestID].nState     = QuestActType.QuestComplete;
            }

            var endActNextQuest = MasterManager.QuestTemplates[nQuestID].EndAct?.NextQuest ?? 0;

            Parent.SendPacket(CPacket.CQuestMan
                              .UserQuestResult(nActCompleteResult, this[nQuestID], dwNpcTemplateID, (short)endActNextQuest));
        }
示例#17
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
            }
        }
示例#18
0
 public void OnQuickslotKeyMapped(CInPacket p)
 {
     for (int i = 0; i < 8; i++)
     {
         Insert(93 + 1, 8, p.Decode4());
     }
 }
示例#19
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));
            }
        }
示例#20
0
        public static void DeleteCharacter(WvsLoginClient c, CInPacket p)
        {
            var szSPW    = p.DecodeString();
            var dwCharID = p.Decode4();

            // TODO check for guild ownership and family membership

            byte nRetCode  = 0x09; //Error
            var  aCharList = c.Account.LoadCharIdList();

            if (aCharList.Contains(dwCharID))
            {
                using (var conn = new NpgsqlConnection(Constants.DB_World0_ConString))
                {
                    conn.Open();

                    using (var cmd = new NpgsqlCommand($"DELETE FROM {Constants.DB_All_World_Schema_Name}.characters WHERE id = {dwCharID}", conn))
                    {
                        cmd.ExecuteNonQuery();
                    }
                }

                nRetCode = 0; //Success
            }

            c.SendPacket(CPacket.CLogin.DeleteCharacter(dwCharID, nRetCode));
        }
示例#21
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
        }
示例#22
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;
            }
            }
        }
        /**
         * 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
            }
        }
示例#24
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);
        }
示例#25
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;
            }
        }
示例#26
0
        /**
         * Cash packages have data in both the Commodity and Package section of Etc.wz
         * Client sends package SN which is stored in the commodity section of WZ files (one of the ~12000 entries)
         * The commodity itemid (not SN) contains the SN for the CashPackage
         * The CashPackage (one of ~450) contains the cash item SN's of the package items
         */
        public static void BuyPackage(WvsShopClient c, CInPacket p)
        {
            if (p.Available < 9)
            {
                return;
            }

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

            var commodityInfo = MasterManager.CommodityProvider[nCommoditySN];

            if (commodityInfo is null)
            {
                return;
            }
            if (!commodityInfo.OnSale)
            {
                return;                                    // TODO proper error code/response
            }
            if (!c.Account.HasCash(cashType, commodityInfo.Price))
            {
                return;                                                                // TODO proper error code/response
            }
            var packagedata = MasterManager.CreateCashPackageItems(commodityInfo.ItemID);

            packagedata.ForEach(item => { item.dwAccountID = c.Account.ID; item.dwCharacterID = c.dwCharId; });

#if RELEASE
            c.Account.ModifyCash(cashType, -commodityInfo.Price);
#else
            foreach (var item in packagedata)
            {
                item.dwAccountID   = c.Account.ID;
                item.dwCharacterID = c.dwCharId;
                c.Account.AccountData.Locker.Add(item);
            }
            Log.Info($"================COMMODITYSN {nCommoditySN}");             // temporary so i can quickly find a buncha serial numbers
            return;
#endif

            c.SendPacket(CPacket.CCashShop.BuyPackageResponse(packagedata));
        }
示例#27
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;
            }
        }
示例#28
0
        public static int[] DecodeIntArray(this CInPacket packet, int nCount)
        {
            var retVal = new int[nCount];

            for (var i = 0; i < nCount; i++)
            {
                retVal[i] = packet.Decode4();
            }

            return(retVal);
        }
        // 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);
        }
示例#30
0
        public void OnPacket(WvsGameClient c, CInPacket p)
        {
            var ownerId = p.Decode4();

            if (Contains(ownerId))
            {
                if (c.Character.Party?.TryGetValue(ownerId, out PartyMember item) ?? false)
                {
                    c.Character.Action.SetField(Field.ReturnMapId);
                }
            }
        }