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); }
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); } }