Few changes

Added config ini file
Added internal cache to reduce callExtension times
This commit is contained in:
Matthew McConnell 2016-10-03 20:45:12 +01:00
parent 1655049690
commit 33a584b2e9
7 changed files with 248 additions and 9 deletions

View File

@ -7,6 +7,7 @@ mkdir @ExileLootDrop\addons
%MSBUILD% src\ExileLootDrop.sln /property:Configuration=release /target:Rebuild /verbosity:normal /nologo
copy src\ExileLootDrop\bin\Release\ExileLootDrop.dll @ExileLootDrop
copy src\ExileLootDrop\bin\Release\ExileLootDrop.cfg @ExileLootDrop
copy src\ExileLootDrop\bin\Release\ExileLootDrop.ini @ExileLootDrop
copy src\ExileLootDropTester\bin\Release\ExileLootDropTester.exe @ExileLootDrop
copy LICENSE.txt @ExileLootDrop
copy README.md @ExileLootDrop

View File

@ -47,6 +47,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="DllEntry.cs" />
<Compile Include="IniParser.cs" />
<Compile Include="Logger.cs" />
<Compile Include="Loot.cs" />
<Compile Include="CfgGroup.cs" />
@ -63,6 +64,9 @@
<None Include="ExileLootDrop.cfg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="ExileLootDrop.ini">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View File

@ -0,0 +1,3 @@
[General]
LootCfg=ExileLootDrop.cfg
CacheItems=50000

View File

@ -0,0 +1,199 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace ExileLootDrop
{
public class IniParser
{
private readonly string _iniFilePath;
private readonly Hashtable _keyPairs = new Hashtable();
private readonly List<SectionPair> _tmpList = new List<SectionPair>();
public readonly string Name;
public IniParser(string iniPath)
{
string str2 = null;
_iniFilePath = iniPath;
Name = Path.GetFileNameWithoutExtension(iniPath);
if (!File.Exists(iniPath))
throw new FileNotFoundException("Unable to locate " + iniPath);
using (TextReader reader = new StreamReader(iniPath))
{
for (var str = reader.ReadLine(); str != null; str = reader.ReadLine())
{
str = str.Trim();
if (str == "")
continue;
if (str.StartsWith("[") && str.EndsWith("]"))
str2 = str.Substring(1, str.Length - 2);
else
{
SectionPair pair;
if (str.StartsWith(";"))
str = str.Replace("=", "%eq%") + @"=%comment%";
var strArray = str.Split(new[] { '=' }, 2);
string str3 = null;
if (str2 == null)
{
str2 = "ROOT";
}
pair.Section = str2;
pair.Key = strArray[0];
if (strArray.Length > 1)
{
str3 = strArray[1];
}
_keyPairs.Add(pair, str3);
_tmpList.Add(pair);
}
}
}
}
public void AddSetting(string sectionName, string settingName)
{
AddSetting(sectionName, settingName, null);
}
public void AddSetting(string sectionName, string settingName, string settingValue)
{
SectionPair pair;
pair.Section = sectionName;
pair.Key = settingName;
if (_keyPairs.ContainsKey(pair))
{
_keyPairs.Remove(pair);
}
if (_tmpList.Contains(pair))
{
_tmpList.Remove(pair);
}
_keyPairs.Add(pair, settingValue);
_tmpList.Add(pair);
}
public int Count()
{
return Sections.Length;
}
public void DeleteSetting(string sectionName, string settingName)
{
SectionPair pair;
pair.Section = sectionName;
pair.Key = settingName;
if (!_keyPairs.ContainsKey(pair)) return;
_keyPairs.Remove(pair);
_tmpList.Remove(pair);
}
public string[] EnumSection(string sectionName)
{
return (from pair in _tmpList where !pair.Key.StartsWith(";") where pair.Section == sectionName select pair.Key).ToArray();
}
public string[] Sections => (from pair in _tmpList
group pair by pair.Section into bySection
from IGrouping<string, SectionPair> g in bySection
select g.Key).ToArray();
public string GetSetting(string sectionName, string settingName, string defaultValue = "")
{
SectionPair pair;
pair.Section = sectionName;
pair.Key = settingName;
return !_keyPairs.ContainsKey(pair) ? defaultValue : ((string)_keyPairs[pair]).Trim();
}
public bool GetBoolSetting(string sectionName, string settingName, bool defaultValue = false)
{
if (defaultValue)
return (GetSetting(sectionName, settingName).ToLower() != "false");
return (GetSetting(sectionName, settingName).ToLower() == "true");
}
public void Save()
{
SaveSettings(_iniFilePath);
}
public void SaveSettings(string newFilePath)
{
var list = new ArrayList();
var str2 = "";
foreach (var pair in _tmpList.Where(pair => !list.Contains(pair.Section)))
{
list.Add(pair.Section);
}
foreach (string str3 in list)
{
str2 = str2 + "[" + str3 + "]\r\n";
foreach (var pair2 in _tmpList)
{
if (pair2.Section == str3)
{
var str = (string)_keyPairs[pair2];
if (str != null)
{
if (str == "%comment%")
{
str = "";
}
else
{
str = "=" + str;
}
}
str2 = str2 + pair2.Key.Replace("%eq%", "=") + str + "\r\n";
}
}
str2 = str2 + "\r\n";
}
using (TextWriter writer = new StreamWriter(newFilePath))
writer.Write(str2);
}
public void SetSetting(string sectionName, string settingName, string value)
{
SectionPair pair;
pair.Section = sectionName;
pair.Key = settingName;
if (_keyPairs.ContainsKey(pair))
{
_keyPairs[pair] = value;
}
else
{
AddSetting(sectionName, settingName, value);
}
}
public bool ContainsSetting(string sectionName, string settingName)
{
SectionPair pair;
pair.Section = sectionName;
pair.Key = settingName;
return _keyPairs.Contains(pair);
}
[StructLayout(LayoutKind.Sequential)]
private struct SectionPair
{
public string Section;
public string Key;
}
}
}

View File

@ -62,7 +62,16 @@ namespace ExileLootDrop
/// </summary>
private Loot()
{
const string cfgpath = "ExileLootDrop.cfg";
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
@ -98,11 +107,11 @@ namespace ExileLootDrop
foreach (var group in _cfgGroups)
{
var list = FlattenGroups(group);
var table = new LootTable(group.Name, list);
var table = new LootTable(group.Name, list, cacheCount);
Table.Add(group.Name, table);
}
var span = DateTime.Now - start;
Logger.Log<Loot>($"Took {span.Milliseconds}ms to load and parse loot cfg");
Logger.Log<Loot>($"Took {span.TotalMilliseconds}ms to load and parse loot cfg");
}
/// <summary>
@ -157,11 +166,11 @@ namespace ExileLootDrop
if (!Table.ContainsKey(table))
throw new LootTableNotFoundException($"No loot table called {table}");
var items = new List<string>();
var items = new string[count];
for (var i = 0; i < count; i++)
items.Add(Table[table].Drop());
items[i] = Table[table].Drop();
return items.ToArray();
return items;
}
/// <summary>

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace ExileLootDrop
{
@ -16,14 +17,18 @@ namespace ExileLootDrop
public LootItem[] LootItems { get; }
private readonly Random _rnd = new Random();
private readonly int _cacheCount;
private int _cachePtr;
private readonly LootItem[] _cacheItems;
/// <summary>
/// LootTable constuctor
/// </summary>
/// <param name="name">Table name</param>
/// <param name="lootList">Item list</param>
public LootTable(string name, List<LootItem> lootList)
public LootTable(string name, List<LootItem> lootList, int cacheCount = 0)
{
_cacheCount = cacheCount;
Name = name;
var sum = 0m;
lootList.ForEach(i =>
@ -32,6 +37,19 @@ namespace ExileLootDrop
i.Sum = sum;
});
LootItems = lootList.ToArray();
Logger.Log<LootTable>($"Pre caching loot for {Name}");
var cache = new List<LootItem>();
for (var i = 0; i < _cacheCount; i++)
{
var rnd = (decimal)_rnd.NextDouble();
foreach (var item in LootItems.Where(item => item.Sum >= rnd))
{
cache.Add(item);
break;
}
}
_cachePtr = 0;
_cacheItems = cache.ToArray();
}
/// <summary>
@ -40,6 +58,11 @@ namespace ExileLootDrop
/// <returns>Item classname</returns>
public string Drop()
{
if (_cacheCount != 0 && _cachePtr < _cacheCount)
{
return _cacheItems[_cachePtr++].Item;
}
var rnd = (decimal)_rnd.NextDouble();
foreach (var item in LootItems)
{

View File

@ -7,7 +7,7 @@ namespace ExileLootDropTester
{
class Program
{
const int Loops = 1000000;
const int Loops = 50000;
static void Main(string[] args)
{