/// <summary> /// Load a loot config into a List of CfgGroups /// </summary> /// <param name="file">Path to loot config. If relative will start in the same directory as this extension</param> /// <returns>CfgGroup List</returns> public static List <CfgGroup> Load(string file) { if (!Path.IsPathRooted(file)) { var basepath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (basepath != null) { file = Path.Combine(basepath, file); } } if (!File.Exists(file)) { throw new CfgGroupException($"File not found: {file}"); } var lootcfg = Regex.Replace(File.ReadAllText(file), BlockComments + "|" + LineComments, "\n", RegexOptions.Singleline); var groups = new List <CfgGroup>(); CfgGroup group = null; foreach (var line in lootcfg.Split('\r', '\n').Where(l => !string.IsNullOrWhiteSpace(l))) { if (line[0] == '>') { group = new CfgGroup(line.Substring(1).Trim()); groups.Add(group); continue; } group?.Add(line); } return(groups); }
/// <summary> /// Loot constructor /// </summary> private Loot() { var assembly = Assembly.GetExecutingAssembly(); var assemblyName = Path.GetFileNameWithoutExtension(assembly.Location); var iniPath = Path.Combine(BasePath, $"{assemblyName}.ini"); if (!File.Exists(iniPath)) { throw new LootException($"{assemblyName}.ini was not found"); } var ini = new IniParser(iniPath); var cfgpath = ini.GetSetting("General", "LootCfg", "ExileLootDrop.cfg"); var cacheCount = Convert.ToInt32(ini.GetSetting("General", "CacheItems", "0")); Logger.LoggerHandlerManager.AddHandler(new ConsoleLoggerHandler()); var logfile = Path.Combine(BasePath, "output.log"); try { if (File.Exists(logfile)) { File.Delete(logfile); } } catch { // ignore } Logger.LoggerHandlerManager.AddHandler(new FileLoggerHandler(logfile)); Logger.Log <Loot>(Logger.Level.Info, "====================================================================="); Logger.Log <Loot>(Logger.Level.Info, "Exile Loot Drop Extension"); Logger.Log <Loot>(Logger.Level.Info, "By maca134"); Logger.Log <Loot>(Logger.Level.Info, "Please remember to donate for more cool shit!"); Logger.Log <Loot>(Logger.Level.Info, "http://maca134.co.uk"); Logger.Log <Loot>(Logger.Level.Info, "====================================================================="); var start = DateTime.Now; try { _cfgGroups = CfgGroup.Load(cfgpath); } catch (CfgGroupException ex) { _hasErrored = true; Logger.Log <Loot>(Logger.Level.Error, $"There was an error loading the loot cfg {cfgpath}: {ex.Message}"); throw new LootException($"There was an error loading the loot cfg {cfgpath}", ex); } foreach (var group in _cfgGroups) { var list = FlattenGroups(group); var table = new LootTable(group.Name, list, cacheCount); Table.Add(group.Name, table); } var span = DateTime.Now - start; Logger.Log <Loot>($"Took {span.TotalMilliseconds}ms to load and parse loot cfg"); }
/// <summary> /// Flattens cfg groups (recursive) /// </summary> /// <param name="group">Base group</param> /// <param name="depth">Current depth</param> /// <returns></returns> private List <LootItem> FlattenGroups(CfgGroup group, int depth = 0) { var list = new List <LootItem>(); if (depth > MaxDepth) { Logger.Log <Loot>(Logger.Level.Warning, $"The loot table is too deep: {depth} > {MaxDepth}"); return(list); } var total = group.Items.Select(i => i.Chance).Sum(); foreach (var item in group.Items.OrderByDescending(a => a.Chance)) { var chance = item.Chance / total; var child = _cfgGroups.Find(g => g.Name == item.Item); if (child != null) { var childlist = FlattenGroups(child, depth++); childlist.ForEach(i => { list.Add(new LootItem { Item = i.Item, Chance = i.Chance * chance }); }); continue; } list.Add(new LootItem { Item = item.Item, Chance = chance }); } return(list); }