More integration work

This commit is contained in:
2024-04-14 14:48:59 -04:00
parent 5e5b9884ef
commit 9464500e95
13 changed files with 59 additions and 1803 deletions
-135
View File
@@ -1,135 +0,0 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.net;
import engine.mbEnums.DispatchChannel;
import engine.objects.ProducedItem;
import org.pmw.tinylog.Logger;
import java.util.HashSet;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.atomic.LongAdder;
/**
* Thread blocks until MagicBane dispatch messages are
* enqueued then processes them in FIFO order. The collection
* is thread safe.
* <p>
* Any large messages not time sensitive such as load object
* sent to more than a single individual should be spawned
* individually on a DispatchMessageThread.
*/
public enum ItemProductionManager implements Runnable {
ITEMPRODUCTIONMANAGER;
// Instance variables
@SuppressWarnings("unchecked") // Cannot have arrays of generics in java.
private static final DelayQueue<ItemQueue> producedQueue = new DelayQueue<>();
public static volatile long[] messageCount = new long[DispatchChannel.values().length];
// Class variables
public static LongAdder[] dispatchCount = new LongAdder[DispatchChannel.values().length];
// Performance metrics
public static volatile long[] maxRecipients = new long[DispatchChannel.values().length];
public static LongAdder dispatchPoolSize = new LongAdder();
public static HashSet<ProducedItem> FailedItems = new HashSet<>();
public Thread itemProductionThread = null;
private ItemQueue itemQueue;
private long nextFailedItemAudit;
// Thread constructor
public static void send(ItemQueue item) {
// Don't queue up empty dispatches!
if (item == null)
return;
producedQueue.add(item);
}
public static String getNetstatString() {
String outString = null;
String newLine = System.getProperty("line.separator");
outString = "[LUA_NETSTA()]" + newLine;
outString += "poolSize: " + dispatchPoolSize.longValue() + '\n';
for (DispatchChannel dispatchChannel : DispatchChannel.values()) {
outString += "Channel: " + dispatchChannel.name() + '\n';
outString += "Dispatches: " + dispatchCount[dispatchChannel.getChannelID()].longValue() + '\n';
outString += "Messages: " + messageCount[dispatchChannel.getChannelID()] + '\n';
outString += "maxRecipients: " + maxRecipients[dispatchChannel.getChannelID()] + '\n';
}
return outString;
}
public void startMessagePump() {
itemProductionThread = new Thread(this);
itemProductionThread.setName("ItemProductionManager");
}
public void initialize() {
itemProductionThread.start();
}
@Override
public void run() {
while (true) {
try {
this.itemQueue = producedQueue.take();
if (this.itemQueue == null) {
return;
}
if (this.itemQueue != null) {
if (this.itemQueue.item == null) {
this.itemQueue.release();
return;
}
boolean created = this.itemQueue.item.finishProduction();
if (!created)
FailedItems.add(this.itemQueue.item);
this.itemQueue.release();
}
} catch (Exception e) {
Logger.error(e);
}
}
}
// For Debugging:
//Logger.error("MessageDispatcher", messageDispatch.msg.getOpcodeAsString() + " sent to " + messageDispatch.playerList.size() + " players");
}
-86
View File
@@ -1,86 +0,0 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.net;
import engine.objects.ProducedItem;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import static engine.net.MessageDispatcher.itemPoolSize;
/**
* Data class holds a message and a distribution list
*/
public class ItemQueue implements Delayed {
private static final ConcurrentLinkedQueue<ItemQueue> itemPool = new ConcurrentLinkedQueue<>();
public ProducedItem item;
public long delayTime;
public ItemQueue(ProducedItem item, long delayTime) {
this.item = item;
this.delayTime = System.currentTimeMillis() + delayTime;
}
public static ItemQueue borrow(ProducedItem item, long delayTime) {
ItemQueue itemQueue;
itemQueue = itemPool.poll();
if (itemQueue == null) {
itemQueue = new ItemQueue(item, delayTime);
} else {
itemQueue.item = item;
itemQueue.delayTime = System.currentTimeMillis() + delayTime;
itemPoolSize.decrement();
}
return itemQueue;
}
public void reset() {
this.item = null;
this.delayTime = 0;
}
public void release() {
this.reset();
itemPool.add(this);
itemPoolSize.increment();
}
@Override
public int compareTo(Delayed another) {
ItemQueue anotherTask = (ItemQueue) another;
if (this.delayTime < anotherTask.delayTime) {
return -1;
}
if (this.delayTime > anotherTask.delayTime) {
return 1;
}
return 0;
}
@Override
public long getDelay(TimeUnit unit) {
long difference = delayTime - System.currentTimeMillis();
return unit.convert(difference, TimeUnit.MILLISECONDS);
}
}
@@ -82,7 +82,7 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
WorkOrder workOrder = new WorkOrder();
workOrder.total_to_produce = msg.total_to_produce;
workOrder.vendor = vendorNPC;
workOrder.templateID = msg.templateID;
workOrder.templateID = msg.itemUUID;
workOrder.prefixToken = msg.pToken;
workOrder.suffixToken = msg.sToken;
workOrder.item_name_override = msg.name;
@@ -101,7 +101,7 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
}
break;
case JUNK:
junkItem(msg.templateID, vendorNPC, origin);
junkItem(msg.itemUUID, vendorNPC, origin);
break;
case RECYCLE:
recycleItem(msg.items, vendorNPC, origin);
@@ -110,13 +110,13 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
break;
case COMPLETE:
vendorNPC.completeItem(msg.templateID);
// todo fix vendorNPC.completeItem(msg.itemUUID);
break;
case DEPOSIT:
depositItem(msg.templateID, vendorNPC, origin);
depositItem(msg.itemUUID, vendorNPC, origin);
break;
case SETPRICE:
setItemPrice(msg.itemType, msg.templateID, msg.itemPrice, vendorNPC, origin);
setItemPrice(msg.itemType, msg.itemUUID, msg.itemPrice, vendorNPC, origin);
break;
case TAKE:
takeItem(msg.items, vendorNPC, origin);
@@ -364,7 +364,7 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
// Delete the item and cancel any pending rolling timer jobs
targetItem.recycle(vendor);
vendor.removeItemFromForge(targetItem);
// todo fix vendor.removeItemFromForge(targetItem);
// Refresh vendor's inventory to client
@@ -10,6 +10,7 @@
package engine.net.client.msg;
import engine.gameManager.BuildingManager;
import engine.gameManager.ForgeManager;
import engine.gameManager.PowersManager;
import engine.mbEnums;
import engine.mbEnums.GameObjectType;
@@ -27,7 +28,7 @@ public class ItemProductionMsg extends ClientNetMsg {
public int size;
public int buildingUUID;
public int unknown01;
public int templateID;
public int itemUUID;
public int itemType;
public int total_to_produce;
public int unknown03;
@@ -50,7 +51,7 @@ public class ItemProductionMsg extends ClientNetMsg {
this.size = 0;
this.buildingUUID = 0;
this.unknown01 = 0;
this.templateID = 0;
this.itemUUID = 0;
this.total_to_produce = 0;
this.unknown03 = 0;
this.pToken = 0;
@@ -70,7 +71,7 @@ public class ItemProductionMsg extends ClientNetMsg {
this.buildingUUID = building.getObjectUUID();
this.npcUUID = vendor.getObjectUUID();
this.itemType = item.getObjectType().ordinal();
this.templateID = item.getObjectUUID();
this.itemUUID = item.getObjectUUID();
this.unknown01 = 0;
this.total_to_produce = 0;
this.unknown03 = 0;
@@ -128,7 +129,7 @@ public class ItemProductionMsg extends ClientNetMsg {
if (!add) {
writer.put((byte) 1);
Item item = Item.getFromCache(this.templateID);
Item item = Item.getFromCache(this.itemUUID);
if (item != null)
Item.serializeForClientMsgWithoutSlot(item, writer);
writer.putInt(building.getStrongboxValue());
@@ -142,12 +143,14 @@ public class ItemProductionMsg extends ClientNetMsg {
writer.putInt(0);
writer.put((byte) 1);
Item item;
if (this.itemType == GameObjectType.Item.ordinal())
item = Item.getFromCache(this.templateID);
if (this.itemUUID > 0)
item = Item.getFromCache(this.itemUUID);
else
item = MobLoot.getFromCache(this.templateID);
item = ForgeManager.inMemoryItemLookup.get(this.itemUUID);
if (item != null)
Item.serializeForClientMsgWithoutSlot(item, writer);
writer.putInt(building.getStrongboxValue());
writer.putInt(0);
writer.putInt(0);
@@ -155,7 +158,7 @@ public class ItemProductionMsg extends ClientNetMsg {
break;
case CONFIRM_TAKE:
writer.putInt(this.itemType);
writer.putInt(this.templateID);
writer.putInt(this.itemUUID);
writer.putInt(1);
writer.putInt(0);
writer.putInt(0);
@@ -167,7 +170,7 @@ public class ItemProductionMsg extends ClientNetMsg {
break;
case SETPRICE:
writer.putInt(this.itemType);
writer.putInt(this.templateID);
writer.putInt(this.itemUUID);
writer.putInt(1);
writer.putInt(0);
writer.putInt(0);
@@ -180,7 +183,7 @@ public class ItemProductionMsg extends ClientNetMsg {
break;
case CONFIRM_SETPRICE:
writer.putInt(this.itemType);
writer.putInt(this.templateID);
writer.putInt(this.itemUUID);
writer.putInt(1);
writer.putInt(0);
writer.putInt(0);
@@ -194,7 +197,7 @@ public class ItemProductionMsg extends ClientNetMsg {
break;
case DEPOSIT:
writer.putInt(this.itemType);
writer.putInt(this.templateID);
writer.putInt(this.itemUUID);
writer.putInt(1);
writer.putInt(0);
writer.putInt(0);
@@ -234,7 +237,7 @@ public class ItemProductionMsg extends ClientNetMsg {
writer.putInt(0);
writer.putInt(0);
writer.putInt(1);
MobLoot toRoll = MobLoot.getFromCache(this.templateID);
MobLoot toRoll = MobLoot.getFromCache(this.itemUUID);
writer.putInt(-1497023830);
if (toRoll != null && toRoll.getPrefix() != null && !toRoll.getPrefix().isEmpty()) {
@@ -262,7 +265,7 @@ public class ItemProductionMsg extends ClientNetMsg {
writer.putString(toRoll.name);
writer.putInt(GameObjectType.MobLoot.ordinal());
writer.putInt(this.templateID);
writer.putInt(this.itemUUID);
writer.putInt(0); //items left to produce?
writer.putInt(toRoll.templateID);
@@ -306,7 +309,7 @@ public class ItemProductionMsg extends ClientNetMsg {
break;
case COMPLETE:
writer.putInt(this.itemType);
writer.putInt(this.templateID);
writer.putInt(this.itemUUID);
writer.putInt(this.total_to_produce);
writer.putInt(this.unknown03);
writer.putInt(this.pToken);
@@ -318,7 +321,7 @@ public class ItemProductionMsg extends ClientNetMsg {
break;
case JUNK:
writer.putInt(this.itemType);
writer.putInt(this.templateID);
writer.putInt(this.itemUUID);
writer.putInt(this.total_to_produce);
writer.putInt(this.unknown03);
writer.putInt(this.pToken);
@@ -355,7 +358,7 @@ public class ItemProductionMsg extends ClientNetMsg {
switch (this.actionType) {
case SETPRICE:
this.itemType = reader.getInt();
this.templateID = reader.getInt();
this.itemUUID = reader.getInt();
reader.getInt();
reader.getInt();
reader.getInt();
@@ -380,15 +383,15 @@ public class ItemProductionMsg extends ClientNetMsg {
HashMap<Integer, Integer> tempIDs = new HashMap<>();
for (int i = 0; i < this.size; i++) {
int type = reader.getInt(); // Item type padding
this.templateID = reader.getInt();
tempIDs.put(this.templateID, type);
this.itemUUID = reader.getInt();
tempIDs.put(this.itemUUID, type);
}
reader.getInt();
this.items = tempIDs;
break;
case DEPOSIT:
this.itemType = reader.getInt();
this.templateID = reader.getInt();
this.itemUUID = reader.getInt();
reader.getInt();
reader.getInt();
reader.getInt();
@@ -400,7 +403,7 @@ public class ItemProductionMsg extends ClientNetMsg {
break;
case JUNK:
this.itemType = reader.getInt();
this.templateID = reader.getInt();
this.itemUUID = reader.getInt();
this.total_to_produce = reader.getInt();
this.unknown03 = reader.getInt();
this.pToken = reader.getInt();
@@ -412,7 +415,7 @@ public class ItemProductionMsg extends ClientNetMsg {
break;
default:
this.itemType = reader.getInt();
this.templateID = reader.getInt();
this.itemUUID = reader.getInt();
this.total_to_produce = reader.getInt();
this.unknown03 = reader.getInt();
this.pToken = reader.getInt();
+2 -1
View File
@@ -9,6 +9,7 @@
package engine.net.client.msg;
import engine.gameManager.ForgeManager;
import engine.gameManager.NPCManager;
import engine.gameManager.PowersManager;
import engine.mbEnums.GameObjectType;
@@ -435,7 +436,7 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.put((byte) template.modTable);//EffectItemType
}
List<MobLoot> itemList = npc.getRolling();
List<Item> itemList = ForgeManager.vendorItemLookup.get(npc);
itemList = itemList.stream().limit(npc.getRank()).collect(Collectors.toList());
writer.putInt(itemList.size());