Compare commits
3
Commits
5b1fad3372
...
db432929bf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db432929bf | ||
|
|
29aee61d4c | ||
|
|
38bc6152ed |
@@ -1,4 +1,4 @@
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel;
|
||||
using Slugify;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers;
|
||||
|
||||
@@ -42,11 +42,6 @@ internal class AonprdLoader(AonprdImporter importer)
|
||||
{
|
||||
foreach (string? file in Compendium.Files(types))
|
||||
{
|
||||
if (file is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
using StreamReader fileReader = new(Path.Combine(Importer.Dir, $"{file}.json"));
|
||||
JArray array = JArray.Parse(fileReader.ReadToEnd());
|
||||
|
||||
|
||||
+40
-61
@@ -1,5 +1,6 @@
|
||||
using LinqToDB;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Pf2eModel;
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel.Model.Base;
|
||||
using Pf2eModel.Model.Base.Source;
|
||||
@@ -49,7 +50,7 @@ internal abstract partial class AbstractProcessor(ProcessorInput input)
|
||||
Context.SaveChanges();
|
||||
}
|
||||
|
||||
protected string AddedDescription(string path) => $"\n\n---\n[{path}]\n\n{Input.GetOptional<string>(path) ?? ""}";
|
||||
protected string AddedDescription(string path) => $"\r\n\r\n========== [{path}] ==========\r\n\r\n{Input.GetOptional<string>(path) ?? ""}";
|
||||
|
||||
protected string AddedDescription(string[] paths) => string.Join("", paths.Select(AddedDescription));
|
||||
|
||||
@@ -60,7 +61,7 @@ internal abstract partial class AbstractProcessor(ProcessorInput input)
|
||||
Entity.Id = Helper.NextEntityId;
|
||||
Entity.Type = Type;
|
||||
Entity.Name = Input.GetRequired<string>("name");
|
||||
Entity.Img = ""; // GetRequired<string>("img");
|
||||
Entity.Img = "";
|
||||
Entity.Description = GetDescription();
|
||||
Entity.Rarity = Input.EnumOptional<EntityRarity>("rarity", EntityRarity.Common);
|
||||
Entity.Slug = Helper.GenerateSlug(Entity.Name);
|
||||
@@ -85,32 +86,33 @@ internal abstract partial class AbstractProcessor(ProcessorInput input)
|
||||
|
||||
JArray? legacyIdArray = Input.GetOptional<JArray>("legacy_id");
|
||||
|
||||
if (legacyIdArray is not null)
|
||||
if (legacyIdArray is null)
|
||||
{
|
||||
string legacyId = legacyIdArray[0].ToString();
|
||||
|
||||
if (LegacyAliases.TryGetValue(legacyId, out string? legacyName))
|
||||
{
|
||||
if (legacyName != Entity.Name)
|
||||
{
|
||||
EntityAlias legacyAlias = new()
|
||||
{
|
||||
Type = AliasType.LegacyEnglish,
|
||||
Alias = legacyName,
|
||||
Entity = Entity
|
||||
};
|
||||
|
||||
Context.EntityAliases.Add(legacyAlias);
|
||||
}
|
||||
|
||||
LegacyAliases.Remove(legacyId);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemasterWithoutLegacy.Add(legacyId, Entity);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
string legacyId = legacyIdArray[0].ToString();
|
||||
|
||||
if (LegacyAliases.TryGetValue(legacyId, out string? legacyName))
|
||||
{
|
||||
if (legacyName != Entity.Name)
|
||||
{
|
||||
EntityAlias legacyAlias = new()
|
||||
{
|
||||
Type = AliasType.LegacyEnglish,
|
||||
Alias = legacyName,
|
||||
Entity = Entity
|
||||
};
|
||||
|
||||
Context.EntityAliases.Add(legacyAlias);
|
||||
}
|
||||
|
||||
LegacyAliases.Remove(legacyId);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemasterWithoutLegacy.Add(legacyId, Entity);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void AddSource()
|
||||
@@ -185,6 +187,8 @@ internal abstract partial class AbstractProcessor(ProcessorInput input)
|
||||
.ToList();
|
||||
|
||||
List<Trait> traits = Context.Traits
|
||||
.Include(t => t.Entity)
|
||||
.ThenInclude(e => e.Aliases)
|
||||
.Where(t => traitEntities.Contains(t.Entity))
|
||||
.ToList();
|
||||
|
||||
@@ -202,47 +206,22 @@ internal abstract partial class AbstractProcessor(ProcessorInput input)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected IEnumerable<Trait> GetTraits(IEnumerable<string> names)
|
||||
{
|
||||
List<Trait> result = Context.Traits.Where(t => names.Contains(t.Entity.Name)).ToList();
|
||||
|
||||
foreach (string name in names)
|
||||
{
|
||||
if (result.Any(t => t.Entity.Name == name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
Trait trait = new()
|
||||
{
|
||||
Name = name,
|
||||
Slug = name,
|
||||
Type = TraitType.Regular,
|
||||
Description = "",
|
||||
};
|
||||
Context.Traits.Add(trait);
|
||||
result.Add(trait);
|
||||
*/
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void ProcessLegacy(string id, string name)
|
||||
{
|
||||
if (RemasterWithoutLegacy.TryGetValue(id, out Entity? remastered))
|
||||
{
|
||||
if (remastered.Name != name)
|
||||
if (remastered.Name == name)
|
||||
{
|
||||
EntityAlias alias = new()
|
||||
{
|
||||
Type = AliasType.LegacyEnglish,
|
||||
Alias = name,
|
||||
Entity = remastered!
|
||||
};
|
||||
Context.EntityAliases.Add(alias);
|
||||
return;
|
||||
}
|
||||
|
||||
EntityAlias alias = new()
|
||||
{
|
||||
Type = AliasType.LegacyEnglish,
|
||||
Alias = name,
|
||||
Entity = remastered!
|
||||
};
|
||||
Context.EntityAliases.Add(alias);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -52,7 +52,7 @@ internal class AonprdDataBuilder(AonprdLoader loader)
|
||||
|
||||
foreach (AonprdLoader.LoaderEntry entry in Loader.Entries(item.Attribute.Type))
|
||||
{
|
||||
bar2.Refresh(i++, $"{entry.Id}");
|
||||
bar2.Refresh(j++, $"{entry.Id}");
|
||||
|
||||
AonprdProcessorInput input = new(entry.Json);
|
||||
AbstractProcessor processor = (AbstractProcessor) item.Constructor.Invoke([input]);
|
||||
@@ -68,7 +68,7 @@ internal class AonprdDataBuilder(AonprdLoader loader)
|
||||
}
|
||||
}
|
||||
|
||||
bar2.Refresh(j, "Processor complited");
|
||||
bar2.Refresh(j, "Processor completed");
|
||||
}
|
||||
|
||||
bar1.Refresh(i, "Done!");
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
internal class AonprdEnumAttribute(string[] values) : Attribute
|
||||
{
|
||||
public readonly string[] Values = values;
|
||||
|
||||
public AonprdEnumAttribute(string value) : this([value])
|
||||
{
|
||||
}
|
||||
}
|
||||
+15
-2
@@ -4,7 +4,8 @@ namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder;
|
||||
public static class AonprdEnumResolver
|
||||
{
|
||||
private static readonly ICollection<Solver> Solvers = [
|
||||
new Solver<ActionType>(new() {
|
||||
new Solver<ActionType>(new()
|
||||
{
|
||||
{ "Single Action", ActionType.SingleAction },
|
||||
{ "Reaction or One Action", ActionType.SingleAction },
|
||||
{ "Free Action or One Action", ActionType.SingleAction },
|
||||
@@ -16,7 +17,8 @@ public static class AonprdEnumResolver
|
||||
{ "Single Action to Two Actions", ActionType.SingleToTwoActions },
|
||||
}),
|
||||
|
||||
new Solver<SourceCategory>(new() {
|
||||
new Solver<SourceCategory>(new()
|
||||
{
|
||||
{ "Rulebooks", SourceCategory.Rulebooks },
|
||||
{ "Adventure Paths", SourceCategory.AdventurePaths },
|
||||
{ "Lost Omens", SourceCategory.LostOmens },
|
||||
@@ -25,6 +27,17 @@ public static class AonprdEnumResolver
|
||||
{ "Blog Posts", SourceCategory.BlogPosts },
|
||||
{ "Society", SourceCategory.Society },
|
||||
}),
|
||||
|
||||
new Solver<AncestryVision>(new()
|
||||
{
|
||||
{ "Low-Light Vision", AncestryVision.LowLightVision },
|
||||
{ "Darkvision", AncestryVision.DarkVision },
|
||||
}),
|
||||
|
||||
new Solver<AttributeValues>(new()
|
||||
{
|
||||
{ "Consitution", AttributeValues.Constitution }
|
||||
})
|
||||
];
|
||||
|
||||
public static T Resolve<T>(string value) where T : Enum
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
using LinqToDB;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel.Model.Enum;
|
||||
using Pf2eModel.Model.Structure;
|
||||
using Pf2eModel.Model.Structure.AncestryRelation;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
|
||||
|
||||
[AonprdProcessor("ancestry", ["trait", "language"])]
|
||||
internal class AncestryProcessor(ProcessorInput input) : AbstractProcessor(input)
|
||||
{
|
||||
public override EntityType Type { get; } = EntityType.Ancestry;
|
||||
|
||||
public override Ancestry Object { get; } = new Ancestry();
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
string type = Input.GetRequired<string>("type");
|
||||
|
||||
if (type != "Ancestry")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
base.Process();
|
||||
|
||||
Object.Size = Input.GetRequired<JArray>("size").Select(t => Input.Enum<Size>(t.ToString())).ToArray();
|
||||
|
||||
string hp = Input.GetRequired<string>("hp_raw");
|
||||
Object.Hp = Convert.ToInt32((hp != "") ? hp : "0");
|
||||
|
||||
Object.Speed = Convert.ToInt32(Input.GetOptional<int>("speed.land"));
|
||||
|
||||
Object.Vision = Input.EnumOptional<AncestryVision>("vision", AncestryVision.Normal);
|
||||
|
||||
AddBoosts("attribute", true);
|
||||
AddBoosts("attribute_flaw", false);
|
||||
|
||||
// TODO - import languages from Foundry!
|
||||
// ProcessLanguages();
|
||||
}
|
||||
|
||||
protected void AddBoosts(string path, bool isBoost)
|
||||
{
|
||||
List<string> boosts = Input.GetOptional<JArray>(path)?.ToArray().Select(t => t.ToString()).ToList() ?? [];
|
||||
|
||||
if (boosts.Contains("Two free ability boosts"))
|
||||
{
|
||||
boosts.Remove("Two free ability boosts");
|
||||
boosts.Add("Free");
|
||||
boosts.Add("Free");
|
||||
}
|
||||
|
||||
foreach (string boost in boosts)
|
||||
{
|
||||
AncestryBoost ancestryBoost = new()
|
||||
{
|
||||
Ancestry = Object,
|
||||
Boost = isBoost,
|
||||
Value = Input.Enum<AttributeValues>(boost),
|
||||
};
|
||||
|
||||
Context.AncestryBoosts.Add(ancestryBoost);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected override string GetDescription()
|
||||
=> base.GetDescription() + AddedDescription([
|
||||
"source_markdown",
|
||||
"summary_markdown",
|
||||
"trait_markdown",
|
||||
"search_markdown"
|
||||
]);
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
using Pf2eModel.Model.Enum;
|
||||
using Pf2eModel.Model.Structure;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
|
||||
|
||||
[AonprdProcessor("language")]
|
||||
internal class LanguageProcessor(ProcessorInput input) : AbstractProcessor(input)
|
||||
{
|
||||
public override EntityType Type { get; } = EntityType.Language;
|
||||
|
||||
public override Language Object { get; } = new Language();
|
||||
|
||||
}
|
||||
+1
-1
@@ -21,7 +21,7 @@ internal class TraitProcessor(ProcessorInput input) : AbstractProcessor(input)
|
||||
|
||||
protected override void AddTraits()
|
||||
{
|
||||
// Во втором проходе
|
||||
// Необходимо пропускать
|
||||
}
|
||||
|
||||
protected override string GetDescription()
|
||||
|
||||
+1
@@ -1,4 +1,5 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Pf2eModel;
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel.Model.Base;
|
||||
using Pf2eModel.Model.Base.Source;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Pf2eDataScrapper;
|
||||
using Pf2eDataScrapper.Importers.Implementations.Aonprd;
|
||||
|
||||
Console.SetWindowSize(Console.LargestWindowWidth - 20, Console.LargestWindowHeight - 10);
|
||||
//Console.SetWindowSize(Console.LargestWindowWidth - 20, Console.LargestWindowHeight - 10);
|
||||
|
||||
EnvSettings.Load();
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+47
-51
@@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel;
|
||||
using Pf2eModel.Model.Enum;
|
||||
|
||||
#nullable disable
|
||||
@@ -13,7 +13,7 @@ using Pf2eModel.Model.Enum;
|
||||
namespace Pf2eModel.Migrations
|
||||
{
|
||||
[DbContext(typeof(Pf2eDbContext))]
|
||||
[Migration("20250418083111_1")]
|
||||
[Migration("20250418174520_1")]
|
||||
partial class _1
|
||||
{
|
||||
/// <inheritdoc />
|
||||
@@ -27,18 +27,18 @@ namespace Pf2eModel.Migrations
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "action_category", new[] { "unknown", "offensive", "defensive", "interaction", "familiar", "army_tactic", "army_war_action", "kingdom_activity", "kingdom_feat", "kingdom_feature" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "action_type", new[] { "none", "1_action", "2_actions", "3_actions", "1-3_actions", "1-2_actions" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "alias_type", new[] { "legacy", "english", "legacy_english", "hobby", "other" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "ancestry_vision", new[] { "normal", "low-light-vision", "darkvision" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "attribute_values", new[] { "any", "str", "dex", "con", "int", "wis", "cha" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "ancestry_vision", new[] { "normal", "low-light-vision", "dark-vision" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "attribute_values", new[] { "free", "str", "dex", "con", "int", "wis", "cha" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "class_progression_type", new[] { "entity", "ancestry_feat", "class_feat", "general_feat", "skill_feat", "skill_increase" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "condition_group", new[] { "unknown", "senses", "abilities", "death", "attitudes", "detection" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_category", new[] { "deity", "pantheon", "covenant", "philosophy" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_fonts", new[] { "none", "heal", "harm", "any" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_sanctification", new[] { "holy", "unholy", "any" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_rarity", new[] { "common", "uncommon", "rare", "unique" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_type", new[] { "unknown", "trait", "action", "ancestry", "background", "backpack", "campaign_feature", "class", "condition", "deity", "feat", "heritage", "spell" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_type", new[] { "unknown", "trait", "action", "ancestry", "background", "backpack", "campaign_feature", "class", "condition", "deity", "feat", "heritage", "spell", "language" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "feat_action_type", new[] { "passive", "action", "reaction", "free" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "feat_category", new[] { "ancestryfeature", "classfeature", "calling", "class", "skill", "general", "ancestry", "bonus", "deityboon", "curse", "pfsboon", "campaign_feature" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "size", new[] { "med", "tiny" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "size", new[] { "tiny", "small", "medium", "large" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "source_category", new[] { "rulebook", "adventure-path", "lost-omens", "adventures", "comics", "blog-posts", "society" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "spell_area_type", new[] { "burst", "emanation", "cone", "line", "square", "cube", "cylinder" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "spell_damage_category", new[] { "persistent", "splash" });
|
||||
@@ -425,41 +425,6 @@ namespace Pf2eModel.Migrations
|
||||
b.ToTable("frequencies", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Pf2eModel.Model.Common.Language", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id")
|
||||
.HasColumnOrder(1);
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)")
|
||||
.HasColumnName("name")
|
||||
.HasColumnOrder(2);
|
||||
|
||||
b.Property<EntityRarity>("Rarity")
|
||||
.HasColumnType("entity_rarity")
|
||||
.HasColumnName("rarity")
|
||||
.HasColumnOrder(4);
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)")
|
||||
.HasColumnName("slug")
|
||||
.HasColumnOrder(3);
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_languages");
|
||||
|
||||
b.ToTable("languages", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Pf2eModel.Model.Common.Training", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -543,25 +508,21 @@ namespace Pf2eModel.Migrations
|
||||
.HasColumnName("hp")
|
||||
.HasColumnOrder(3);
|
||||
|
||||
b.Property<int>("Reach")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("reach")
|
||||
.HasColumnOrder(4);
|
||||
|
||||
b.Property<Size>("Size")
|
||||
.HasColumnType("size")
|
||||
b.PrimitiveCollection<Size[]>("Size")
|
||||
.IsRequired()
|
||||
.HasColumnType("size[]")
|
||||
.HasColumnName("size")
|
||||
.HasColumnOrder(2);
|
||||
|
||||
b.Property<int>("Speed")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("speed")
|
||||
.HasColumnOrder(5);
|
||||
.HasColumnOrder(4);
|
||||
|
||||
b.Property<AncestryVision>("Vision")
|
||||
.HasColumnType("ancestry_vision")
|
||||
.HasColumnName("vision")
|
||||
.HasColumnOrder(6);
|
||||
.HasColumnOrder(5);
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_ancestries");
|
||||
@@ -1190,6 +1151,29 @@ namespace Pf2eModel.Migrations
|
||||
b.ToTable("heritages", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Language", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id")
|
||||
.HasColumnOrder(1);
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("EntityId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("entity_id");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_languages");
|
||||
|
||||
b.HasIndex("EntityId")
|
||||
.HasDatabaseName("ix_languages_entity_id");
|
||||
|
||||
b.ToTable("languages", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -1632,7 +1616,7 @@ namespace Pf2eModel.Migrations
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_ancestry_languages_ancestries_ancestry_id");
|
||||
|
||||
b.HasOne("Pf2eModel.Model.Common.Language", "Language")
|
||||
b.HasOne("Pf2eModel.Model.Structure.Language", "Language")
|
||||
.WithMany()
|
||||
.HasForeignKey("LanguageId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
@@ -1899,6 +1883,18 @@ namespace Pf2eModel.Migrations
|
||||
b.Navigation("Entity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Language", b =>
|
||||
{
|
||||
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
|
||||
.WithMany()
|
||||
.HasForeignKey("EntityId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_languages_entities_entity_id");
|
||||
|
||||
b.Navigation("Entity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
||||
{
|
||||
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel;
|
||||
using Pf2eModel.Model.Enum;
|
||||
|
||||
#nullable disable
|
||||
@@ -24,18 +24,18 @@ namespace Pf2eModel.Migrations
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "action_category", new[] { "unknown", "offensive", "defensive", "interaction", "familiar", "army_tactic", "army_war_action", "kingdom_activity", "kingdom_feat", "kingdom_feature" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "action_type", new[] { "none", "1_action", "2_actions", "3_actions", "1-3_actions", "1-2_actions" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "alias_type", new[] { "legacy", "english", "legacy_english", "hobby", "other" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "ancestry_vision", new[] { "normal", "low-light-vision", "darkvision" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "attribute_values", new[] { "any", "str", "dex", "con", "int", "wis", "cha" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "ancestry_vision", new[] { "normal", "low-light-vision", "dark-vision" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "attribute_values", new[] { "free", "str", "dex", "con", "int", "wis", "cha" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "class_progression_type", new[] { "entity", "ancestry_feat", "class_feat", "general_feat", "skill_feat", "skill_increase" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "condition_group", new[] { "unknown", "senses", "abilities", "death", "attitudes", "detection" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_category", new[] { "deity", "pantheon", "covenant", "philosophy" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_fonts", new[] { "none", "heal", "harm", "any" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_sanctification", new[] { "holy", "unholy", "any" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_rarity", new[] { "common", "uncommon", "rare", "unique" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_type", new[] { "unknown", "trait", "action", "ancestry", "background", "backpack", "campaign_feature", "class", "condition", "deity", "feat", "heritage", "spell" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_type", new[] { "unknown", "trait", "action", "ancestry", "background", "backpack", "campaign_feature", "class", "condition", "deity", "feat", "heritage", "spell", "language" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "feat_action_type", new[] { "passive", "action", "reaction", "free" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "feat_category", new[] { "ancestryfeature", "classfeature", "calling", "class", "skill", "general", "ancestry", "bonus", "deityboon", "curse", "pfsboon", "campaign_feature" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "size", new[] { "med", "tiny" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "size", new[] { "tiny", "small", "medium", "large" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "source_category", new[] { "rulebook", "adventure-path", "lost-omens", "adventures", "comics", "blog-posts", "society" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "spell_area_type", new[] { "burst", "emanation", "cone", "line", "square", "cube", "cylinder" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "spell_damage_category", new[] { "persistent", "splash" });
|
||||
@@ -422,41 +422,6 @@ namespace Pf2eModel.Migrations
|
||||
b.ToTable("frequencies", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Pf2eModel.Model.Common.Language", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id")
|
||||
.HasColumnOrder(1);
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)")
|
||||
.HasColumnName("name")
|
||||
.HasColumnOrder(2);
|
||||
|
||||
b.Property<EntityRarity>("Rarity")
|
||||
.HasColumnType("entity_rarity")
|
||||
.HasColumnName("rarity")
|
||||
.HasColumnOrder(4);
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)")
|
||||
.HasColumnName("slug")
|
||||
.HasColumnOrder(3);
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_languages");
|
||||
|
||||
b.ToTable("languages", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Pf2eModel.Model.Common.Training", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -540,25 +505,21 @@ namespace Pf2eModel.Migrations
|
||||
.HasColumnName("hp")
|
||||
.HasColumnOrder(3);
|
||||
|
||||
b.Property<int>("Reach")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("reach")
|
||||
.HasColumnOrder(4);
|
||||
|
||||
b.Property<Size>("Size")
|
||||
.HasColumnType("size")
|
||||
b.PrimitiveCollection<Size[]>("Size")
|
||||
.IsRequired()
|
||||
.HasColumnType("size[]")
|
||||
.HasColumnName("size")
|
||||
.HasColumnOrder(2);
|
||||
|
||||
b.Property<int>("Speed")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("speed")
|
||||
.HasColumnOrder(5);
|
||||
.HasColumnOrder(4);
|
||||
|
||||
b.Property<AncestryVision>("Vision")
|
||||
.HasColumnType("ancestry_vision")
|
||||
.HasColumnName("vision")
|
||||
.HasColumnOrder(6);
|
||||
.HasColumnOrder(5);
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_ancestries");
|
||||
@@ -1187,6 +1148,29 @@ namespace Pf2eModel.Migrations
|
||||
b.ToTable("heritages", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Language", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id")
|
||||
.HasColumnOrder(1);
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("EntityId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("entity_id");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_languages");
|
||||
|
||||
b.HasIndex("EntityId")
|
||||
.HasDatabaseName("ix_languages_entity_id");
|
||||
|
||||
b.ToTable("languages", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -1629,7 +1613,7 @@ namespace Pf2eModel.Migrations
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_ancestry_languages_ancestries_ancestry_id");
|
||||
|
||||
b.HasOne("Pf2eModel.Model.Common.Language", "Language")
|
||||
b.HasOne("Pf2eModel.Model.Structure.Language", "Language")
|
||||
.WithMany()
|
||||
.HasForeignKey("LanguageId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
@@ -1896,6 +1880,18 @@ namespace Pf2eModel.Migrations
|
||||
b.Navigation("Entity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Language", b =>
|
||||
{
|
||||
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
|
||||
.WithMany()
|
||||
.HasForeignKey("EntityId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_languages_entities_entity_id");
|
||||
|
||||
b.Navigation("Entity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
||||
{
|
||||
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
using Pf2eModel.Model.Enum;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Pf2eModel.Model.Common;
|
||||
|
||||
public partial class Language
|
||||
{
|
||||
[System.ComponentModel.DataAnnotations.Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column(Order = 1)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column(Order = 2)]
|
||||
[MaxLength(Pf2eDbContext.NameLength)]
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
[Column(Order = 3)]
|
||||
[MaxLength(Pf2eDbContext.NameLength)]
|
||||
public string Slug { get; set; } = null!;
|
||||
|
||||
[Column(Order = 4)]
|
||||
public EntityRarity Rarity { get; set; }
|
||||
}
|
||||
@@ -5,11 +5,11 @@ namespace Pf2eModel.Model.Enum;
|
||||
public enum AncestryVision
|
||||
{
|
||||
[PgName("normal")]
|
||||
normal,
|
||||
Normal,
|
||||
|
||||
[PgName("low-light-vision")]
|
||||
LowLightVision,
|
||||
|
||||
[PgName("darkvision")]
|
||||
darkvision,
|
||||
[PgName("dark-vision")]
|
||||
DarkVision,
|
||||
}
|
||||
@@ -4,8 +4,8 @@ namespace Pf2eModel.Model.Enum;
|
||||
|
||||
public enum AttributeValues
|
||||
{
|
||||
[PgName("any")]
|
||||
Any,
|
||||
[PgName("free")]
|
||||
Free,
|
||||
|
||||
[PgName("str")]
|
||||
Strength,
|
||||
|
||||
@@ -41,5 +41,8 @@ public enum EntityType
|
||||
Heritage,
|
||||
|
||||
[PgName("spell")]
|
||||
Spell
|
||||
Spell,
|
||||
|
||||
[PgName("language")]
|
||||
Language
|
||||
}
|
||||
@@ -4,9 +4,15 @@ namespace Pf2eModel.Model.Enum;
|
||||
|
||||
public enum Size
|
||||
{
|
||||
[PgName("med")]
|
||||
med,
|
||||
|
||||
[PgName("tiny")]
|
||||
tiny,
|
||||
Tiny,
|
||||
|
||||
[PgName("small")]
|
||||
Small,
|
||||
|
||||
[PgName("medium")]
|
||||
Medium,
|
||||
|
||||
[PgName("large")]
|
||||
Large,
|
||||
}
|
||||
@@ -16,19 +16,16 @@ public partial class Ancestry : IEntity
|
||||
public Entity Entity { get; set; } = null!;
|
||||
|
||||
[Column(Order = 2)]
|
||||
public Size Size { get; set; } = Size.med;
|
||||
public Size[] Size { get; set; }
|
||||
|
||||
[Column(Order = 3)]
|
||||
public int Hp { get; set; }
|
||||
|
||||
[Column(Order = 4)]
|
||||
public int Reach { get; set; }
|
||||
|
||||
[Column(Order = 5)]
|
||||
public int Speed { get; set; }
|
||||
|
||||
[Column(Order = 6)]
|
||||
public AncestryVision Vision { get; set; } = AncestryVision.normal;
|
||||
[Column(Order = 5)]
|
||||
public AncestryVision Vision { get; set; } = AncestryVision.Normal;
|
||||
|
||||
public virtual ICollection<AncestryBoost> AncestryBoosts { get; set; } = [];
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Pf2eModel.Model.Common;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Pf2eModel.Model.Structure.AncestryRelation;
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
using Pf2eModel.Model.Base;
|
||||
using Pf2eModel.Model.Enum;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Pf2eModel.Model.Structure;
|
||||
|
||||
[EntityOfType(EntityType.Language)]
|
||||
public partial class Language: IEntity
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column(Order = 1)]
|
||||
public int Id { get; set; }
|
||||
|
||||
public Entity Entity { get; set; } = null!;
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@ using Pf2eModel.Model.Structure.DeityRelation;
|
||||
using Pf2eModel.Model.Structure.FeatRelation;
|
||||
using Pf2eModel.Model.Structure.SpellRelation;
|
||||
|
||||
namespace Pf2eModel.Model;
|
||||
namespace Pf2eModel;
|
||||
|
||||
public partial class Pf2eDbContext : DbContext
|
||||
{
|
||||
@@ -30,7 +30,7 @@ public partial class Pf2eDbContext : DbContext
|
||||
|
||||
#region DbSets
|
||||
|
||||
public virtual DbSet<Structure.Action> Actions { get; set; }
|
||||
public virtual DbSet<Model.Structure.Action> Actions { get; set; }
|
||||
|
||||
public virtual DbSet<Ancestry> Ancestries { get; set; }
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel.Model.Base;
|
||||
using Pf2eModel.Model.Base.Keywords;
|
||||
using Pf2eModel.Model.Base.Source;
|
||||
@@ -14,7 +15,7 @@ using Pf2eModel.Model.Structure.DeityRelation;
|
||||
using Pf2eModel.Model.Structure.FeatRelation;
|
||||
using Pf2eModel.Model.Structure.SpellRelation;
|
||||
|
||||
namespace Pf2eModel.Model;
|
||||
namespace Pf2eModel;
|
||||
|
||||
public partial class Pf2eDbContext
|
||||
{
|
||||
@@ -28,7 +29,6 @@ public partial class Pf2eDbContext
|
||||
DefineBase(modelBuilder);
|
||||
DefineCommon(modelBuilder);
|
||||
DefineStructure(modelBuilder);
|
||||
DefineFunctions(modelBuilder);
|
||||
}
|
||||
|
||||
private void DefineEnums(ModelBuilder modelBuilder)
|
||||
@@ -135,7 +135,7 @@ public partial class Pf2eDbContext
|
||||
private void DefineStructure(ModelBuilder modelBuilder)
|
||||
{
|
||||
// Action
|
||||
modelBuilder.Entity<Structure.Action>(entity =>
|
||||
modelBuilder.Entity<Model.Structure.Action>(entity =>
|
||||
{
|
||||
BindEntity(entity);
|
||||
});
|
||||
@@ -325,86 +325,4 @@ public partial class Pf2eDbContext
|
||||
BindEntity(entity);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void DefineFunctions(ModelBuilder modelBuilder)
|
||||
{
|
||||
// modelBuilder.HasDbFunction(typeof(Pf2eDbContext).GetMethod(nameof(FTruncateTables), Array.Empty<Type>()))
|
||||
/*
|
||||
modelBuilder.HasPostgresExtension($"""
|
||||
CREATE OR REPLACE FUNCTION f_truncate_tables()
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql AS
|
||||
$func$
|
||||
BEGIN
|
||||
EXECUTE (
|
||||
SELECT 'TRUNCATE TABLE '
|
||||
|| string_agg(format('%I.%I', schemaname, tablename), ', ')
|
||||
|| ' CASCADE;'
|
||||
FROM pg_tables
|
||||
WHERE schemaname = 'public'
|
||||
AND tablename != '__EFMigrationsHistory'
|
||||
);
|
||||
END
|
||||
$func$;
|
||||
""")
|
||||
;
|
||||
|
||||
/*
|
||||
Database.ExecuteSql($"""
|
||||
CREATE OR REPLACE FUNCTION f_truncate_tables()
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql AS
|
||||
$func$
|
||||
BEGIN
|
||||
EXECUTE (
|
||||
SELECT 'TRUNCATE TABLE '
|
||||
|| string_agg(format('%I.%I', schemaname, tablename), ', ')
|
||||
|| ' CASCADE;'
|
||||
FROM pg_tables
|
||||
WHERE schemaname = 'public'
|
||||
AND tablename != '__EFMigrationsHistory'
|
||||
);
|
||||
END
|
||||
$func$;
|
||||
""");
|
||||
|
||||
Database.ExecuteSql($"""
|
||||
CREATE OR REPLACE FUNCTION f_drop_tables()
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql AS
|
||||
$func$
|
||||
BEGIN
|
||||
EXECUTE (
|
||||
SELECT 'DROP TABLE '
|
||||
|| string_agg(format('%I.%I', schemaname, tablename), ', ')
|
||||
|| ' CASCADE;'
|
||||
FROM pg_tables
|
||||
WHERE schemaname = 'public'
|
||||
);
|
||||
END
|
||||
$func$;
|
||||
""");
|
||||
|
||||
Database.ExecuteSql($"""
|
||||
CREATE OR REPLACE FUNCTION f_permission_tables(_username text)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql AS
|
||||
$func$
|
||||
DECLARE
|
||||
_tbl text;
|
||||
_sch text;
|
||||
BEGIN
|
||||
FOR _sch, _tbl IN
|
||||
SELECT schemaname, tablename
|
||||
FROM pg_tables
|
||||
WHERE schemaname = 'public'
|
||||
LOOP
|
||||
EXECUTE format('ALTER TABLE %I.%I OWNER TO %I', _sch, _tbl, _username);
|
||||
END LOOP;
|
||||
END
|
||||
$func$;
|
||||
""");
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,4 +27,22 @@
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="RebuildDatabase.bat">
|
||||
<Generator></Generator>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="RebuildDatabase.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>RebuildDatabase.bat</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
@echo off
|
||||
|
||||
del /s .\Migrations\Pf2eDbContextModelSnapshot.cs
|
||||
del /s .\Migrations\*_1.cs
|
||||
del /s .\Migrations\*_1.Designer.cs
|
||||
|
||||
dotnet ef database drop -f
|
||||
dotnet ef migrations add 1
|
||||
dotnet ef database update
|
||||
@@ -1,81 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel.Model.Base;
|
||||
using Pf2eModel.Model.Structure;
|
||||
|
||||
namespace Pf2eViewer;
|
||||
internal class EntityConventor : JsonConverter
|
||||
{
|
||||
private Pf2eDbContext Context = new();
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return objectType == typeof(Entity) || objectType.IsAssignableTo(typeof(IEntity));
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
|
||||
{
|
||||
JToken token = JToken.FromObject(value!);
|
||||
|
||||
if (token.Type != JTokenType.Object)
|
||||
{
|
||||
token.WriteTo(writer);
|
||||
return;
|
||||
}
|
||||
|
||||
JObject obj = (JObject) token;
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case Entity e:
|
||||
obj = ProcessEntity(obj, e);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
obj.WriteTo(writer);
|
||||
}
|
||||
|
||||
JObject ProcessEntity(JObject obj, Entity e)
|
||||
{
|
||||
List<int> traitIds = e.Traits.Select(t => t.Id).ToList();
|
||||
List<Trait> traits = Context.Traits.Where(t => traitIds.Contains(t.Id)).Include(t => t.Entity).ToList();
|
||||
|
||||
|
||||
foreach (JToken item in (JArray) obj.SelectToken("Traits"))
|
||||
{
|
||||
JObject o = (JObject) item;
|
||||
int id = o.SelectToken("Id").ToObject<int>();
|
||||
|
||||
o.Add("Name", traits.FirstOrDefault(t => t.Id == id)!.Entity.Name);
|
||||
}
|
||||
|
||||
obj.Remove("Description");
|
||||
|
||||
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
public override bool CanRead => false;
|
||||
|
||||
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
|
||||
{
|
||||
throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
|
||||
}
|
||||
|
||||
|
||||
private abstract class Conventer<T>(JsonWriter writer, T value, JsonSerializer serializer, Pf2eDbContext context)
|
||||
{
|
||||
public JsonWriter Writer { get; } = writer;
|
||||
public T Value { get; } = value;
|
||||
public JsonSerializer Serializer { get; } = serializer;
|
||||
public Pf2eDbContext Context { get; } = context;
|
||||
|
||||
public abstract JObject Process();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Pf2eModel;
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel.Model.Base;
|
||||
using Pf2eModel.Model.Base.Source;
|
||||
using Pf2eModel.Model.Structure;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Pf2eViewer;
|
||||
internal class EntityConverter : JsonConverter
|
||||
{
|
||||
private readonly Pf2eDbContext _context = new();
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return objectType == typeof(Entity) || objectType.IsAssignableTo(typeof(IEntity));
|
||||
}
|
||||
|
||||
private Dictionary<string, object?> DictionarySerialization(object source)
|
||||
{
|
||||
Dictionary<string, object?> dictionary = [];
|
||||
|
||||
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(source))
|
||||
{
|
||||
object? v = property.GetValue(source);
|
||||
dictionary.Add(property.Name, v);
|
||||
}
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
|
||||
{
|
||||
Dictionary<string, object?> dictionary = DictionarySerialization(value!);
|
||||
|
||||
if (value.GetType() != typeof(Entity))
|
||||
{
|
||||
dictionary.Remove("Entity");
|
||||
}
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case Entity entity:
|
||||
ProcessEntity(dictionary, entity);
|
||||
break;
|
||||
|
||||
case Trait trait:
|
||||
ProcessTrait(dictionary, trait);
|
||||
break;
|
||||
}
|
||||
|
||||
writer.WriteStartObject();
|
||||
|
||||
foreach (KeyValuePair<string, object> keyValuePair in dictionary)
|
||||
{
|
||||
writer.WritePropertyName(keyValuePair.Key, true);
|
||||
serializer.Serialize(writer, keyValuePair.Value);
|
||||
}
|
||||
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
|
||||
private void ProcessTrait(Dictionary<string, object?> dictionary, Trait trait)
|
||||
{
|
||||
string name = trait.Entity?.Name ?? _context.Entities.Where(e => e.Id == trait.Id).Select(e => e.Name).FirstOrDefault()!;
|
||||
|
||||
dictionary.Remove("Entity");
|
||||
dictionary.Remove("Entities");
|
||||
dictionary.Add("Name", name);
|
||||
}
|
||||
|
||||
private void ProcessEntity(Dictionary<string, object?> dictionary, Entity entity)
|
||||
{
|
||||
dictionary.Remove("Description");
|
||||
}
|
||||
|
||||
public override bool CanRead => false;
|
||||
|
||||
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
|
||||
{
|
||||
throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
|
||||
}
|
||||
}
|
||||
Generated
+109
-13
@@ -32,6 +32,13 @@ partial class MainViewForm
|
||||
InnerSplitContainer = new SplitContainer();
|
||||
TypesListBox = new ListBox();
|
||||
EntityGridView = new DataGridView();
|
||||
PaginationPagel = new Panel();
|
||||
PageTextBox = new TextBox();
|
||||
PaginationLabel = new TextBox();
|
||||
LastPageButton = new Button();
|
||||
NextPageButton = new Button();
|
||||
PrevPageButton = new Button();
|
||||
FirstPageButton = new Button();
|
||||
ResultSplitContainer = new SplitContainer();
|
||||
EntityTreeView = new TreeView();
|
||||
DescriptionTextBox = new TextBox();
|
||||
@@ -44,6 +51,7 @@ partial class MainViewForm
|
||||
InnerSplitContainer.Panel2.SuspendLayout();
|
||||
InnerSplitContainer.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize) EntityGridView).BeginInit();
|
||||
PaginationPagel.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize) ResultSplitContainer).BeginInit();
|
||||
ResultSplitContainer.Panel1.SuspendLayout();
|
||||
ResultSplitContainer.Panel2.SuspendLayout();
|
||||
@@ -65,8 +73,8 @@ partial class MainViewForm
|
||||
//
|
||||
RootSplitContainer.Panel2.Controls.Add(ResultSplitContainer);
|
||||
RootSplitContainer.Panel2MinSize = 400;
|
||||
RootSplitContainer.Size = new Size(811, 688);
|
||||
RootSplitContainer.SplitterDistance = 324;
|
||||
RootSplitContainer.Size = new Size(1181, 688);
|
||||
RootSplitContainer.SplitterDistance = 254;
|
||||
RootSplitContainer.TabIndex = 0;
|
||||
//
|
||||
// InnerSplitContainer
|
||||
@@ -83,8 +91,9 @@ partial class MainViewForm
|
||||
// InnerSplitContainer.Panel2
|
||||
//
|
||||
InnerSplitContainer.Panel2.Controls.Add(EntityGridView);
|
||||
InnerSplitContainer.Size = new Size(324, 688);
|
||||
InnerSplitContainer.SplitterDistance = 274;
|
||||
InnerSplitContainer.Panel2.Controls.Add(PaginationPagel);
|
||||
InnerSplitContainer.Size = new Size(254, 688);
|
||||
InnerSplitContainer.SplitterDistance = 102;
|
||||
InnerSplitContainer.TabIndex = 1;
|
||||
//
|
||||
// TypesListBox
|
||||
@@ -94,7 +103,7 @@ partial class MainViewForm
|
||||
TypesListBox.ItemHeight = 15;
|
||||
TypesListBox.Location = new Point(0, 0);
|
||||
TypesListBox.Name = "TypesListBox";
|
||||
TypesListBox.Size = new Size(324, 274);
|
||||
TypesListBox.Size = new Size(254, 102);
|
||||
TypesListBox.TabIndex = 0;
|
||||
TypesListBox.SelectedIndexChanged += TypesListBox_SelectedIndexChanged;
|
||||
//
|
||||
@@ -105,23 +114,101 @@ partial class MainViewForm
|
||||
EntityGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
|
||||
EntityGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||
EntityGridView.Dock = DockStyle.Fill;
|
||||
EntityGridView.Location = new Point(0, 0);
|
||||
EntityGridView.Location = new Point(0, 53);
|
||||
EntityGridView.MultiSelect = false;
|
||||
EntityGridView.Name = "EntityGridView";
|
||||
EntityGridView.ReadOnly = true;
|
||||
EntityGridView.RowHeadersVisible = false;
|
||||
EntityGridView.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders;
|
||||
EntityGridView.ShowEditingIcon = false;
|
||||
EntityGridView.Size = new Size(324, 410);
|
||||
EntityGridView.Size = new Size(254, 529);
|
||||
EntityGridView.TabIndex = 0;
|
||||
EntityGridView.RowStateChanged += EntityGridView_RowStateChanged;
|
||||
//
|
||||
// PaginationPagel
|
||||
//
|
||||
PaginationPagel.Controls.Add(PageTextBox);
|
||||
PaginationPagel.Controls.Add(PaginationLabel);
|
||||
PaginationPagel.Controls.Add(LastPageButton);
|
||||
PaginationPagel.Controls.Add(NextPageButton);
|
||||
PaginationPagel.Controls.Add(PrevPageButton);
|
||||
PaginationPagel.Controls.Add(FirstPageButton);
|
||||
PaginationPagel.Dock = DockStyle.Top;
|
||||
PaginationPagel.Location = new Point(0, 0);
|
||||
PaginationPagel.Name = "PaginationPagel";
|
||||
PaginationPagel.Size = new Size(254, 53);
|
||||
PaginationPagel.TabIndex = 1;
|
||||
//
|
||||
// PageTextBox
|
||||
//
|
||||
PageTextBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||
PageTextBox.Location = new Point(81, 4);
|
||||
PageTextBox.Name = "PageTextBox";
|
||||
PageTextBox.Size = new Size(92, 23);
|
||||
PageTextBox.TabIndex = 8;
|
||||
PageTextBox.Text = "1";
|
||||
PageTextBox.TextAlign = HorizontalAlignment.Center;
|
||||
PageTextBox.KeyPress += PageTextBox_KeyPress;
|
||||
//
|
||||
// PaginationLabel
|
||||
//
|
||||
PaginationLabel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||
PaginationLabel.BorderStyle = BorderStyle.None;
|
||||
PaginationLabel.Location = new Point(3, 31);
|
||||
PaginationLabel.Name = "PaginationLabel";
|
||||
PaginationLabel.ReadOnly = true;
|
||||
PaginationLabel.Size = new Size(248, 16);
|
||||
PaginationLabel.TabIndex = 7;
|
||||
PaginationLabel.Text = "Всего";
|
||||
PaginationLabel.TextAlign = HorizontalAlignment.Center;
|
||||
//
|
||||
// LastPageButton
|
||||
//
|
||||
LastPageButton.Anchor = AnchorStyles.Top | AnchorStyles.Right;
|
||||
LastPageButton.Location = new Point(218, 3);
|
||||
LastPageButton.Name = "LastPageButton";
|
||||
LastPageButton.Size = new Size(33, 23);
|
||||
LastPageButton.TabIndex = 3;
|
||||
LastPageButton.Text = ">>";
|
||||
LastPageButton.UseVisualStyleBackColor = true;
|
||||
LastPageButton.Click += LastPageButton_Click;
|
||||
//
|
||||
// NextPageButton
|
||||
//
|
||||
NextPageButton.Anchor = AnchorStyles.Top | AnchorStyles.Right;
|
||||
NextPageButton.Location = new Point(179, 3);
|
||||
NextPageButton.Name = "NextPageButton";
|
||||
NextPageButton.Size = new Size(33, 23);
|
||||
NextPageButton.TabIndex = 2;
|
||||
NextPageButton.Text = ">";
|
||||
NextPageButton.UseVisualStyleBackColor = true;
|
||||
NextPageButton.Click += NextPageButton_Click;
|
||||
//
|
||||
// PrevPageButton
|
||||
//
|
||||
PrevPageButton.Location = new Point(42, 3);
|
||||
PrevPageButton.Name = "PrevPageButton";
|
||||
PrevPageButton.Size = new Size(33, 23);
|
||||
PrevPageButton.TabIndex = 1;
|
||||
PrevPageButton.Text = "<";
|
||||
PrevPageButton.UseVisualStyleBackColor = true;
|
||||
PrevPageButton.Click += PrevPageButton_Click;
|
||||
//
|
||||
// FirstPageButton
|
||||
//
|
||||
FirstPageButton.Location = new Point(3, 3);
|
||||
FirstPageButton.Name = "FirstPageButton";
|
||||
FirstPageButton.Size = new Size(33, 23);
|
||||
FirstPageButton.TabIndex = 0;
|
||||
FirstPageButton.Text = "<<";
|
||||
FirstPageButton.UseVisualStyleBackColor = true;
|
||||
FirstPageButton.Click += FirstPageButton_Click;
|
||||
//
|
||||
// ResultSplitContainer
|
||||
//
|
||||
ResultSplitContainer.Dock = DockStyle.Fill;
|
||||
ResultSplitContainer.Location = new Point(0, 0);
|
||||
ResultSplitContainer.Name = "ResultSplitContainer";
|
||||
ResultSplitContainer.Orientation = Orientation.Horizontal;
|
||||
//
|
||||
// ResultSplitContainer.Panel1
|
||||
//
|
||||
@@ -130,8 +217,8 @@ partial class MainViewForm
|
||||
// ResultSplitContainer.Panel2
|
||||
//
|
||||
ResultSplitContainer.Panel2.Controls.Add(DescriptionTextBox);
|
||||
ResultSplitContainer.Size = new Size(483, 688);
|
||||
ResultSplitContainer.SplitterDistance = 269;
|
||||
ResultSplitContainer.Size = new Size(923, 688);
|
||||
ResultSplitContainer.SplitterDistance = 467;
|
||||
ResultSplitContainer.TabIndex = 1;
|
||||
//
|
||||
// EntityTreeView
|
||||
@@ -139,7 +226,7 @@ partial class MainViewForm
|
||||
EntityTreeView.Dock = DockStyle.Fill;
|
||||
EntityTreeView.Location = new Point(0, 0);
|
||||
EntityTreeView.Name = "EntityTreeView";
|
||||
EntityTreeView.Size = new Size(483, 269);
|
||||
EntityTreeView.Size = new Size(467, 688);
|
||||
EntityTreeView.TabIndex = 0;
|
||||
//
|
||||
// DescriptionTextBox
|
||||
@@ -150,14 +237,14 @@ partial class MainViewForm
|
||||
DescriptionTextBox.Name = "DescriptionTextBox";
|
||||
DescriptionTextBox.ReadOnly = true;
|
||||
DescriptionTextBox.ScrollBars = ScrollBars.Vertical;
|
||||
DescriptionTextBox.Size = new Size(483, 415);
|
||||
DescriptionTextBox.Size = new Size(452, 688);
|
||||
DescriptionTextBox.TabIndex = 0;
|
||||
//
|
||||
// MainViewForm
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(811, 688);
|
||||
ClientSize = new Size(1181, 688);
|
||||
Controls.Add(RootSplitContainer);
|
||||
Name = "MainViewForm";
|
||||
Text = "DataBaseViewer";
|
||||
@@ -170,6 +257,8 @@ partial class MainViewForm
|
||||
((System.ComponentModel.ISupportInitialize) InnerSplitContainer).EndInit();
|
||||
InnerSplitContainer.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize) EntityGridView).EndInit();
|
||||
PaginationPagel.ResumeLayout(false);
|
||||
PaginationPagel.PerformLayout();
|
||||
ResultSplitContainer.Panel1.ResumeLayout(false);
|
||||
ResultSplitContainer.Panel2.ResumeLayout(false);
|
||||
ResultSplitContainer.Panel2.PerformLayout();
|
||||
@@ -187,4 +276,11 @@ partial class MainViewForm
|
||||
private TreeView EntityTreeView;
|
||||
private SplitContainer ResultSplitContainer;
|
||||
private TextBox DescriptionTextBox;
|
||||
private Panel PaginationPagel;
|
||||
private Button LastPageButton;
|
||||
private Button NextPageButton;
|
||||
private Button PrevPageButton;
|
||||
private Button FirstPageButton;
|
||||
private TextBox PageTextBox;
|
||||
private TextBox PaginationLabel;
|
||||
}
|
||||
|
||||
+109
-22
@@ -1,6 +1,8 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Pf2eModel;
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel.Model.Base;
|
||||
@@ -29,27 +31,108 @@ public partial class MainViewForm : Form
|
||||
TypesListBox.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
private void TypesListBox_SelectedIndexChanged(object sender, EventArgs e)
|
||||
public const int PerPage = 20;
|
||||
|
||||
public int Count;
|
||||
|
||||
public int Page
|
||||
{
|
||||
if (TypesListBox.SelectedItem is null)
|
||||
get => Convert.ToInt32(PageTextBox.Text);
|
||||
set
|
||||
{
|
||||
PageTextBox.Text = value.ToString();
|
||||
UpdateTreeView();
|
||||
}
|
||||
}
|
||||
|
||||
public int MaxPage => Convert.ToInt32(Math.Ceiling(1.0 * Count / PerPage));
|
||||
|
||||
|
||||
private void UpdateTreeView()
|
||||
{
|
||||
EntityType type = (EntityType) TypesListBox.SelectedItem!;
|
||||
|
||||
Count = Context.Entities.Count(e => e.Type == type);
|
||||
|
||||
if (Page < 1 || Page > MaxPage)
|
||||
{
|
||||
Page = Math.Min(MaxPage, Math.Max(1, Page));
|
||||
return;
|
||||
}
|
||||
|
||||
EntityGridView.DataSource = Context.Entities
|
||||
.Where(e => e.Type == (EntityType) TypesListBox.SelectedItem)
|
||||
.OrderBy(e => e.Id)
|
||||
.Include(e => e.Sources).Include(e => e.Aliases).Include(e => e.Keywords).Include(e => e.Externals)
|
||||
.Include(e => e.Sources)
|
||||
.ThenInclude(s => s.Source)
|
||||
.Include(e => e.Aliases)
|
||||
.Include(e => e.Keywords)
|
||||
.Include(e => e.Externals)
|
||||
.ThenInclude(x => x.Target)
|
||||
.Include(e => e.Traits)
|
||||
.ThenInclude(t => t.Entity)
|
||||
.Select(e => new EntityGridRow(e))
|
||||
.Skip((Page - 1) * PerPage)
|
||||
.Take(PerPage)
|
||||
.ToList();
|
||||
|
||||
EntityGridView.Rows[0].Selected = true;
|
||||
|
||||
PaginationLabel.Text = $"Всего: {Count} объектов, {MaxPage} страниц";
|
||||
|
||||
FirstPageButton.Enabled = Page > 1;
|
||||
PrevPageButton.Enabled = Page > 1;
|
||||
NextPageButton.Enabled = Page < MaxPage;
|
||||
LastPageButton.Enabled = Page < MaxPage;
|
||||
}
|
||||
|
||||
private void TypesListBox_SelectedIndexChanged(object sender, EventArgs _)
|
||||
{
|
||||
if (TypesListBox.SelectedItem is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Page = 1;
|
||||
}
|
||||
private void FirstPageButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Page = 1;
|
||||
}
|
||||
|
||||
private void PrevPageButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Page--;
|
||||
}
|
||||
|
||||
private void NextPageButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Page++;
|
||||
}
|
||||
|
||||
private void LastPageButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Page = MaxPage;
|
||||
}
|
||||
|
||||
private void PageTextBox_KeyPress(object sender, KeyPressEventArgs e)
|
||||
{
|
||||
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
if (e.KeyChar == (char) Keys.Return)
|
||||
{
|
||||
UpdateTreeView();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void EntityGridView_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e)
|
||||
{
|
||||
int rowsCount = EntityGridView.SelectedRows.Count;
|
||||
if (rowsCount == 0 || rowsCount > 1)
|
||||
if (rowsCount is 0 or > 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -62,26 +145,38 @@ public partial class MainViewForm : Form
|
||||
|
||||
JsonToTreeview(EntityTreeView, json, "Entity");
|
||||
|
||||
DescriptionTextBox.Text = data.GetEntity().Description;
|
||||
DescriptionTextBox.Text = data.GetEntity().Description.Replace("\\r", "").Replace("\\n", "\\r\\n");
|
||||
}
|
||||
|
||||
public string SerializeEntity(Entity entity)
|
||||
{
|
||||
JsonSerializerSettings settings = new JsonSerializerSettings()
|
||||
JsonSerializerSettings settings = new()
|
||||
{
|
||||
Converters = [new EntityConventor()]
|
||||
// ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
Converters = [
|
||||
new EntityConverter(),
|
||||
new StringEnumConverter { NamingStrategy = new CamelCaseNamingStrategy() },
|
||||
]
|
||||
};
|
||||
|
||||
string result = JsonConvert.SerializeObject(entity, settings);
|
||||
|
||||
Type type = EntityOfTypeAttribute.Resolve(entity);
|
||||
string subReuslt = JsonConvert.SerializeObject(Context.Find(type, entity.Id), settings);
|
||||
string subResult = JsonConvert.SerializeObject(ResolveEntity(entity), settings);
|
||||
|
||||
return result[..^1] + $",\"SubEntity\":{subReuslt}}}";
|
||||
return result[..^1] + $",\"SubEntity\":{subResult}}}";
|
||||
}
|
||||
|
||||
public IEntity? ResolveEntity(Entity entity)
|
||||
{
|
||||
switch (entity.Type)
|
||||
{
|
||||
case EntityType.Ancestry:
|
||||
return Context.Ancestries
|
||||
.FirstOrDefault(e => e.Id == entity.Id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void JsonToTreeview(TreeView treeView, string jsonString, string rootName)
|
||||
{
|
||||
@@ -90,11 +185,11 @@ public partial class MainViewForm : Form
|
||||
: JObject.Parse(jsonString);
|
||||
|
||||
treeView.Nodes.Clear();
|
||||
|
||||
foreach (TreeNode node in Element2TreeNode(json, rootName).Nodes)
|
||||
{
|
||||
treeView.Nodes.Add(node);
|
||||
}
|
||||
treeView.ExpandAll();
|
||||
}
|
||||
|
||||
private static TreeNode Element2TreeNode(object element, string text = "")
|
||||
@@ -114,10 +209,7 @@ public partial class MainViewForm : Form
|
||||
case "JArray":
|
||||
JArray jArray = (JArray) element;
|
||||
int i = 0;
|
||||
foreach (JToken oJtok in jArray)
|
||||
{
|
||||
subNodes.Add(Element2TreeNode(oJtok, string.Format("[{0}]", i++)));
|
||||
}
|
||||
subNodes.AddRange(jArray.Select(token => Element2TreeNode(token, $"[{i++}]")));
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
@@ -147,20 +239,15 @@ public partial class MainViewForm : Form
|
||||
return treeNode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private class EntityGridRow(Entity e)
|
||||
{
|
||||
public int Id { get; set; } = e.Id;
|
||||
public string Name { get; set; } = e.Name;
|
||||
//public string Slug { get; set; } = e.Slug;
|
||||
//public EntityRarity Rarity { get; set; } = e.Rarity;
|
||||
public EntityRarity Rarity { get; set; } = e.Rarity;
|
||||
|
||||
private readonly Entity _e = e;
|
||||
public Entity GetEntity() => _e;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user