forked from MagicBane/Server
				
			
				 13 changed files with 59 additions and 1803 deletions
			
			
		@ -1,135 +0,0 @@
				@@ -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");
 | 
				
			||||
} | 
				
			||||
@ -1,86 +0,0 @@
				@@ -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); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						@ -1,225 +0,0 @@
				@@ -1,225 +0,0 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.objects; | 
				
			||||
 | 
				
			||||
import engine.gameManager.PowersManager; | 
				
			||||
import engine.mbEnums.DispatchChannel; | 
				
			||||
import engine.net.DispatchMessage; | 
				
			||||
import engine.net.client.msg.ItemProductionMsg; | 
				
			||||
import engine.powers.EffectsBase; | 
				
			||||
import org.joda.time.DateTime; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.Date; | 
				
			||||
 | 
				
			||||
public class ProducedItem { | 
				
			||||
 | 
				
			||||
    private int ID; | 
				
			||||
    private int npcUID; | 
				
			||||
    private int templateID; | 
				
			||||
    private DateTime dateToUpgrade; | 
				
			||||
    private boolean isRandom; | 
				
			||||
 | 
				
			||||
    private String prefix; | 
				
			||||
    private String suffix; | 
				
			||||
    private String name; | 
				
			||||
    private int amount; | 
				
			||||
    private int producedItemID = 0; | 
				
			||||
    private boolean inForge; | 
				
			||||
    private int value; | 
				
			||||
 | 
				
			||||
    private int playerID; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * ResultSet Constructor | 
				
			||||
     */ | 
				
			||||
 | 
				
			||||
    public ProducedItem(ResultSet rs) throws SQLException { | 
				
			||||
        this.ID = rs.getInt("ID"); | 
				
			||||
        this.npcUID = rs.getInt("npcUID"); | 
				
			||||
        this.templateID = rs.getInt("templateID"); | 
				
			||||
 | 
				
			||||
        Date sqlDateTime = rs.getTimestamp("dateToUpgrade"); | 
				
			||||
 | 
				
			||||
        if (sqlDateTime != null) | 
				
			||||
            this.dateToUpgrade = new DateTime(sqlDateTime); | 
				
			||||
        else | 
				
			||||
            dateToUpgrade = null; | 
				
			||||
        this.isRandom = rs.getBoolean("isRandom"); | 
				
			||||
        this.prefix = rs.getString("prefix"); | 
				
			||||
        this.suffix = rs.getString("suffix"); | 
				
			||||
        this.name = rs.getString("name"); | 
				
			||||
        this.inForge = rs.getBoolean("inForge"); | 
				
			||||
        this.value = rs.getInt("value"); | 
				
			||||
        this.playerID = rs.getInt("playerID"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public ProducedItem(int ID, int npcUID, int templateID, DateTime dateToUpgrade, boolean isRandom, String prefix, String suffix, String name, int playerID) { | 
				
			||||
        super(); | 
				
			||||
        this.ID = ID; | 
				
			||||
        this.npcUID = npcUID; | 
				
			||||
        this.templateID = templateID; | 
				
			||||
        this.dateToUpgrade = dateToUpgrade; | 
				
			||||
        this.isRandom = isRandom; | 
				
			||||
        this.prefix = prefix; | 
				
			||||
        this.suffix = suffix; | 
				
			||||
        this.name = name; | 
				
			||||
        this.value = 0; | 
				
			||||
        this.playerID = playerID; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public int getNpcUID() { | 
				
			||||
        return npcUID; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public DateTime getDateToUpgrade() { | 
				
			||||
        return dateToUpgrade; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public int getTemplateID() { | 
				
			||||
        return templateID; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void setTemplateID(int templateID) { | 
				
			||||
        this.templateID = templateID; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public boolean isRandom() { | 
				
			||||
        return isRandom; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void setRandom(boolean isRandom) { | 
				
			||||
        this.isRandom = isRandom; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public String getPrefix() { | 
				
			||||
        return prefix; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public String getSuffix() { | 
				
			||||
        return suffix; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void setSuffix(String suffix) { | 
				
			||||
        this.suffix = suffix; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public String getName() { | 
				
			||||
        return name; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void setName(String name) { | 
				
			||||
        this.name = name; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public int getID() { | 
				
			||||
        return ID; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void setID(int iD) { | 
				
			||||
        ID = iD; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public int getAmount() { | 
				
			||||
        return amount; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void setAmount(int amount) { | 
				
			||||
        this.amount = amount; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
 | 
				
			||||
    public int getProducedItemID() { | 
				
			||||
        return producedItemID; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void setProducedItemID(int producedItemID) { | 
				
			||||
        this.producedItemID = producedItemID; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public boolean isInForge() { | 
				
			||||
        return inForge; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public int getValue() { | 
				
			||||
        return value; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void setValue(int value) { | 
				
			||||
        this.value = value; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public boolean finishProduction() { | 
				
			||||
        NPC npc = NPC.getFromCache(this.getNpcUID()); | 
				
			||||
 | 
				
			||||
        if (npc == null) | 
				
			||||
            return false; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
        //update the client to ID the item in the window when item finishes rolling.
 | 
				
			||||
        //If there is more than 1 item left to roll, complete the item and throw it in inventory
 | 
				
			||||
        //and reproduce next item.
 | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
 | 
				
			||||
            if (this.getAmount() > 1) { | 
				
			||||
                this.setAmount(this.getAmount() - 1); | 
				
			||||
                npc.completeItem(this.getProducedItemID()); | 
				
			||||
 | 
				
			||||
                int pToken = 0; | 
				
			||||
                int sToken = 0; | 
				
			||||
 | 
				
			||||
                if (!this.isRandom()) { | 
				
			||||
                    EffectsBase eb = PowersManager.getEffectByIDString(this.getPrefix()); | 
				
			||||
                    if (eb != null) | 
				
			||||
                        pToken = eb.getToken(); | 
				
			||||
                    eb = PowersManager.getEffectByIDString(this.getSuffix()); | 
				
			||||
                    if (eb != null) | 
				
			||||
                        sToken = eb.getToken(); | 
				
			||||
 | 
				
			||||
                } | 
				
			||||
 | 
				
			||||
                Item item = npc.produceItem(0, this.getAmount(), this.isRandom(), pToken, sToken, this.getName(), this.getTemplateID()); | 
				
			||||
 | 
				
			||||
                if (item == null) | 
				
			||||
                    return false; | 
				
			||||
 | 
				
			||||
            } else { | 
				
			||||
 | 
				
			||||
                //update item to complete
 | 
				
			||||
                MobLoot targetItem = MobLoot.getFromCache(this.getProducedItemID()); | 
				
			||||
 | 
				
			||||
                if (targetItem == null) | 
				
			||||
                    return false; | 
				
			||||
 | 
				
			||||
                ItemProductionMsg outMsg = new ItemProductionMsg(npc.getBuilding(), npc, targetItem, 8, true); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
                DispatchMessage.dispatchMsgToInterestArea(npc, outMsg, DispatchChannel.SECONDARY, 700, false, false); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
        } catch (Exception e) { | 
				
			||||
            Logger.error(e); | 
				
			||||
            return false; | 
				
			||||
        } | 
				
			||||
        return true; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public int getPlayerID() { | 
				
			||||
        return playerID; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
 | 
				
			||||
} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue