// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // Magicbane Emulator Project © 2013 - 2022 // www.magicbane.com package engine.net.client.msg; import engine.Enum.GameObjectType; import engine.gameManager.BuildingManager; import engine.gameManager.NPCManager; import engine.gameManager.PowersManager; import engine.net.AbstractConnection; import engine.net.AbstractNetMsg; import engine.net.ByteBufferReader; import engine.net.ByteBufferWriter; import engine.net.client.Protocol; import engine.objects.Building; import engine.objects.Item; import engine.objects.MobLoot; import engine.objects.NPC; import engine.powers.EffectsBase; import java.util.ArrayList; import java.util.HashMap; public class ItemProductionMsg extends ClientNetMsg { private static final int ACTION_PRODUCE = 1; private static final int ACTION_JUNK = 2; private static final int ACTION_RECYCLE = 3; private static final int ACTION_COMPLETE = 4; private static final int ACTION_DEPOSIT = 6; private static final int ACTION_SETPRICE = 5; private static final int ACTION_TAKE = 7; private static final int ACTION_CONFIRM_SETPRICE = 9; private static final int ACTION_CONFIRM_DEPOSIT = 10; private static final int ACTION_CONFIRM_TAKE = 11; // Unsure. Sent by client private static final int ACTION_CONFIRM_PRODUCE = 8; private ArrayList ItemList; private int size; private int buildingUUID; private int unknown01; private int itemUUID; private int itemType; private int totalProduction; private int unknown03; private int pToken; private int sToken; private String name; private int actionType; private int npcUUID; private boolean add; private int itemPrice; private boolean isMultiple; private HashMap itemIDtoTypeMap; /** * This is the general purpose constructor. */ public ItemProductionMsg() { super(Protocol.ITEMPRODUCTION); this.actionType = 0; this.size = 0; this.buildingUUID = 0; this.unknown01 = 0; this.itemUUID = 0; this.totalProduction = 0; this.unknown03 = 0; this.pToken = 0; this.sToken = 0; this.name = ""; this.itemPrice = 0; this.itemType = 0; } ; public ItemProductionMsg(Building building, NPC vendor, Item item, int actionType, boolean add) { super(Protocol.ITEMPRODUCTION); this.actionType = actionType; this.size = 0; this.buildingUUID = building.getObjectUUID(); this.npcUUID = vendor.getObjectUUID(); this.itemType = item.getObjectType().ordinal(); this.itemUUID = item.getObjectUUID(); this.unknown01 = 0; this.totalProduction = 0; this.unknown03 = 0; this.pToken = 0; this.sToken = 0; this.name = ""; this.add = add; this.itemPrice = item.getValue(); } /** * This constructor is used by NetMsgFactory. It attempts to deserialize the * ByteBuffer into a message. If a BufferUnderflow occurs (based on reading * past the limit) then this constructor Throws that Exception to the * caller. */ public ItemProductionMsg(AbstractConnection origin, ByteBufferReader reader) { super(Protocol.ITEMPRODUCTION, origin, reader); } /** * @see AbstractNetMsg#getPowerOfTwoBufferSize() */ @Override protected int getPowerOfTwoBufferSize() { //Larger size for historically larger opcodes return (16); // 2^16 == 64k } /** * Serializes the subclass specific items to the supplied NetMsgWriter. */ @Override protected void _serialize(ByteBufferWriter writer) { Building building = BuildingManager.getBuildingFromCache(this.buildingUUID); if (building == null) return; // Common Header writer.putInt(this.actionType); writer.putInt(GameObjectType.Building.ordinal()); writer.putInt(this.buildingUUID); writer.putInt(GameObjectType.NPC.ordinal()); writer.putInt(this.npcUUID); switch (this.actionType) { case ACTION_CONFIRM_DEPOSIT: writer.putInt(0); // Not item ordinal? writer.putInt(0); // Not item uuid? writer.putInt(1); writer.putInt(0); if (!add) { writer.put((byte) 1); Item item = Item.getFromCache(this.itemUUID); if (item != null) Item.serializeForClientMsgWithoutSlot(item, writer); writer.putInt(building.getStrongboxValue()); writer.putInt(0); writer.putInt(0); writer.put((byte) 0); break; } writer.putInt(0); writer.putInt(0); writer.putInt(0); writer.put((byte) 1); Item item; if (this.itemType == GameObjectType.Item.ordinal()) item = Item.getFromCache(this.itemUUID); else item = MobLoot.getFromCache(this.itemUUID); if (item != null) Item.serializeForClientMsgWithoutSlot(item, writer); writer.putInt(building.getStrongboxValue()); writer.putInt(0); writer.putInt(0); writer.put((byte) 0); break; case ACTION_CONFIRM_TAKE: writer.putInt(this.itemType); writer.putInt(this.itemUUID); writer.putInt(1); writer.putInt(0); writer.putInt(0); writer.putInt(0); writer.putInt(0); writer.putInt(0); writer.putInt(0); writer.put((byte) 0); break; case ACTION_SETPRICE: writer.putInt(this.itemType); writer.putInt(this.itemUUID); writer.putInt(1); writer.putInt(0); writer.putInt(0); writer.putInt(0); writer.putInt(0); writer.putInt(this.itemPrice); // new price writer.putInt(0); writer.putInt(0); writer.put((byte) 0); break; case ACTION_CONFIRM_SETPRICE: writer.putInt(this.itemType); writer.putInt(this.itemUUID); writer.putInt(1); writer.putInt(0); writer.putInt(0); writer.putInt(0); writer.putInt(0); writer.put((byte) 1); writer.putInt(building.getStrongboxValue()); // new price writer.putInt(0); writer.putInt(0); //writer.put((byte) 0); break; case ACTION_DEPOSIT: writer.putInt(this.itemType); writer.putInt(this.itemUUID); writer.putInt(1); writer.putInt(0); writer.putInt(0); writer.putInt(0); writer.putInt(0); writer.putInt(0); writer.putInt(0); writer.put((byte) 0); break; case ACTION_TAKE: case ACTION_RECYCLE: writer.putInt(0); writer.putInt(0); writer.putInt(1); writer.putInt(0); writer.putInt(0); writer.putInt(0); writer.putInt(0); writer.put((byte) 1); writer.putInt(building.getStrongboxValue()); if (this.itemIDtoTypeMap != null) { writer.putInt(this.itemIDtoTypeMap.size()); for (int itemID : this.itemIDtoTypeMap.keySet()) { writer.putInt(this.itemIDtoTypeMap.get(itemID)); writer.putInt(itemID); } } else writer.putInt(0); writer.putInt(0); break; case ACTION_CONFIRM_PRODUCE: writer.putInt(0); writer.putInt(0); writer.putInt(1); MobLoot toRoll = MobLoot.getFromCache(this.itemUUID); writer.putInt(-1497023830); if (toRoll != null && toRoll.getPrefix() != null && !toRoll.getPrefix().isEmpty()) { EffectsBase eb = PowersManager.getEffectByIDString(toRoll.getPrefix()); if (eb == null) this.pToken = 0; else this.pToken = eb.getToken(); } if (toRoll != null && toRoll.getSuffix() != null && !toRoll.getSuffix().isEmpty()) { EffectsBase eb = PowersManager.getEffectByIDString(toRoll.getSuffix()); if (eb == null) this.sToken = 0; else this.sToken = eb.getToken(); } if (toRoll.isRandom() == false || (toRoll != null && toRoll.isComplete())) { writer.putInt(this.pToken); writer.putInt(this.sToken); } else { writer.putInt(0); writer.putInt(0); } writer.putString(toRoll.getCustomName()); ; writer.putInt(GameObjectType.MobLoot.ordinal()); writer.putInt(this.itemUUID); writer.putInt(0); //items left to produce? if (toRoll != null) { writer.putInt(toRoll.getItemBaseID()); writer.putInt(toRoll.getValue()); } else { writer.putInt(0); writer.putInt(0); } NPC vendor = NPCManager.getFromCache(this.npcUUID); if (vendor != null) { if (toRoll.isComplete()) { writer.putInt(0); writer.putInt(0); } else { long timeLeft = toRoll.getDateToUpgrade() - System.currentTimeMillis(); timeLeft /= 1000; writer.putInt((int) timeLeft); writer.putInt(vendor.getRollingTimeInSeconds(toRoll.getItemBaseID())); } } else { writer.putInt(0); writer.putInt(0); } if (toRoll.isComplete()) writer.putInt(0); else writer.putInt(1); writer.put((byte) 0); if (toRoll != null && toRoll.isComplete()) writer.put((byte) 1); else writer.put((byte) 0); writer.put((byte) 0); writer.put((byte) 1); writer.putInt(vendor.getBuilding().getStrongboxValue()); writer.putInt(0); writer.putInt(0); //writer.putInt(0); //error popup break; case ACTION_COMPLETE: writer.putInt(this.itemType); writer.putInt(this.itemUUID); writer.putInt(this.totalProduction); writer.putInt(this.unknown03); writer.putInt(this.pToken); writer.putInt(this.sToken); writer.putInt(0); writer.putInt(0); writer.putInt(0); writer.put((byte) 0); break; case ACTION_JUNK: writer.putInt(this.itemType); writer.putInt(this.itemUUID); writer.putInt(this.totalProduction); writer.putInt(this.unknown03); writer.putInt(this.pToken); writer.putInt(this.sToken); writer.putString(this.name); writer.putInt(0); writer.putInt(0); writer.putShort((short) 0); writer.put((byte) 0); break; default: writer.putInt(0); writer.putInt(1); writer.putInt(0); writer.putInt(0); break; } } /** * Deserializes the subclass specific items from the supplied NetMsgReader. */ @Override protected void _deserialize(ByteBufferReader reader) { // Common header this.actionType = reader.getInt(); reader.getInt(); // Building type padding this.buildingUUID = reader.getInt(); reader.getInt(); // NPC type padding this.npcUUID = reader.getInt(); switch (this.actionType) { case ACTION_SETPRICE: this.itemType = reader.getInt(); this.itemUUID = reader.getInt(); reader.getInt(); reader.getInt(); reader.getInt(); reader.getInt(); reader.getInt(); this.itemPrice = reader.getInt(); reader.getInt(); reader.getInt(); reader.get(); break; case ACTION_RECYCLE: case ACTION_TAKE: reader.getInt(); reader.getInt(); reader.getInt(); reader.getInt(); reader.getInt(); reader.getInt(); reader.getInt(); reader.get(); this.size = reader.getInt(); HashMap tempIDs = new HashMap<>(); for (int i = 0; i < this.size; i++) { int type = reader.getInt(); // Item type padding this.itemUUID = reader.getInt(); tempIDs.put(this.itemUUID, type); } reader.getInt(); this.itemIDtoTypeMap = tempIDs; break; case ACTION_DEPOSIT: this.itemType = reader.getInt(); this.itemUUID = reader.getInt(); reader.getInt(); reader.getInt(); reader.getInt(); reader.getInt(); reader.getInt(); reader.getInt(); reader.getInt(); reader.get(); break; case ACTION_JUNK: this.itemType = reader.getInt(); this.itemUUID = reader.getInt(); this.totalProduction = reader.getInt(); this.unknown03 = reader.getInt(); this.pToken = reader.getInt(); this.sToken = reader.getInt(); this.name = reader.getString(); reader.getInt(); reader.getInt(); reader.get(); break; default: this.itemType = reader.getInt(); this.itemUUID = reader.getInt(); this.totalProduction = reader.getInt(); this.unknown03 = reader.getInt(); this.pToken = reader.getInt(); this.sToken = reader.getInt(); this.name = reader.getString(); this.isMultiple = reader.getInt() != 0 ? true : false; reader.getInt(); if (this.actionType == ACTION_COMPLETE || this.actionType == ACTION_JUNK) reader.get(); else reader.getShort(); break; } } public int getItemType() { return itemType; } // TODO fix ArrayList Accessability. public ArrayList getItemList() { return this.ItemList; } public void setItemList(ArrayList value) { this.ItemList = value; } public void addItem(Long item) { this.ItemList.add(item); } public int getUnknown01() { return unknown01; } public void setUnknown01(int unknown01) { this.unknown01 = unknown01; } public int getTotalProduction() { return totalProduction; } public void setTotalProduction(int unknown02) { this.totalProduction = unknown02; } public int getUnknown03() { return unknown03; } public void setUnknown03(int unknown03) { this.unknown03 = unknown03; } public int getItemUUID() { return itemUUID; } public void setItemUUID(int itemUUID) { this.itemUUID = itemUUID; } public int getpToken() { return pToken; } public void setpToken(int pToken) { this.pToken = pToken; } public int getsToken() { return sToken; } public void setsToken(int sToken) { this.sToken = sToken; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } public int getActionType() { return actionType; } public final void setActionType(int actionType) { this.actionType = actionType; } public int getNpcUUID() { return npcUUID; } public HashMap getItemIDtoTypeMap() { return itemIDtoTypeMap; } /** * @return the itemPrice */ public int getItemPrice() { return itemPrice; } public boolean isMultiple() { return isMultiple; } public void setMultiple(boolean isMultiple) { this.isMultiple = isMultiple; } }