Exemplo n.º 1
0
        public static void OnQueryPostMail(WorldClient client, INetPacketStream packet)
        {
            var onQueryPostMailPacket = new QueryPostMailPacket(packet);
            var queryPostMailEvent    = new QueryPostMailEventArgs(onQueryPostMailPacket.ItemSlot, onQueryPostMailPacket.ItemQuantity, onQueryPostMailPacket.Receiver, (uint)onQueryPostMailPacket.Gold, onQueryPostMailPacket.Title, onQueryPostMailPacket.Text);

            client.Player.NotifySystem <MailboxSystem>(queryPostMailEvent);
        }
Exemplo n.º 2
0
        private void SendMail(IPlayerEntity player, QueryPostMailEventArgs e)
        {
            // TODO: If mailbox is too far away: return;

            var textClient         = DependencyContainer.Instance.Resolve <TextClientLoader>();
            var worldConfiguration = DependencyContainer.Instance.Resolve <WorldConfiguration>();
            var neededGold         = worldConfiguration.Mails.MailShippingCost;

            var database = DependencyContainer.Instance.Resolve <IDatabase>();
            var receiver = database.Characters.Get(x => x.Name == e.Receiver);

            // Receiver doesn't exist
            if (receiver is null)
            {
                WorldPacketFactory.SendAddDiagText(player, textClient["TID_MAIL_UNKNOW"]);
                return;
            }

            var sender = database.Characters.Get(x => x.Id == player.PlayerData.Id);

            // Receiver and sender is same person
            if (receiver == sender)
            {
                WorldPacketFactory.SendAddDiagText(player, textClient["TID_GAME_MSGSELFSENDERROR"]);
                return;
            }

            // Mailbox is full
            if (receiver.ReceivedMails.Count(x => !x.IsDeleted) >= MaxMails)
            {
                WorldPacketFactory.SendDefinedText(player, DefineText.TID_GAME_MAILBOX_FULL, receiver.Name);
                return;
            }

            // Calculate gold amount
            if (e.Gold < 0)
            {
                WorldPacketFactory.SendAddDiagText(player, textClient["TID_GAME_LACKMONEY"]);
                return;
            }

            checked
            {
                try
                {
                    neededGold += e.Gold;
                    if (neededGold > player.PlayerData.Gold)
                    {
                        WorldPacketFactory.SendAddDiagText(player, textClient["TID_GAME_LACKMONEY"]);
                        return;
                    }
                }
                catch (OverflowException) // Catch integer overflows to prevent exploits
                {
                    Logger.LogError($"{player.Object.Name} caused an OverflowException by placing {e.Gold} into a mail.");
                    WorldPacketFactory.SendAddDiagText(player, textClient["TID_GAME_LACKMONEY"]);
                    return;
                }
            }

            // Calculate item quantity and do all kinds of checks
            DbItem item          = null;
            var    inventoryItem = player.Inventory.Items.FirstOrDefault(x => x.Slot == e.ItemSlot);

            if (inventoryItem != null && inventoryItem.Id > -1)
            {
                var quantity = e.ItemQuantity;
                if (e.ItemQuantity > inventoryItem.Quantity)
                {
                    quantity = (short)inventoryItem.Quantity;
                }
                item = database.Items.Get(x => x.Id == inventoryItem.DbId);

                // TODO: Add the following checks

                /* All AddDiagText
                 * IsBound - TID_GAME_CANNOT_POST  https://github.com/domz1/SourceFlyFF/blob/ce4897376fb9949fea768165c898c3e17c84607c/Program/WORLDSERVER/DPSrvr.cpp#L7402
                 * IsUsing - TID_GAME_CANNOT_DO_USINGITEM  https://github.com/domz1/SourceFlyFF/blob/ce4897376fb9949fea768165c898c3e17c84607c/Program/WORLDSERVER/DPSrvr.cpp#L7407
                 * IsCharged()- TID_GAME_CANNOT_POST https://github.com/domz1/SourceFlyFF/blob/ce4897376fb9949fea768165c898c3e17c84607c/Program/WORLDSERVER/DPSrvr.cpp#L7434
                 */

                if (inventoryItem.IsEquipped() ||
                    inventoryItem.ExtraUsed != 0 ||
                    inventoryItem.Data.ItemKind3 == ItemKind3.QUEST ||
                    (inventoryItem.Data.ItemKind3 == ItemKind3.CLOAK /*&& inventoryItem.GuildId != 0*/) // || GuildId on items is not yet implemented
                    /*(inventoryItem.Data.Parts == Parts.PARTS_RIDE && inventoryItem.Data.ItemJob == DefineJob.JOB_VAGRANT)*/)
                {
                    WorldPacketFactory.SendAddDiagText(player, textClient["TID_GAME_CANNOT_POST"]);
                    return;
                }

                // TODO: Not yet implemented

                /*if (inventoryItem.Data.Parts == Parts.PARTS_RIDE && inventoryItem.Data.ItemJob == DefineJob.JOB_VAGRANT)
                 * {
                 *  WorldPacketFactory.SendAddDiagText(player, textClient["TID_GAME_CANNOT_POST"]);
                 *  return;
                 * }*/

                if (inventoryItem.Data.IsStackable)
                {
                    var futureQuantity = inventoryItem.Quantity - quantity;
                    if (futureQuantity == 0)
                    {
                        player.Inventory.Items.Remove(inventoryItem);
                    }
                    inventoryItem.Quantity = futureQuantity;
                    WorldPacketFactory.SendItemUpdate(player, UpdateItemType.UI_NUM, inventoryItem.Slot, futureQuantity);
                }
                else // Not stackable so always remove it
                {
                    player.Inventory.Items.Remove(inventoryItem);
                    WorldPacketFactory.SendItemUpdate(player, UpdateItemType.UI_NUM, inventoryItem.Slot, 0);
                }
            }

            // Remove gold now
            player.PlayerData.Gold -= (int)neededGold;
            WorldPacketFactory.SendUpdateAttributes(player, DefineAttributes.GOLD, player.PlayerData.Gold);

            // Create mail
            var mail = new DbMail
            {
                Sender       = sender,
                Receiver     = receiver,
                Gold         = e.Gold,
                Item         = item,
                ItemQuantity = item is null ? (short)0 : e.ItemQuantity,
                Title        = e.Title,
                Text         = e.Text,
                HasBeenRead  = false
            };

            database.Mails.Create(mail);
            database.Complete();
            WorldPacketFactory.SendAddDiagText(player, textClient["TID_MAIL_SEND_OK"]);

            // Send message to receiver when he's online
            var worldServer    = DependencyContainer.Instance.Resolve <IWorldServer>();
            var receiverEntity = worldServer.GetPlayerEntity(e.Receiver);

            if (receiverEntity != null)
            {
                receiverEntity.PlayerData.Mode |= ModeType.MODE_MAILBOX;
                WorldPacketFactory.SendModifyMode(receiverEntity);
            }
        }