// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // Magicbane Emulator Project © 2013 - 2022 // www.magicbane.com package engine.objects; import engine.Enum; import engine.gameManager.ChatManager; import engine.gameManager.DbManager; import engine.net.Dispatch; import engine.net.DispatchMessage; import engine.net.client.ClientConnection; import engine.net.client.msg.*; import engine.server.MBServerStatics; import org.joda.time.DateTime; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.pmw.tinylog.Logger; import java.sql.SQLException; import java.util.ArrayList; import java.util.EnumSet; import java.util.concurrent.ConcurrentHashMap; public class Warehouse { public EnumSet locked = EnumSet.noneOf(Enum.ResourceType.class); public int buildingUID; public City city; public ArrayList transactions = new ArrayList<>(); public ConcurrentHashMap resources = new ConcurrentHashMap<>(); public Warehouse(Building building) { this.buildingUID = building.objectUUID; this.city = building.getCity(); // New empty warehouse for (Enum.ResourceType resourceType : EnumSet.allOf(Enum.ResourceType.class)) this.resources.put(resourceType, 0); // With no locks this.locked = EnumSet.noneOf(Enum.ResourceType.class); } public Warehouse(JSONObject warehouse) throws SQLException { JSONObject resources = (JSONObject) warehouse.get("resources"); for (Object key : resources.keySet()) { Enum.ResourceType resourceType = Enum.ResourceType.valueOf((String) key); int value = ((Long) resources.get(key)).intValue(); this.resources.put(resourceType, value); } JSONArray lockedResources = (JSONArray) warehouse.get("locks"); if (lockedResources.isEmpty() == false) for (Object o : lockedResources) this.locked.add(Enum.ResourceType.valueOf((String) o)); } public static void warehouseDeposit(MerchantMsg msg, PlayerCharacter player, NPC npc) { Building warehouseBuilding; Warehouse warehouse; int depositAmount; Dispatch dispatch; Item resource = Item.getFromCache(msg.getItemID()); if (resource == null) return; depositAmount = msg.getAmount(); CharacterItemManager itemMan = player.getCharItemManager(); if (!itemMan.doesCharOwnThisItem(resource.getObjectUUID())) return; warehouseBuilding = npc.getBuilding(); if (warehouseBuilding == null) return; warehouse = warehouseBuilding.getCity().warehouse; if (warehouse == null) return; if (!deposit(player, resource, depositAmount, true, true,warehouse)) { return; } ViewResourcesMessage vrm = new ViewResourcesMessage(player); vrm.setGuild(player.getGuild()); vrm.setWarehouseBuilding(warehouseBuilding); vrm.configure(); dispatch = Dispatch.borrow(player, vrm); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); } public static void warehouseWithdraw(MerchantMsg msg, PlayerCharacter player, NPC npc) { int withdrawAmount; Building warehouseBuilding; Warehouse warehouse; Dispatch dispatch; withdrawAmount = msg.getAmount(); warehouseBuilding = npc.getBuilding(); if (warehouseBuilding == null) return; if (player.getGuild() != warehouseBuilding.getGuild() || !GuildStatusController.isInnerCouncil(player.getGuildStatus())) return; City city = warehouseBuilding.getCity(); if (city == null) return; ; warehouse = city.warehouse; if (warehouse == null) return; Enum.ResourceType resourceType = Enum.ResourceType.hashLookup.get(msg.getHashID()); if (isResourceLocked(warehouse, resourceType)) { ChatManager.chatSystemInfo(player, "You cannot withdrawl a locked resource."); return; } if (!withdraw(warehouse, player, resourceType, withdrawAmount, true, true)) { ChatManager.chatGuildError(player, "Failed to withdrawl " + resourceType.name() + '.'); Logger.debug(player.getName() + " Failed to withdrawl =" + resourceType.name() + " from Warehouse With ID = " + warehouseBuilding.getObjectUUID()); return; } ViewResourcesMessage vrm = new ViewResourcesMessage(player); vrm.setGuild(player.getGuild()); vrm.setWarehouseBuilding(warehouseBuilding); vrm.configure(); dispatch = Dispatch.borrow(player, vrm); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); } public static void warehouseLock(MerchantMsg msg, PlayerCharacter player, NPC npc) { Building warehouseBuilding; Warehouse warehouse; int hashID; Dispatch dispatch; hashID = msg.getHashID(); warehouseBuilding = npc.getBuilding(); if (warehouseBuilding == null) return; if (player.getGuild() != warehouseBuilding.getGuild() || !GuildStatusController.isInnerCouncil(player.getGuildStatus())) return; City city = warehouseBuilding.getCity(); if (city == null) return; ; warehouse = city.warehouse; Enum.ResourceType resourceType = Enum.ResourceType.hashLookup.get(hashID); // toggle lock if (warehouse.locked.contains(resourceType)) { boolean worked; warehouse.locked.remove(resourceType); worked = DbManager.WarehouseQueries.UPDATE_WAREHOUSE(warehouse); if (worked) { ViewResourcesMessage vrm = new ViewResourcesMessage(player); vrm.setGuild(player.getGuild()); vrm.setWarehouseBuilding(warehouseBuilding); vrm.configure(); dispatch = Dispatch.borrow(player, vrm); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); } else warehouse.locked.add(resourceType); return; } boolean worked; warehouse.locked.add(resourceType); worked = DbManager.WarehouseQueries.UPDATE_WAREHOUSE(warehouse); if (worked) { warehouse.locked.add(resourceType); ViewResourcesMessage vrm = new ViewResourcesMessage(player); vrm.setGuild(player.getGuild()); vrm.setWarehouseBuilding(warehouseBuilding); vrm.configure(); dispatch = Dispatch.borrow(player, vrm); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); } else warehouse.locked.remove(resourceType); } public static synchronized boolean deposit(PlayerCharacter pc, Item resource, int amount, boolean removeFromInventory, boolean transaction, Warehouse warehouse) { ClientConnection origin = pc.getClientConnection(); if (origin == null) return false; if (amount < 0) { Logger.info(pc.getFirstName() + " Attempting to Dupe!!!!!!"); return false; } Enum.ResourceType resourceType = Enum.ResourceType.resourceLookup.get(resource.templateID); if (warehouse.resources.get(resourceType) == null) return false; CharacterItemManager itemMan = pc.getCharItemManager(); if (itemMan == null) return false; if (itemMan.getGoldTrading() > 0) { ErrorPopupMsg.sendErrorPopup(pc, 195); return false; } if (!itemMan.doesCharOwnThisItem(resource.getObjectUUID())) return false; if (!resource.validForInventory(origin, pc, itemMan)) return false; if (resource.getNumOfItems() < amount) return false; int oldAmount = warehouse.resources.get(resourceType); int newAmount = oldAmount + amount; if (newAmount > Enum.ResourceType.resourceLookup.get(resource.templateID).deposit_limit) return false; if (removeFromInventory) { if (resourceType.equals(Enum.ResourceType.GOLD)) { if (itemMan.getGoldInventory().getNumOfItems() - amount < 0) return false; if (itemMan.getGoldInventory().getNumOfItems() - amount > MBServerStatics.PLAYER_GOLD_LIMIT) return false; if (!itemMan.modifyInventoryGold(-amount)) return false; UpdateGoldMsg ugm = new UpdateGoldMsg(pc); ugm.configure(); Dispatch dispatch = Dispatch.borrow(pc, ugm); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); itemMan.updateInventory(); } else { itemMan.delete(resource); itemMan.updateInventory(); } } itemMan.updateInventory(); if (newAmount > resourceType.deposit_limit) return false; warehouse.resources.put(resourceType, newAmount); if (!DbManager.WarehouseQueries.UPDATE_WAREHOUSE(warehouse)) { warehouse.resources.put(resourceType, oldAmount); return false; } if (resource.template.item_type.equals(Enum.ItemType.GOLD)) resourceType = Enum.ResourceType.GOLD; else resourceType = Enum.ResourceType.valueOf(ItemTemplate.templates.get(resource.getTemplateID()).item_base_name.toUpperCase()); if (transaction) AddTransactionToWarehouse(warehouse, pc.getObjectType(), pc.getObjectUUID(), Enum.TransactionType.DEPOSIT, resourceType, amount); return true; } public static synchronized boolean depositFromMine(Mine mine, Enum.ResourceType resourceType, int amount, Warehouse warehouse) { int oldAmount = warehouse.resources.get(resourceType); int newAmount = oldAmount + amount; if (newAmount > resourceType.deposit_limit) return false; warehouse.resources.put(resourceType, newAmount); if (!DbManager.WarehouseQueries.UPDATE_WAREHOUSE(warehouse)) { warehouse.resources.put(resourceType, oldAmount); return false; } if (mine != null) AddTransactionToWarehouse(warehouse, Enum.GameObjectType.Building, mine.getBuildingID(), Enum.TransactionType.MINE, resourceType, amount); return true; } public static synchronized void depositRealmTaxes(PlayerCharacter taxer, Enum.ResourceType resourceType, int amount, Warehouse warehouse) { int oldAmount = warehouse.resources.get(resourceType); int newAmount = oldAmount + amount; warehouse.resources.put(resourceType, newAmount); if (!DbManager.WarehouseQueries.UPDATE_WAREHOUSE(warehouse)) { warehouse.resources.put(resourceType, oldAmount); return; } AddTransactionToWarehouse(warehouse, taxer.getObjectType(), taxer.getObjectUUID(), Enum.TransactionType.TAXRESOURCEDEPOSIT, resourceType, amount); } public static synchronized void depositProfitTax(Enum.ResourceType resourceType, int amount, Building building, Warehouse warehouse) { if (warehouse.resources.get(resourceType) == null) return; int oldAmount = warehouse.resources.get(resourceType); int newAmount = oldAmount + amount; if (newAmount > resourceType.deposit_limit) return; warehouse.resources.put(resourceType, newAmount); if (!DbManager.WarehouseQueries.UPDATE_WAREHOUSE(warehouse)) { warehouse.resources.put(resourceType, oldAmount); return; } if (building != null) AddTransactionToWarehouse(warehouse, Enum.GameObjectType.Building, building.getObjectUUID(), Enum.TransactionType.DEPOSIT, resourceType, amount); } public static synchronized boolean withdraw(Warehouse warehouse, NPC npc, Enum.ResourceType resourceType, int amount, boolean transaction) { int oldAmount = warehouse.resources.get(resourceType); int newAmount = oldAmount - amount; if (warehouse.resources.get(resourceType) == null) return false; if (amount <= 0) return false; if (oldAmount < amount) return false; warehouse.resources.put(resourceType, newAmount); if (!DbManager.WarehouseQueries.UPDATE_WAREHOUSE(warehouse)) { warehouse.resources.put(resourceType, oldAmount); return false; } if (transaction) AddTransactionToWarehouse(warehouse, npc.getObjectType(), npc.getObjectUUID(), Enum.TransactionType.WITHDRAWL, resourceType, amount); return true; } public static synchronized void transferResources(Warehouse warehouse, PlayerCharacter taxer, TaxResourcesMsg msg, ArrayList realmResources, float taxPercent) { for (Enum.ResourceType resourceType : realmResources) { if (warehouse.resources.get(resourceType) == null) return; int amount = (int) (warehouse.resources.get(resourceType) * taxPercent); if (amount <= 0) { msg.getResources().put(resourceType.hash, 0); continue; } int oldAmount = warehouse.resources.get(resourceType); if (oldAmount < amount) amount = oldAmount; int newAmount = oldAmount - amount; if (newAmount < amount) continue; msg.getResources().put(resourceType.hash, amount); if (!DbManager.WarehouseQueries.UPDATE_WAREHOUSE(warehouse)) { msg.getResources().put(resourceType.hash, 0); warehouse.resources.put(resourceType, oldAmount); continue; } warehouse.resources.put(resourceType, newAmount); depositRealmTaxes(taxer, resourceType, amount, warehouse); Enum.ResourceType resource; AddTransactionToWarehouse(warehouse, taxer.getObjectType(), taxer.getObjectUUID(), Enum.TransactionType.TAXRESOURCE, resourceType, amount); } } public static synchronized boolean withdraw(Warehouse warehouse, PlayerCharacter pc, Enum.ResourceType resourceType, int amount, boolean addToInventory, boolean transaction) { if (pc == null) return false; ItemTemplate template = ItemTemplate.templates.get(resourceType.templateID); if (warehouse.resources.get(resourceType) == null) return false; if (amount <= 0) return false; CharacterItemManager itemMan = pc.getCharItemManager(); if (itemMan == null) return false; if (addToInventory) if (!itemMan.hasRoomInventory(template.item_wt * amount)) { ChatManager.chatSystemInfo(pc, "You can not carry any more of that item."); return false; } if (addToInventory && resourceType.equals(Enum.ResourceType.GOLD)) { if (pc.getCharItemManager().getGoldInventory().getNumOfItems() + amount > MBServerStatics.PLAYER_GOLD_LIMIT) return false; if (pc.getCharItemManager().getGoldInventory().getNumOfItems() + amount < 0) return false; } int oldAmount = warehouse.resources.get(resourceType); if (oldAmount < amount) return false; int newAmount = oldAmount - amount; warehouse.resources.put(resourceType, newAmount); if (!DbManager.WarehouseQueries.UPDATE_WAREHOUSE(warehouse)) { warehouse.resources.put(resourceType, oldAmount); return false; } if (addToInventory) { if (resourceType.equals(Enum.ResourceType.GOLD)) { itemMan.addGoldToInventory(amount, false); UpdateGoldMsg ugm = new UpdateGoldMsg(pc); ugm.configure(); Dispatch dispatch = Dispatch.borrow(pc, ugm); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); itemMan.updateInventory(); } else { boolean itemWorked = false; Item item = new Item(resourceType.templateID); item.ownerID = pc.getObjectUUID(); item.ownerType = Enum.OwnerType.PlayerCharacter; item.containerType = Enum.ItemContainerType.INVENTORY; item.numberOfItems = amount; try { item = DbManager.ItemQueries.PERSIST(item); itemWorked = true; } catch (Exception e) { Logger.error(e); } if (itemWorked) { itemMan.addItemToInventory(item); itemMan.updateInventory(); } } } if (transaction) AddTransactionToWarehouse(warehouse, pc.getObjectType(), pc.getObjectUUID(), Enum.TransactionType.WITHDRAWL, resourceType, amount); return true; } public static synchronized boolean loot(Warehouse warehouse, PlayerCharacter pc, Enum.ResourceType resourceType, int amount, boolean addToInventory) { if (pc == null) return false; ItemTemplate template = ItemTemplate.templates.get(resourceType); if (template == null) return false; if (warehouse.resources.get(resourceType) == null) return false; if (amount <= 0) return false; CharacterItemManager itemMan = pc.getCharItemManager(); if (itemMan == null) return false; if (!itemMan.hasRoomInventory(template.item_wt)) { ChatManager.chatSystemInfo(pc, "You can not carry any more of that item."); return false; } int oldAmount = warehouse.resources.get(resourceType); if (oldAmount < amount) return false; int newAmount = oldAmount - amount; warehouse.resources.put(resourceType, newAmount); if (addToInventory) { if (resourceType.equals(Enum.ResourceType.GOLD)) { itemMan.addGoldToInventory(amount, false); UpdateGoldMsg ugm = new UpdateGoldMsg(pc); ugm.configure(); Dispatch dispatch = Dispatch.borrow(pc, ugm); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); itemMan.updateInventory(); } else { boolean itemWorked = false; Item item = new Item(resourceType.templateID); item.ownerID = pc.getObjectUUID(); item.ownerType = Enum.OwnerType.PlayerCharacter; item.containerType = Enum.ItemContainerType.INVENTORY; item.numberOfItems = amount; try { item = DbManager.ItemQueries.PERSIST(item); itemWorked = true; } catch (Exception e) { Logger.error(e); } if (itemWorked) { itemMan.addItemToInventory(item); itemMan.updateInventory(); } } } return true; } public static boolean isEmpty(Warehouse warehouse) { int amount = 0; for (Enum.ResourceType resourceType : EnumSet.allOf(Enum.ResourceType.class)) { amount += warehouse.resources.get(resourceType); if (amount > 0) return false; } return true; } public static void loadAllTransactions(Warehouse warehouse) { warehouse.transactions = DbManager.WarehouseQueries.GET_TRANSACTIONS_FOR_WAREHOUSE(warehouse.buildingUID); } public static void AddTransactionToWarehouse(Warehouse warehouse, Enum.GameObjectType targetType, int targetUUID, Enum.TransactionType transactionType, Enum.ResourceType resource, int amount) { if (!DbManager.WarehouseQueries.CREATE_TRANSACTION(warehouse.buildingUID, targetType, targetUUID, transactionType, resource, amount, DateTime.now())) return; Transaction transaction = new Transaction(warehouse.buildingUID, targetType, targetUUID, transactionType, resource, amount, DateTime.now()); warehouse.transactions.add(transaction); } public static boolean isAboveCap(Warehouse warehouse, Enum.ResourceType resourceType, int deposit) { int newAmount = warehouse.resources.get(resourceType) + deposit; return newAmount > resourceType.deposit_limit; } public static boolean isResourceLocked(Warehouse warehouse, Enum.ResourceType resourceType) { return resourceType.elementOf(warehouse.locked); } }