forked from MagicBane/Server
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
422 lines
14 KiB
422 lines
14 KiB
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . |
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· |
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ |
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ |
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ |
|
// Magicbane Emulator Project © 2013 - 2022 |
|
// www.magicbane.com |
|
|
|
|
|
package engine.net.client.msg; |
|
|
|
import engine.gameManager.BuildingManager; |
|
import engine.gameManager.ForgeManager; |
|
import engine.loot.WorkOrder; |
|
import engine.mbEnums; |
|
import engine.mbEnums.GameObjectType; |
|
import engine.net.*; |
|
import engine.objects.Building; |
|
import engine.objects.Item; |
|
import engine.objects.NPC; |
|
|
|
import java.util.HashMap; |
|
|
|
public class ItemProductionMsg extends ClientNetMsg { |
|
|
|
public int size; |
|
public int buildingUUID; |
|
public int unknown01; |
|
public int itemUUID; |
|
public int itemType; |
|
public int total_to_produce; |
|
public int unknown03; |
|
public int pToken; |
|
public int sToken; |
|
public String name; |
|
public mbEnums.ProductionActionType actionType; |
|
public int npcUUID; |
|
public boolean add; |
|
public int itemPrice; |
|
public HashMap<Integer, Integer> items; |
|
|
|
/** |
|
* This is the general purpose constructor. |
|
*/ |
|
|
|
public ItemProductionMsg() { |
|
super(Protocol.ITEMPRODUCTION); |
|
this.actionType = mbEnums.ProductionActionType.NONE; |
|
this.size = 0; |
|
this.buildingUUID = 0; |
|
this.unknown01 = 0; |
|
this.itemUUID = 0; |
|
this.total_to_produce = 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, mbEnums.ProductionActionType 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.total_to_produce = 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.ordinal()); |
|
writer.putInt(GameObjectType.Building.ordinal()); |
|
writer.putInt(this.buildingUUID); |
|
writer.putInt(GameObjectType.NPC.ordinal()); |
|
writer.putInt(this.npcUUID); |
|
|
|
switch (this.actionType) { |
|
|
|
case 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 = Item.getFromCache(this.itemUUID); // Negative ID items not sent here. Deposit virtual item? |
|
|
|
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 = 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; |
|
case 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 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 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 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 TAKE: |
|
case 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.items != null) { |
|
writer.putInt(this.items.size()); |
|
|
|
for (int itemID : this.items.keySet()) { |
|
writer.putInt(this.items.get(itemID)); |
|
writer.putInt(itemID); |
|
} |
|
|
|
} else |
|
writer.putInt(0); |
|
|
|
writer.putInt(0); |
|
|
|
break; |
|
case CONFIRM_PRODUCE: |
|
writer.putInt(0); |
|
writer.putInt(0); |
|
writer.putInt(1); |
|
Item toRoll = Item.getFromCache(this.itemUUID); |
|
writer.putInt(-1497023830); |
|
|
|
WorkOrder workOrder = ForgeManager.itemWorkOrderLookup.get(toRoll); |
|
|
|
this.pToken = toRoll.prefixToken; |
|
this.sToken = toRoll.suffixToken; |
|
|
|
if (toRoll.isComplete() || (workOrder.prefixToken != 0 && workOrder.suffixToken != 0)) { |
|
writer.putInt(this.pToken); |
|
writer.putInt(this.sToken); |
|
} else { |
|
writer.putInt(0); |
|
writer.putInt(0); |
|
} |
|
|
|
writer.putString(toRoll.name); |
|
writer.putInt(toRoll.getObjectType().ordinal()); |
|
writer.putInt(this.itemUUID); |
|
writer.putInt(0); //items left to produce? |
|
|
|
writer.putInt(toRoll.templateID); |
|
writer.putInt(toRoll.getValue()); |
|
|
|
NPC vendor = NPC.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.templateID)); |
|
} |
|
|
|
} 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 COMPLETE: |
|
writer.putInt(this.itemType); |
|
writer.putInt(this.itemUUID); |
|
writer.putInt(this.total_to_produce); |
|
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 JUNK: |
|
writer.putInt(this.itemType); |
|
writer.putInt(this.itemUUID); |
|
writer.putInt(this.total_to_produce); |
|
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 = mbEnums.ProductionActionType.values()[reader.getInt()]; |
|
reader.getInt(); // Building type padding |
|
this.buildingUUID = reader.getInt(); |
|
reader.getInt(); // NPC type padding |
|
this.npcUUID = reader.getInt(); |
|
|
|
switch (this.actionType) { |
|
case 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 RECYCLE: |
|
case TAKE: |
|
reader.getInt(); |
|
reader.getInt(); |
|
reader.getInt(); |
|
reader.getInt(); |
|
reader.getInt(); |
|
reader.getInt(); |
|
reader.getInt(); |
|
reader.get(); |
|
this.size = reader.getInt(); |
|
HashMap<Integer, Integer> 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.items = tempIDs; |
|
break; |
|
case 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 JUNK: |
|
this.itemType = reader.getInt(); |
|
this.itemUUID = reader.getInt(); |
|
this.total_to_produce = 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.total_to_produce = reader.getInt(); |
|
this.unknown03 = reader.getInt(); |
|
this.pToken = reader.getInt(); |
|
this.sToken = reader.getInt(); |
|
this.name = reader.getString(); |
|
this.size = reader.getInt(); |
|
reader.getInt(); |
|
|
|
if (this.actionType == mbEnums.ProductionActionType.COMPLETE || this.actionType == mbEnums.ProductionActionType.JUNK) |
|
reader.get(); |
|
else |
|
reader.getShort(); |
|
break; |
|
} |
|
} |
|
|
|
}
|
|
|