/* * This file is part of aion-unique <aion-unique.org>. * * aion-unique is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * aion-unique is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with aion-unique. If not, see <http://www.gnu.org/licenses/>. */ package com.aionemu.gameserver.services; import java.sql.Timestamp; import java.util.Calendar; import java.util.Collections; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import org.apache.log4j.Logger; import com.aionemu.commons.database.dao.DAOManager; import com.aionemu.gameserver.dao.InventoryDAO; import com.aionemu.gameserver.dao.MailDAO; import com.aionemu.gameserver.dao.PlayerDAO; import com.aionemu.gameserver.model.gameobjects.Item; import com.aionemu.gameserver.model.gameobjects.Letter; import com.aionemu.gameserver.model.gameobjects.player.Mailbox; import com.aionemu.gameserver.model.gameobjects.player.Player; import com.aionemu.gameserver.model.gameobjects.player.PlayerCommonData; import com.aionemu.gameserver.model.gameobjects.player.Storage; import com.aionemu.gameserver.model.gameobjects.player.StorageType; import com.aionemu.gameserver.model.templates.mail.MailMessage; import com.aionemu.gameserver.network.aion.serverpackets.SM_DELETE_ITEM; import com.aionemu.gameserver.network.aion.serverpackets.SM_INVENTORY_UPDATE; import com.aionemu.gameserver.network.aion.serverpackets.SM_MAIL_SERVICE; import com.aionemu.gameserver.network.aion.serverpackets.SM_SYSTEM_MESSAGE; import com.aionemu.gameserver.network.aion.serverpackets.SM_UPDATE_ITEM; import com.aionemu.gameserver.utils.PacketSendUtility; import com.aionemu.gameserver.utils.ThreadPoolManager; import com.aionemu.gameserver.utils.idfactory.IDFactory; import com.aionemu.gameserver.utils.idfactory.IDFactoryAionObject; import com.aionemu.gameserver.world.World; import com.google.inject.Inject; /** * @author kosyachok * */ public class MailService { private static final Logger log = Logger.getLogger(MailService.class); private IDFactory aionObjectsIDFactory; private World world; private ItemService itemService; protected Queue<Player> newPlayers = new ConcurrentLinkedQueue<Player>(); @Inject public MailService(@IDFactoryAionObject IDFactory aionObjectsIDFactory, World world, ItemService itemService) { this.aionObjectsIDFactory = aionObjectsIDFactory; this.world = world; this.itemService = itemService; } /** * * @param sender * @param recipientName * @param title * @param message * @param attachedItemObjId * @param attachedItemCount * @param attachedKinahCount * @param express */ public void sendMail(Player sender, String recipientName, String title, String message, int attachedItemObjId, int attachedItemCount, int attachedKinahCount, boolean express) { if(express) // TODO express mail return; if(recipientName.length() > 16) return; if(title.length() > 20) title = title.substring(0, 20); if(message.length() > 1000) message = message.substring(0, 1000); if(!DAOManager.getDAO(PlayerDAO.class).isNameUsed(recipientName)) { // TODO retail message PacketSendUtility.sendMessage(sender, "Incorrect recipient name"); return; } PlayerCommonData recipientCommonData = DAOManager.getDAO(PlayerDAO.class).loadPlayerCommonDataByName( recipientName, world); Player onlineRecipient; if(recipientCommonData == null) { PacketSendUtility.sendPacket(sender, new SM_MAIL_SERVICE(MailMessage.NO_SUCH_CHARACTER_NAME)); return; } if(recipientCommonData.getRace().getRaceId() != sender.getCommonData().getRace().getRaceId()) { PacketSendUtility.sendPacket(sender, new SM_MAIL_SERVICE(MailMessage.MAIL_IS_ONE_RACE_ONLY)); return; } if(recipientCommonData.isOnline()) { onlineRecipient = world.findPlayer(recipientCommonData.getPlayerObjId()); if(!onlineRecipient.getMailbox().haveFreeSlots()) { PacketSendUtility.sendPacket(sender, new SM_MAIL_SERVICE(MailMessage.RECIPIENT_MAILBOX_FULL)); return; } } else { if(recipientCommonData.getMailboxLetters() >= 100) { PacketSendUtility.sendPacket(sender, new SM_MAIL_SERVICE(MailMessage.RECIPIENT_MAILBOX_FULL)); return; } onlineRecipient = null; } if(!validateMailSendPrice(sender, attachedKinahCount, attachedItemObjId, attachedItemCount)) return; Item attachedItem = null; int finalAttachedKinahCount = 0; int kinahMailCommission = 0; int itemMailCommission = 0; Storage senderInventory = sender.getInventory(); if(attachedItemObjId != 0) { Item senderItem = senderInventory.getItemByObjId(attachedItemObjId); if(senderItem != null) { float qualityPriceRate; switch(senderItem.getItemTemplate().getItemQuality()) { case JUNK: case COMMON: qualityPriceRate = 0.02f; break; case RARE: qualityPriceRate = 0.03f; break; case LEGEND: case UNIQUE: qualityPriceRate = 0.04f; break; case MYTHIC: case EPIC: qualityPriceRate = 0.05f; break; default: qualityPriceRate = 0.02f; break; } if(senderItem.getItemCount() == attachedItemCount) { senderInventory.removeFromBag(senderItem, false); PacketSendUtility.sendPacket(sender, new SM_DELETE_ITEM(attachedItemObjId)); senderItem.setEquipped(false); senderItem.setEquipmentSlot(0); senderItem.setItemLocation(StorageType.MAILBOX.getId()); attachedItem = senderItem; itemMailCommission = Math.round((senderItem.getItemTemplate().getPrice() * attachedItem .getItemCount()) * qualityPriceRate); } else if(senderItem.getItemCount() > attachedItemCount) { attachedItem = itemService.newItem(senderItem.getItemTemplate().getTemplateId(), attachedItemCount); senderItem.decreaseItemCount(attachedItemCount); PacketSendUtility.sendPacket(sender, new SM_UPDATE_ITEM(senderItem)); attachedItem.setEquipped(false); attachedItem.setEquipmentSlot(0); attachedItem.setItemLocation(StorageType.MAILBOX.getId()); itemMailCommission = Math.round((attachedItem.getItemTemplate().getPrice() * attachedItem .getItemCount()) * qualityPriceRate); } } } if(attachedKinahCount > 0) { if(senderInventory.getKinahItem().getItemCount() - attachedKinahCount >= 0) { finalAttachedKinahCount = attachedKinahCount; kinahMailCommission = Math.round(attachedKinahCount * 0.01f); } } Timestamp time = new Timestamp(Calendar.getInstance().getTimeInMillis()); Letter newLetter = new Letter(aionObjectsIDFactory.nextId(), recipientCommonData.getPlayerObjId(), attachedItem, finalAttachedKinahCount, title, message, sender.getName(), time, true, express); if(!DAOManager.getDAO(MailDAO.class).storeLetter(time, newLetter)) return; senderInventory.decreaseKinah(finalAttachedKinahCount); if(attachedItem != null) if(!DAOManager.getDAO(InventoryDAO.class).store(attachedItem, recipientCommonData.getPlayerObjId())) return; int finalMailCommission = 10 + kinahMailCommission + itemMailCommission; senderInventory.decreaseKinah(finalMailCommission); if(onlineRecipient != null) { Mailbox recipientMailbox = onlineRecipient.getMailbox(); recipientMailbox.putLetterToMailbox(newLetter); PacketSendUtility.sendPacket(onlineRecipient, new SM_MAIL_SERVICE(onlineRecipient, onlineRecipient .getMailbox().getLetters())); PacketSendUtility.sendPacket(onlineRecipient, new SM_MAIL_SERVICE(false, false)); PacketSendUtility.sendPacket(onlineRecipient, new SM_MAIL_SERVICE(true, true)); } PacketSendUtility.sendPacket(sender, new SM_MAIL_SERVICE(MailMessage.MAIL_SEND_SECCESS)); } /** * Read letter with specified letter id * * @param player * @param letterId */ public void readMail(Player player, int letterId) { Letter letter = player.getMailbox().getLetterFromMailbox(letterId); if(letter == null) { log.warn("Cannot read mail " + player.getObjectId() + " " + letterId); return; } PacketSendUtility.sendPacket(player, new SM_MAIL_SERVICE(player, letter, letter.getTimeStamp().getTime())); letter.setReadLetter(); } /** * * @param player * @param letterId * @param attachmentType */ public void getAttachments(Player player, int letterId, int attachmentType) { Letter letter = player.getMailbox().getLetterFromMailbox(letterId); if(letter == null) return; switch(attachmentType) { case 0: { Item attachedItem = letter.getAttachedItem(); if(attachedItem == null) return; if(player.getInventory().isFull()) { PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.MSG_FULL_INVENTORY); return; } Item inventoryItem = player.getInventory().putToBag(attachedItem); PacketSendUtility.sendPacket(player, new SM_INVENTORY_UPDATE(Collections.singletonList(inventoryItem))); PacketSendUtility.sendPacket(player, new SM_MAIL_SERVICE(letterId, attachmentType)); letter.removeAttachedItem(); break; } case 1: { player.getInventory().increaseKinah(letter.getAttachedKinah()); PacketSendUtility.sendPacket(player, new SM_MAIL_SERVICE(letterId, attachmentType)); letter.removeAttachedKinah(); break; } } } /** * * @param player * @param letterId */ public void deleteMail(Player player, int letterId) { Mailbox mailbox = player.getMailbox(); mailbox.removeLetter(letterId); DAOManager.getDAO(MailDAO.class).deleteLetter(letterId); PacketSendUtility.sendPacket(player, new SM_MAIL_SERVICE(letterId)); } /** * * @param sender * @param attachedKinahCount * @param attachedItemObjId * @param attachedItemCount * @return */ private boolean validateMailSendPrice(Player sender, int attachedKinahCount, int attachedItemObjId, int attachedItemCount) { int itemMailCommission = 0; int kinahMailCommission = Math.round(attachedKinahCount * 0.01f); if(attachedItemObjId != 0) { Item senderItem = sender.getInventory().getItemByObjId(attachedItemObjId); float qualityPriceRate; switch(senderItem.getItemTemplate().getItemQuality()) { case JUNK: case COMMON: qualityPriceRate = 0.02f; break; case RARE: qualityPriceRate = 0.03f; break; case LEGEND: case UNIQUE: qualityPriceRate = 0.04f; break; case MYTHIC: case EPIC: qualityPriceRate = 0.05f; break; default: qualityPriceRate = 0.02f; break; } itemMailCommission = Math.round((senderItem.getItemTemplate().getPrice() * attachedItemCount) * qualityPriceRate); } int finalMailPrice = 10 + itemMailCommission + kinahMailCommission; if(sender.getInventory().getKinahItem().getItemCount() >= finalMailPrice) return true; return false; } /** * * @param player */ public void onPlayerLogin(final Player player) { ThreadPoolManager.getInstance().schedule(new Runnable(){ @Override public void run() { player.setMailbox(DAOManager.getDAO(MailDAO.class).loadPlayerMailbox(player)); PacketSendUtility.sendPacket(player, new SM_MAIL_SERVICE(player, player.getMailbox().getLetters())); if(player.getMailbox().haveUnread()) PacketSendUtility.sendPacket(player, new SM_MAIL_SERVICE(true, true)); } }, 10000); } }