Skip to content

Commit

Permalink
Few changes
Browse files Browse the repository at this point in the history
Added config ini file
Added internal cache to reduce callExtension times
  • Loading branch information
maca134 committed Oct 3, 2016
1 parent 1655049 commit 33a584b
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 9 deletions.
1 change: 1 addition & 0 deletions build.bat
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions src/ExileLootDrop/ExileLootDrop.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand All @@ -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" />
Expand Down
3 changes: 3 additions & 0 deletions src/ExileLootDrop/ExileLootDrop.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[General]
LootCfg=ExileLootDrop.cfg
CacheItems=50000
199 changes: 199 additions & 0 deletions src/ExileLootDrop/IniParser.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
23 changes: 16 additions & 7 deletions src/ExileLootDrop/Loot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,22 @@ public static string Invoke(string input)

private readonly List<CfgGroup> _cfgGroups;
private Dictionary<string, LootTable> Table { get; } = new Dictionary<string, LootTable>();

/// <summary>
/// Loot constructor
/// </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
Expand Down Expand Up @@ -98,11 +107,11 @@ private Loot()
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>
Expand Down Expand Up @@ -157,11 +166,11 @@ public string[] GetItems(string table, int count = 1)
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>
Expand Down
25 changes: 24 additions & 1 deletion src/ExileLootDrop/LootTable.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace ExileLootDrop
{
Expand All @@ -16,14 +17,18 @@ public class LootTable
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 =>
Expand All @@ -32,6 +37,19 @@ public LootTable(string name, List<LootItem> lootList)
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>
Expand All @@ -40,6 +58,11 @@ public LootTable(string name, List<LootItem> lootList)
/// <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)
{
Expand Down
2 changes: 1 addition & 1 deletion src/ExileLootDropTester/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace ExileLootDropTester
{
class Program
{
const int Loops = 1000000;
const int Loops = 50000;

static void Main(string[] args)
{
Expand Down

0 comments on commit 33a584b

Please sign in to comment.