admin管理员组文章数量:1134247
I'm trying to create a logger for item drops for a game that I'm playing. I can get the item name, id, etc. from the game logs, but I'm having a hard time figuring out how to import and then store that information inside of my .Net app. After some research, I think creating a class with the fields that I want to use and then using a list would be best.
My problem is, I don't know how many different Dropped_From_NPC_# and Dropped_In_Zone_# there will be for each item. Some items might only have 1 NPC/Zone it drops from while others might have hundreds.
What is the simplest way to bring that information into my applications memory so that I can search for specific pieces of it later on?
public class ItemDatabaseInformation
{
public string Name { get; set; }
public Int64 LinkID { get; set; }
public Int64 IconID { get; set; }
public string Dropped_From_NPC_1 { get; set; }
public string Dropped_In_Zone_1 { get; set; }
public string Dropped_From_NPC_2 { get; set; }
public string Dropped_In_Zone_2 { get; set; }
public string Dropped_From_NPC_3 { get; set; }
public string Dropped_In_Zone_3 { get; set; }
}
I'm trying to create a logger for item drops for a game that I'm playing. I can get the item name, id, etc. from the game logs, but I'm having a hard time figuring out how to import and then store that information inside of my .Net app. After some research, I think creating a class with the fields that I want to use and then using a list would be best.
My problem is, I don't know how many different Dropped_From_NPC_# and Dropped_In_Zone_# there will be for each item. Some items might only have 1 NPC/Zone it drops from while others might have hundreds.
What is the simplest way to bring that information into my applications memory so that I can search for specific pieces of it later on?
public class ItemDatabaseInformation
{
public string Name { get; set; }
public Int64 LinkID { get; set; }
public Int64 IconID { get; set; }
public string Dropped_From_NPC_1 { get; set; }
public string Dropped_In_Zone_1 { get; set; }
public string Dropped_From_NPC_2 { get; set; }
public string Dropped_In_Zone_2 { get; set; }
public string Dropped_From_NPC_3 { get; set; }
public string Dropped_In_Zone_3 { get; set; }
}
Share
Improve this question
edited Jan 7 at 18:12
TylerH
21.2k76 gold badges79 silver badges110 bronze badges
asked Jan 7 at 18:10
bjcaseybjcasey
371 silver badge6 bronze badges
2
|
3 Answers
Reset to default 1The classical OOP approach to this would be to create another class that stores the information you care about for each time a drop event occurs. Then, you can store a List<T>
of that class and add to it as drop events happen.
Something like:
public class DropInfo
{
public string ItemName { get; set; }
public int NpcId { get; set; }
public int ZoneId { get; set; }
}
And then, in your database class:
public class ItemDatabaseInformation
{
public string Name { get; set; }
public Int64 LinkID { get; set; }
public Int64 IconID { get; set; }
public List<DropInfo> DroppedItems = new List<DropInfo>();
public void RecordItemDropped(string itemName, int npcId, int zoneId)
{
DroppedItems.Add(new DropInfo()
{
ItemName = itemName,
NpcId = npcId,
zoneId = zoneId
});
}
}
Edit: For the searching component, there are various mechanisms, such as Linq, that provide ways of searching lists for an element with a desired property.
For example:
public DropInfo FindDroppedItem(string itemName)
{
return DroppedItems
.Where(i => i.ItemName == itemName)
.FirstOrDefault();
}
Your question asks for a simple way to work with "item drops" data. Specifically:
to bring that information into my applications memory so that I can search for specific pieces of it later on.
Placing the emphasis on "search" often the simplest way involves a database, and your additional requirement is for one that is in memory and not persisted on disk. One way to declare one is to install the sqlite-net-pcl NuGet and then use ":memory:"
as the database path of the SQLiteConnection
that is used throughout.
// <PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
using SQLite;
public partial class MainForm : Form
{
// IS: "Storing Information in Memory"
// IS NOT: Persisted on disk (which requires a database file name instead of ":memory:")
readonly SQLiteConnection ItemDatabase = new SQLiteConnection(":memory:");
public MainForm()
{
InitializeComponent();
ItemDatabase.CreateTable<ItemRecord>();
ItemDatabase.CreateTable<DropRecord>();
Disposed += (sender, e) => ItemDatabase.Dispose();
textBox.TextChanged += RefreshQuery;
_checkboxes = tableLayoutPanel.Controls.OfType<CheckBox>().ToArray();
foreach (var checkbox in _checkboxes) checkbox.CheckedChanged += RefreshQuery;
}
CheckBox[] _checkboxes;
.
.
.
}
Unknown Number of Nodes
You stated THREE requirements:
- In Memory
- Easily Searchable
- Unknown number of nodes.
One common way of dealing with #3 is having two tables in the database.
The first table holds item header information, indexed e.g. by the Name
property or any other property that is going to uniquely identify it.
[Table("items")]
class ItemRecord
{
[PrimaryKey, Indexed]
public string? Name { get; set; }
public Int64 LinkID { get; set; } = Guid.NewGuid().ToString().GetHashCode();
public Int64 IconID { get; set; } = Guid.NewGuid().ToString().GetHashCode();
}
The second table holds instances of drops. The ParentName
in this case identifies the master item associated with it. Other metadata info like LinkID
or IconID
is not repeated. And like you said, some master items might only have 1 NPC/Zone drop while others might have hundreds.
[Table("drops")]
class DropRecord
{
// Arbitrary value to uniquely identify the record.
[PrimaryKey, Browsable(false)]
public string Uid { get; set; } = Guid.NewGuid().ToString().ToUpper();
[NotNull]
public string? ParentName { get; set; }
public DateTimeOffset TimeStamp { get; set; } = DateTimeOffset.Now;
public string? DroppedFrom { get; set; }
public string? DroppedFromValue { get; set; }
public string? DroppedIn { get; set; }
public string? DroppedInValue { get; set; }
}
This way, you have flexibility with your search. You can get the items associated with a name, for example.
Or you can filter by NPC/Zone info or a combination of name + drop info.
Basic Search
This shows a basic SQL query as a starting point. It responds to "only" the name text OR "only" the checked boxes OR a combination of both.
public partial class MainForm : Form
{
.
.
.
private void RefreshQuery(object? sender, EventArgs e)
{
var nameClause = textBox.TextLength > 0 ? $"ParentName LIKE '%{textBox.Text}%'": null;
var drops =
_checkboxes
.Where(_ => _.Checked).Select(_ => _.Name.Replace("checkBox", string.Empty))
.ToArray();
var dropsClause = drops.Any()
? string.Join(" OR ", drops.Select(_=>$"DroppedFrom='{_}' OR DroppedIn='{_}'"))
: null;
var matches = new List<DropRecord>();
string? sql = null;
if (nameClause is null ^ dropsClause is null)
{
if (nameClause is not null)
sql = $"SELECT * FROM drops WHERE {nameClause}";
else
sql = $"SELECT * FROM drops WHERE {dropsClause}";
}
else if (nameClause is not null)
sql = $"SELECT * FROM drops WHERE {nameClause} AND ({dropsClause})";
if (sql is not null) matches = ItemDatabase.Query<DropRecord>(sql);
FilteredDropRecords.Clear();
foreach (var item in matches)
{
FilteredDropRecords.Add(item);
}
}
}
You can ensure database to save nodes to tables and get from db with Entity Framework Core nugget in .net. If you want to store not too large data use SQLite. You can see documentations here
Before you create a database. Classes you recording must have primary keys
public class ItemDatabaseInformation
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public Int64 LinkID { get; set; }
public Int64 IconID { get; set; }
public List<Node>nodes { get; set; } = new List<Node>()
}
public class Node
{
[Key]
public int Id { get; set; }
public string Zone { get; set; }
public string Npc { get; set; }
}
Edit: I figured out the problem is the how to store many points from and in it dropped
本文标签: cStoring Information in Memory with Unknown Number of NodesStack Overflow
版权声明:本文标题:c# - Storing Information in Memory with Unknown Number of Nodes - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736783454a1952727.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
List
instead of separate fields for each zone etc. – wohlstad Commented Jan 7 at 18:15dropped in+by [{NPC, Zone}, {NPC, Zone}, {NPC, Zone}]
, ordropped in [Zone, Zone, Zone] and dropped by [NPC, NPC, NPC]
? – AKX Commented Jan 7 at 18:22