|  |  |  | @ -17,29 +17,31 @@ import java.util.concurrent.LinkedBlockingQueue;@@ -17,29 +17,31 @@ import java.util.concurrent.LinkedBlockingQueue; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.concurrent.atomic.LongAdder; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.regex.Pattern; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /** | 
			
		
	
		
			
				
					|  |  |  |  |  * 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. | 
			
		
	
		
			
				
					|  |  |  |  |  */ | 
			
		
	
		
			
				
					|  |  |  |  | // MB Dev Notes:
 | 
			
		
	
		
			
				
					|  |  |  |  | // All outgoing Protocol messages to the player are managed through the MessageDispatcher.class.
 | 
			
		
	
		
			
				
					|  |  |  |  | // All incoming Protocol messages from the player are managed by the Protocol.class.
 | 
			
		
	
		
			
				
					|  |  |  |  | //
 | 
			
		
	
		
			
				
					|  |  |  |  | // A DispatchMessage is configured then wrapped in a Dispatch for a distribution list.
 | 
			
		
	
		
			
				
					|  |  |  |  | // A Dispatch can be submitted to the Dispatcher from any thread.
 | 
			
		
	
		
			
				
					|  |  |  |  | //
 | 
			
		
	
		
			
				
					|  |  |  |  | // Dispatches are interleaved between channels.  This is to ensure
 | 
			
		
	
		
			
				
					|  |  |  |  | // a combat or movement message is not delayed by spam clicking a
 | 
			
		
	
		
			
				
					|  |  |  |  | // larger message.  Choose your channel wisely.
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | public class MessageDispatcher implements Runnable { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // Instance variables
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @SuppressWarnings("unchecked") // Cannot have arrays of generics in java.
 | 
			
		
	
		
			
				
					|  |  |  |  |     private static final ConcurrentLinkedQueue<Dispatch>[] _messageQueue = new ConcurrentLinkedQueue[DispatchChannel.values().length]; | 
			
		
	
		
			
				
					|  |  |  |  |     private static final LinkedBlockingQueue<Boolean> _blockingQueue = new LinkedBlockingQueue<>(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // Class variables
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public static volatile long[] messageCount = new long[DispatchChannel.values().length]; | 
			
		
	
		
			
				
					|  |  |  |  |     public static LongAdder[] dispatchCount = new LongAdder[DispatchChannel.values().length]; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // Performance metrics
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public static volatile long[] maxRecipients = new long[DispatchChannel.values().length]; | 
			
		
	
		
			
				
					|  |  |  |  |     public static LongAdder itemPoolSize = new LongAdder(); | 
			
		
	
		
			
				
					|  |  |  |  |     private final Pattern filterPattern; // Unused, but just in case
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -61,6 +63,35 @@ public class MessageDispatcher implements Runnable {@@ -61,6 +63,35 @@ public class MessageDispatcher implements Runnable { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Override | 
			
		
	
		
			
				
					|  |  |  |  |     public void run() { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         boolean shouldBlock; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         while (true) { | 
			
		
	
		
			
				
					|  |  |  |  |             try { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 shouldBlock = true; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 for (DispatchChannel dispatchChannel : DispatchChannel.values()) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     this.messageDispatch = _messageQueue[dispatchChannel.getChannelID()].poll(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if (this.messageDispatch != null) { | 
			
		
	
		
			
				
					|  |  |  |  |                         DispatchMessage.serializeDispatch(this.messageDispatch); | 
			
		
	
		
			
				
					|  |  |  |  |                         shouldBlock = false; | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (shouldBlock == true) | 
			
		
	
		
			
				
					|  |  |  |  |                     shouldBlock = _blockingQueue.take(); | 
			
		
	
		
			
				
					|  |  |  |  |             } catch (Exception e) { | 
			
		
	
		
			
				
					|  |  |  |  |                 Logger.error(e); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public static void send(Dispatch messageDispatch, DispatchChannel dispatchChannel) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         // Don't queue up empty dispatches!
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -74,12 +105,11 @@ public class MessageDispatcher implements Runnable {@@ -74,12 +105,11 @@ public class MessageDispatcher implements Runnable { | 
			
		
	
		
			
				
					|  |  |  |  |         // Update performance metrics
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         messageCount[dispatchChannel.getChannelID()]++; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public static String getNetstatString() { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         String outString = null; | 
			
		
	
		
			
				
					|  |  |  |  |         String outString; | 
			
		
	
		
			
				
					|  |  |  |  |         String newLine = System.getProperty("line.separator"); | 
			
		
	
		
			
				
					|  |  |  |  |         outString = "[LUA_NETSTA()]" + newLine; | 
			
		
	
		
			
				
					|  |  |  |  |         outString += "poolSize: " + itemPoolSize.longValue() + '\n'; | 
			
		
	
	
		
			
				
					|  |  |  | @ -94,37 +124,6 @@ public class MessageDispatcher implements Runnable {@@ -94,37 +124,6 @@ public class MessageDispatcher implements Runnable { | 
			
		
	
		
			
				
					|  |  |  |  |         return outString; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Override | 
			
		
	
		
			
				
					|  |  |  |  |     public void run() { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         boolean shouldBlock; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         while (true) { | 
			
		
	
		
			
				
					|  |  |  |  |             try { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 shouldBlock = true; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 for (DispatchChannel dispatchChannel : DispatchChannel.values()) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     this.messageDispatch = _messageQueue[dispatchChannel.getChannelID()].poll(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if (this.messageDispatch != null) { | 
			
		
	
		
			
				
					|  |  |  |  |                         DispatchMessage.serializeDispatch(this.messageDispatch); | 
			
		
	
		
			
				
					|  |  |  |  |                         shouldBlock = false; | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (shouldBlock == true) | 
			
		
	
		
			
				
					|  |  |  |  |                     shouldBlock = _blockingQueue.take(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             } catch (Exception e) { | 
			
		
	
		
			
				
					|  |  |  |  |                 Logger.error(e); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // For Debugging:
 | 
			
		
	
		
			
				
					|  |  |  |  |     //Logger.error("MessageDispatcher", messageDispatch.msg.getOpcodeAsString() + " sent to " + messageDispatch.playerList.size() + " players");
 | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
	
		
			
				
					|  |  |  | 
 |