|
|
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
|
|
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
|
|
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
|
|
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
|
|
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
|
|
|
// Magicbane Emulator Project © 2013 - 2022
|
|
|
|
// www.magicbane.com
|
|
|
|
|
|
|
|
|
|
|
|
package engine.net.client.msg;
|
|
|
|
|
|
|
|
import engine.gameManager.BuildingManager;
|
|
|
|
import engine.gameManager.ForgeManager;
|
|
|
|
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;
|
|
|
|
if (this.itemUUID > 0)
|
|
|
|
item = Item.getFromCache(this.itemUUID);
|
|
|
|
else
|
|
|
|
item = ForgeManager.inMemoryItemLookup.get(this.itemUUID);
|
|
|
|
|
|
|
|
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.itemUUID > 0)
|
|
|
|
item = Item.getFromCache(this.itemUUID);
|
|
|
|
else
|
|
|
|
item = ForgeManager.inMemoryItemLookup.get(this.itemUUID);
|
|
|
|
|
|
|
|
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 = ForgeManager.inMemoryItemLookup.get(this.itemUUID);
|
|
|
|
writer.putInt(-1497023830);
|
|
|
|
|
|
|
|
this.pToken = toRoll.prefixToken;
|
|
|
|
this.sToken = toRoll.suffixToken;
|
|
|
|
|
|
|
|
if (toRoll.isComplete()) {
|
|
|
|
writer.putInt(this.pToken);
|
|
|
|
writer.putInt(this.sToken);
|
|
|
|
} else {
|
|
|
|
writer.putInt(0);
|
|
|
|
writer.putInt(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
writer.putString(toRoll.name);
|
|
|
|
writer.putInt(GameObjectType.MobLoot.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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|