mirror of
https://github.com/maca134/ExileLootDrop.git
synced 2024-08-30 17:22:13 +00:00
Few changes
Added config ini file Added internal cache to reduce callExtension times
This commit is contained in:
parent
1655049690
commit
33a584b2e9
@ -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
|
||||
|
@ -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" />
|
||||
|
3
src/ExileLootDrop/ExileLootDrop.ini
Normal file
3
src/ExileLootDrop/ExileLootDrop.ini
Normal file
@ -0,0 +1,3 @@
|
||||
[General]
|
||||
LootCfg=ExileLootDrop.cfg
|
||||
CacheItems=50000
|
199
src/ExileLootDrop/IniParser.cs
Normal file
199
src/ExileLootDrop/IniParser.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -56,13 +56,22 @@ namespace ExileLootDrop
|
||||
|
||||
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
|
||||
@ -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>
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -7,7 +7,7 @@ namespace ExileLootDropTester
|
||||
{
|
||||
class Program
|
||||
{
|
||||
const int Loops = 1000000;
|
||||
const int Loops = 50000;
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user