context: /*
   * DAWN OF LIGHT - The first free open source DAoC server emulator
   * 
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; either version 2
   * of the License, or (at your option) any later version.
   * 
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   * 
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   *
   */
  using System;
  using System.Collections;
  using System.Collections.Specialized;
  using System.Reflection;
  using DOL.Database;
  using log4net;
  using System.Collections.Generic;
  
  namespace DOL.GS
  {
  	/// <summary>
  	/// the LootMgr holds pointers to all LootGenerators at 
  	/// associates the correct LootGenerator with a given Mob
  	/// </summary>
  	public sealed class LootMgr
  	{
  		/// <summary>
  		/// Defines a logger for this class.
  		/// </summary>
  		private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  
  		/// <summary>
  		/// Map holding one generator for each different class, to reuse similar generators...
  		/// </summary>
  		static readonly HybridDictionary m_ClassGenerators = new HybridDictionary();
  
  		/// <summary>
  		/// List of global Lootgenerators 
  		/// </summary>
  		static readonly IList m_globalGenerators = new ArrayList();
  
  		/// <summary>
  		/// List of Lootgenerators related by mobname
  		/// </summary>
  		static readonly HybridDictionary m_mobNameGenerators = new HybridDictionary();
  
  		/// <summary>
  		/// List of Lootgenerators related by mobguild
  		/// </summary>
  		static readonly HybridDictionary m_mobGuildGenerators = new HybridDictionary();
  
  		/// <summary>
  		/// List of Lootgenerators related by region ID
  		/// </summary>
  		static readonly HybridDictionary m_mobRegionGenerators = new HybridDictionary();
  
  		// /// <summary>
  		// /// List of Lootgenerators related by mobfaction
  		// /// </summary>
  		static readonly HybridDictionary m_mobFactionGenerators = new HybridDictionary();		
  
  		/// <summary>
  		/// Initializes the LootMgr. This function must be called
  		/// before the LootMgr can be used!
  		/// </summary>
  		public static bool Init()
  		{
  			if (log.IsInfoEnabled)
  				log.Info("Loading LootGenerators...");
  
  			IList<LootGenerator> m_lootGenerators;
  			try
  			{
  				m_lootGenerators = GameServer.Database.SelectAllObjects<LootGenerator>();
  			}
  			catch (Exception e)
  			{
  				if (log.IsErrorEnabled)
  					log.Error("LootMgr: LootGenerators could not be loaded", e);
  				return false;
  			}
  
  			if (m_lootGenerators != null) // did we find any loot generators
  			{
  				foreach (LootGenerator dbGenerator in m_lootGenerators)
  				{
  					ILootGenerator generator = GetGeneratorInCache(dbGenerator);
  					if (generator == null)
  					{
  						Type generatorType = null;
  						foreach (Assembly asm in ScriptMgr.Scripts)
  						{
  							generatorType = asm.GetType(dbGenerator.LootGeneratorClass);
  							if (generatorType != null)
  								break;
  						}
  						if (generatorType == null)
  						{
  							generatorType = Assembly.GetAssembly(typeof(GameServer)).GetType(dbGenerator.LootGeneratorClass);
  						}
  
  						if (generatorType == null)
  						{
  							if (log.IsErrorEnabled)
  								log.Error("Could not find LootGenerator: " + dbGenerator.LootGeneratorClass + "!!!");
  							continue;
  						}
  						generator = (ILootGenerator)Activator.CreateInstance(generatorType);
  
  						PutGeneratorInCache(dbGenerator, generator);
  					}
  					RegisterLootGenerator(generator, dbGenerator.MobName, dbGenerator.MobGuild, dbGenerator.MobFaction, dbGenerator.RegionID);
  				}
  			}
  			if (log.IsDebugEnabled)
  			{
  				log.Debug("Found " + m_globalGenerators.Count + " Global LootGenerators");
  				log.Debug("Found " + m_mobNameGenerators.Count + " Mobnames registered by LootGenerators");
  				log.Debug("Found " + m_mobGuildGenerators.Count + " Guildnames registered by LootGenerators");
  			}
  
  			// no loot generators loaded...
  			if (m_globalGenerators.Count == 0 && m_mobNameGenerators.Count == 0 && m_globalGenerators.Count == 0)
  			{
  				ILootGenerator baseGenerator = new LootGeneratorMoney();
  				RegisterLootGenerator(baseGenerator, null, null, null, 0);
  				if (log.IsInfoEnabled)
  					log.Info("No LootGenerator found, adding LootGeneratorMoney for all mobs as default.");
  			}
  
  			if (log.IsInfoEnabled)
  				log.Info("LootGenerator initialized: true");
  			return true;
  		}
  
  		/// <summary>
  		/// Stores a generator in a cache to reused the same generators multiple times
  		/// </summary>
  		/// <param name="dbGenerator"></param>
  		/// <param name="generator"></param>
  		private static void PutGeneratorInCache(LootGenerator dbGenerator, ILootGenerator generator)
  		{
  			m_ClassGenerators[dbGenerator.LootGeneratorClass + dbGenerator.ExclusivePriority] = generator;
  		}
  
  		/// <summary>
  		///  Returns a generator from cache
  		/// </summary>
  		/// <param name="dbGenerator"></param>
  		/// <returns></returns>
  		private static ILootGenerator GetGeneratorInCache(LootGenerator dbGenerator)
  		{
  			if (m_ClassGenerators[dbGenerator.LootGeneratorClass + dbGenerator.ExclusivePriority] != null)
  			{
  				return (ILootGenerator)m_ClassGenerators[dbGenerator.LootGeneratorClass + dbGenerator.ExclusivePriority];
  			}
  			return null;
  		}
  
  		public static void UnRegisterLootGenerator(ILootGenerator generator, string mobname, string mobguild, string mobfaction)
  		{
  		    UnRegisterLootGenerator(generator, mobname, mobguild, mobfaction, 0);
  		}
  
  		/// <summary>
  		/// Unregister a generator for the given parameters		
  		/// </summary>
  		/// <param name="generator"></param>
  		/// <param name="mobname"></param>
  		/// <param name="mobguild"></param>
  		/// <param name="mobfaction"></param>
  		public static void UnRegisterLootGenerator(ILootGenerator generator, string mobname, string mobguild, string mobfaction, int mobregion)
  		{
  			if (generator == null)
  				return;
  
  			// Loot Generator Name Indexed
  			if (!Util.IsEmpty(mobname))
  			{	
  				
  				try 
  				{
  					// Parse CSV
  					List<string> mobNames = Util.SplitCSV(mobname);
  					
  					foreach(string mob in mobNames) 
  					{
  						if ((IList)m_mobNameGenerators[mob] != null)
  						{
  							((IList)m_mobNameGenerators[mob]).Remove(generator);
  						}
  					}
  
  				}
  				catch 
  				{
  					if (log.IsDebugEnabled)
  					{
  						log.Debug("Could not Parse mobNames for Removing LootGenerator : " + generator.GetType().FullName);
  					}
  				}
  			}
  
  			// Loot Generator Guild Indexed
  			if (!Util.IsEmpty(mobguild))
  			{
  				
  				try 
  				{
  					// Parse CSV
  					List<string> mobGuilds = Util.SplitCSV(mobguild);
  					
  					foreach(string guild in mobGuilds) 
  					{
  
gt: 						if ((IList)m_mobGuildGenerators[guild] != null)