diff --git a/src/Snap.Hutao/Snap.Hutao/App.xaml b/src/Snap.Hutao/Snap.Hutao/App.xaml index 0a40b75921..49f1b61a22 100644 --- a/src/Snap.Hutao/Snap.Hutao/App.xaml +++ b/src/Snap.Hutao/Snap.Hutao/App.xaml @@ -18,7 +18,7 @@ #FFF4F4F4 - #FF272727 + #FF242424 diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Image/Bgra8.cs b/src/Snap.Hutao/Snap.Hutao/Control/Image/Bgra8.cs index 36e8f97830..d993ae39b3 100644 --- a/src/Snap.Hutao/Snap.Hutao/Control/Image/Bgra8.cs +++ b/src/Snap.Hutao/Snap.Hutao/Control/Image/Bgra8.cs @@ -75,21 +75,4 @@ public static Bgra8 FromRgb(byte r, byte g, byte b) { return new(b, g, r, 0xFF); } - - /// - /// 加入噪声 - /// - /// 源 - /// 噪声 - public static Bgra8 Noise(Bgra8 source) - { - Bgra8 target = new(0, 0, 0, 0) - { - B = (byte)Math.Max(0, Math.Min(255, source.B + Random.Shared.Next(-20, 20))), - G = (byte)Math.Max(0, Math.Min(255, source.G + Random.Shared.Next(-20, 20))), - R = (byte)Math.Max(0, Math.Min(255, source.R + Random.Shared.Next(-20, 20))), - A = source.A, - }; - return target; - } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Migrations/20221210111128_Inventory.cs b/src/Snap.Hutao/Snap.Hutao/Migrations/20221210111128_Inventory.cs index c80c927cf9..279c0524d5 100644 --- a/src/Snap.Hutao/Snap.Hutao/Migrations/20221210111128_Inventory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Migrations/20221210111128_Inventory.cs @@ -1,5 +1,4 @@ // -using System; using Microsoft.EntityFrameworkCore.Migrations; #nullable disable diff --git a/src/Snap.Hutao/Snap.Hutao/Migrations/20221217061817_ItemFinishable.Designer.cs b/src/Snap.Hutao/Snap.Hutao/Migrations/20221217061817_ItemFinishable.Designer.cs new file mode 100644 index 0000000000..36deada4d4 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Migrations/20221217061817_ItemFinishable.Designer.cs @@ -0,0 +1,515 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Snap.Hutao.Context.Database; + +#nullable disable + +namespace Snap.Hutao.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20221217061817_ItemFinishable")] + partial class ItemFinishable + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.1"); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b => + { + b.Property("InnerId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("ArchiveId") + .HasColumnType("TEXT"); + + b.Property("Current") + .HasColumnType("INTEGER"); + + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Time") + .HasColumnType("TEXT"); + + b.HasKey("InnerId"); + + b.HasIndex("ArchiveId"); + + b.ToTable("achievements"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.AchievementArchive", b => + { + b.Property("InnerId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("IsSelected") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("InnerId"); + + b.ToTable("achievement_archives"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.AvatarInfo", b => + { + b.Property("InnerId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Info") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Uid") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("InnerId"); + + b.ToTable("avatar_infos"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntry", b => + { + b.Property("InnerId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("ProjectId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("InnerId"); + + b.HasIndex("ProjectId"); + + b.ToTable("cultivate_entries"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateItem", b => + { + b.Property("InnerId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Count") + .HasColumnType("INTEGER"); + + b.Property("EntryId") + .HasColumnType("TEXT"); + + b.Property("IsFinished") + .HasColumnType("INTEGER"); + + b.Property("ItemId") + .HasColumnType("INTEGER"); + + b.HasKey("InnerId"); + + b.HasIndex("EntryId"); + + b.ToTable("cultivate_items"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateProject", b => + { + b.Property("InnerId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("AttachedUid") + .HasColumnType("TEXT"); + + b.Property("IsSelected") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("InnerId"); + + b.ToTable("cultivate_projects"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b => + { + b.Property("InnerId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("DailyNote") + .HasColumnType("TEXT"); + + b.Property("DailyTaskNotify") + .HasColumnType("INTEGER"); + + b.Property("DailyTaskNotifySuppressed") + .HasColumnType("INTEGER"); + + b.Property("ExpeditionNotify") + .HasColumnType("INTEGER"); + + b.Property("ExpeditionNotifySuppressed") + .HasColumnType("INTEGER"); + + b.Property("HomeCoinNotifySuppressed") + .HasColumnType("INTEGER"); + + b.Property("HomeCoinNotifyThreshold") + .HasColumnType("INTEGER"); + + b.Property("ResinNotifySuppressed") + .HasColumnType("INTEGER"); + + b.Property("ResinNotifyThreshold") + .HasColumnType("INTEGER"); + + b.Property("ShowInHomeWidget") + .HasColumnType("INTEGER"); + + b.Property("TransformerNotify") + .HasColumnType("INTEGER"); + + b.Property("TransformerNotifySuppressed") + .HasColumnType("INTEGER"); + + b.Property("Uid") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("InnerId"); + + b.HasIndex("UserId"); + + b.ToTable("daily_notes"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaArchive", b => + { + b.Property("InnerId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("IsSelected") + .HasColumnType("INTEGER"); + + b.Property("Uid") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("InnerId"); + + b.ToTable("gacha_archives"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaItem", b => + { + b.Property("InnerId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("ArchiveId") + .HasColumnType("TEXT"); + + b.Property("GachaType") + .HasColumnType("INTEGER"); + + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("ItemId") + .HasColumnType("INTEGER"); + + b.Property("QueryType") + .HasColumnType("INTEGER"); + + b.Property("Time") + .HasColumnType("TEXT"); + + b.HasKey("InnerId"); + + b.HasIndex("ArchiveId"); + + b.ToTable("gacha_items"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.GameAccount", b => + { + b.Property("InnerId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("AttachUid") + .HasColumnType("TEXT"); + + b.Property("MihoyoSDK") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("InnerId"); + + b.ToTable("game_accounts"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryItem", b => + { + b.Property("InnerId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Count") + .HasColumnType("INTEGER"); + + b.Property("ItemId") + .HasColumnType("INTEGER"); + + b.Property("ProjectId") + .HasColumnType("TEXT"); + + b.HasKey("InnerId"); + + b.HasIndex("ProjectId"); + + b.ToTable("inventory_items"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryReliquary", b => + { + b.Property("InnerId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("AppendPropIdList") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("INTEGER"); + + b.Property("Level") + .HasColumnType("INTEGER"); + + b.Property("MainPropId") + .HasColumnType("INTEGER"); + + b.Property("ProjectId") + .HasColumnType("TEXT"); + + b.HasKey("InnerId"); + + b.HasIndex("ProjectId"); + + b.ToTable("inventory_reliquaries"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryWeapon", b => + { + b.Property("InnerId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("INTEGER"); + + b.Property("Level") + .HasColumnType("INTEGER"); + + b.Property("ProjectId") + .HasColumnType("TEXT"); + + b.Property("PromoteLevel") + .HasColumnType("INTEGER"); + + b.HasKey("InnerId"); + + b.HasIndex("ProjectId"); + + b.ToTable("inventory_weapons"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.ObjectCacheEntry", b => + { + b.Property("Key") + .HasColumnType("TEXT"); + + b.Property("ExpireTime") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Key"); + + b.ToTable("object_cache"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.SettingEntry", b => + { + b.Property("Key") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Key"); + + b.ToTable("settings"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.User", b => + { + b.Property("InnerId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Aid") + .HasColumnType("TEXT"); + + b.Property("CookieToken") + .HasColumnType("TEXT"); + + b.Property("IsSelected") + .HasColumnType("INTEGER"); + + b.Property("Ltoken") + .HasColumnType("TEXT"); + + b.Property("Mid") + .HasColumnType("TEXT"); + + b.Property("Stoken") + .HasColumnType("TEXT"); + + b.HasKey("InnerId"); + + b.ToTable("users"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b => + { + b.HasOne("Snap.Hutao.Model.Entity.AchievementArchive", "Archive") + .WithMany() + .HasForeignKey("ArchiveId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Archive"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntry", b => + { + b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateItem", b => + { + b.HasOne("Snap.Hutao.Model.Entity.CultivateEntry", "Entry") + .WithMany() + .HasForeignKey("EntryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Entry"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b => + { + b.HasOne("Snap.Hutao.Model.Entity.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaItem", b => + { + b.HasOne("Snap.Hutao.Model.Entity.GachaArchive", "Archive") + .WithMany("Items") + .HasForeignKey("ArchiveId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Archive"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryItem", b => + { + b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryReliquary", b => + { + b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryWeapon", b => + { + b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaArchive", b => + { + b.Navigation("Items"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Snap.Hutao/Snap.Hutao/Migrations/20221217061817_ItemFinishable.cs b/src/Snap.Hutao/Snap.Hutao/Migrations/20221217061817_ItemFinishable.cs new file mode 100644 index 0000000000..901fde7200 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Migrations/20221217061817_ItemFinishable.cs @@ -0,0 +1,30 @@ +// +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Snap.Hutao.Migrations +{ + /// + public partial class ItemFinishable : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "IsFinished", + table: "cultivate_items", + type: "INTEGER", + nullable: false, + defaultValue: false); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "IsFinished", + table: "cultivate_items"); + } + } +} diff --git a/src/Snap.Hutao/Snap.Hutao/Migrations/AppDbContextModelSnapshot.cs b/src/Snap.Hutao/Snap.Hutao/Migrations/AppDbContextModelSnapshot.cs index d2a50f7768..e46b0626dd 100644 --- a/src/Snap.Hutao/Snap.Hutao/Migrations/AppDbContextModelSnapshot.cs +++ b/src/Snap.Hutao/Snap.Hutao/Migrations/AppDbContextModelSnapshot.cs @@ -15,7 +15,7 @@ partial class AppDbContextModelSnapshot : ModelSnapshot protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "7.0.0"); + modelBuilder.HasAnnotation("ProductVersion", "7.0.1"); modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b => { @@ -42,7 +42,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("ArchiveId"); - b.ToTable("achievements", (string)null); + b.ToTable("achievements"); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.AchievementArchive", b => @@ -60,7 +60,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("InnerId"); - b.ToTable("achievement_archives", (string)null); + b.ToTable("achievement_archives"); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.AvatarInfo", b => @@ -79,7 +79,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("InnerId"); - b.ToTable("avatar_infos", (string)null); + b.ToTable("avatar_infos"); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntry", b => @@ -101,7 +101,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("ProjectId"); - b.ToTable("cultivate_entries", (string)null); + b.ToTable("cultivate_entries"); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateItem", b => @@ -116,6 +116,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("EntryId") .HasColumnType("TEXT"); + b.Property("IsFinished") + .HasColumnType("INTEGER"); + b.Property("ItemId") .HasColumnType("INTEGER"); @@ -123,7 +126,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("EntryId"); - b.ToTable("cultivate_items", (string)null); + b.ToTable("cultivate_items"); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateProject", b => @@ -144,7 +147,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("InnerId"); - b.ToTable("cultivate_projects", (string)null); + b.ToTable("cultivate_projects"); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b => @@ -200,7 +203,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("UserId"); - b.ToTable("daily_notes", (string)null); + b.ToTable("daily_notes"); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaArchive", b => @@ -218,7 +221,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("InnerId"); - b.ToTable("gacha_archives", (string)null); + b.ToTable("gacha_archives"); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaItem", b => @@ -249,7 +252,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("ArchiveId"); - b.ToTable("gacha_items", (string)null); + b.ToTable("gacha_items"); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.GameAccount", b => @@ -274,7 +277,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("InnerId"); - b.ToTable("game_accounts", (string)null); + b.ToTable("game_accounts"); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryItem", b => @@ -283,7 +286,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("TEXT"); - b.Property("Count") + b.Property("Count") .HasColumnType("INTEGER"); b.Property("ItemId") @@ -296,7 +299,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("ProjectId"); - b.ToTable("inventory_items", (string)null); + b.ToTable("inventory_items"); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryReliquary", b => @@ -325,7 +328,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("ProjectId"); - b.ToTable("inventory_reliquaries", (string)null); + b.ToTable("inventory_reliquaries"); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryWeapon", b => @@ -350,7 +353,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("ProjectId"); - b.ToTable("inventory_weapons", (string)null); + b.ToTable("inventory_weapons"); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.ObjectCacheEntry", b => @@ -366,7 +369,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Key"); - b.ToTable("object_cache", (string)null); + b.ToTable("object_cache"); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.SettingEntry", b => @@ -379,7 +382,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Key"); - b.ToTable("settings", (string)null); + b.ToTable("settings"); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.User", b => @@ -408,7 +411,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("InnerId"); - b.ToTable("users", (string)null); + b.ToTable("users"); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b => diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Cultivation/CultivateItem.cs b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Cultivation/CultivateItem.cs index 353a0d6cc5..758f7d7e01 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Cultivation/CultivateItem.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Cultivation/CultivateItem.cs @@ -2,7 +2,9 @@ // Licensed under the MIT license. using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; using Snap.Hutao.Model.Metadata; +using Snap.Hutao.Service.Cultivation; namespace Snap.Hutao.Model.Binding.Cultivation; @@ -11,6 +13,8 @@ namespace Snap.Hutao.Model.Binding.Cultivation; /// public class CultivateItem : ObservableObject { + private bool isFinished; + /// /// 养成物品 /// @@ -20,6 +24,9 @@ public CultivateItem(Material inner, Entity.CultivateItem entity) { Inner = inner; Entity = entity; + isFinished = Entity.IsFinished; + + FinishStateCommand = new RelayCommand(FlipIsFinished); } /// @@ -31,4 +38,29 @@ public CultivateItem(Material inner, Entity.CultivateItem entity) /// 实体 /// public Entity.CultivateItem Entity { get; } + + /// + /// 调整完成状态命令 + /// + public ICommand FinishStateCommand { get; } + + /// + /// 是否完成此项 + /// + public bool IsFinished + { + get => isFinished; set + { + if (SetProperty(ref isFinished, value)) + { + Entity.IsFinished = value; + Ioc.Default.GetRequiredService().SaveCultivateItem(Entity); + } + } + } + + private void FlipIsFinished() + { + IsFinished = !IsFinished; + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateEntry.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateEntry.cs index 5203ab3dfe..d48be9c7ac 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateEntry.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateEntry.cs @@ -44,10 +44,11 @@ public class CultivateEntry /// /// 创建一个新的养成入口点 /// + /// 项目Id /// 类型 /// 主Id /// 养成入口点 - public static CultivateEntry Create(Guid projectId,CultivateType type, int id) + public static CultivateEntry Create(Guid projectId, CultivateType type, int id) { return new() { diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateItem.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateItem.cs index 879fdf7b16..5c6e6ea983 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateItem.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateItem.cs @@ -40,6 +40,11 @@ public class CultivateItem /// public int Count { get; set; } + /// + /// 是否完成此项 + /// + public bool IsFinished { get; set; } + /// /// 创建一个新的养成物品 /// diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/ObjectCacheEntry.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/ObjectCacheEntry.cs index d5a899263d..f8d114aad5 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/ObjectCacheEntry.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/ObjectCacheEntry.cs @@ -27,7 +27,7 @@ public class ObjectCacheEntry /// 获取该对象是否过期 /// [NotMapped] - public bool IsExpired { get => ExpireTime > DateTimeOffset.Now; } + public bool IsExpired { get => ExpireTime < DateTimeOffset.Now; } /// /// 值字符串 diff --git a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/Inventory/UIIF.cs b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/Inventory/UIIF.cs index e447e50df2..47fbe2be79 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/Inventory/UIIF.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/Inventory/UIIF.cs @@ -68,7 +68,7 @@ internal class UIIFReliquary : UIIFItem /// 副属性列表 /// [JsonPropertyName("appendPropIdList")] - public List AppendPropIdList { get; set; } + public List AppendPropIdList { get; set; } = default!; } /// diff --git a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/Inventory/UIIFInfo.cs b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/Inventory/UIIFInfo.cs index a4ad940b72..7d146c7678 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/Inventory/UIIFInfo.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/Inventory/UIIFInfo.cs @@ -1,4 +1,7 @@ -using Snap.Hutao.Core; +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Snap.Hutao.Core; using Snap.Hutao.Extension; using System; using System.Collections.Generic; diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/INameQuality.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/INameQuality.cs index 7199e3d769..eb4e1341b4 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/INameQuality.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/INameQuality.cs @@ -19,5 +19,4 @@ public interface INameQuality /// 星级 /// ItemQuality Quality { get; } -} - +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/NativeMethods.txt b/src/Snap.Hutao/Snap.Hutao/NativeMethods.txt index e8b1642b4e..0c64a13b20 100644 --- a/src/Snap.Hutao/Snap.Hutao/NativeMethods.txt +++ b/src/Snap.Hutao/Snap.Hutao/NativeMethods.txt @@ -28,4 +28,7 @@ CoWaitForMultipleObjects // USER32 FindWindowEx -GetDpiForWindow \ No newline at end of file +GetDpiForWindow + +// WinRT +IMemoryBufferByteAccess \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs index 73eff46e37..a4ce86c0c8 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs @@ -197,6 +197,15 @@ public void SaveInventoryItem(BindingInventoryItem item) } } + /// + public void SaveCultivateItem(CultivateItem item) + { + using (IServiceScope scope = scopeFactory.CreateScope()) + { + scope.ServiceProvider.GetRequiredService().CultivateItems.UpdateAndSave(item); + } + } + /// public async Task SaveConsumptionAsync(Model.Binding.Cultivation.CultivateType type, int itemId, List items) { diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationService.cs index 8dfb8cc82a..ed5df53cb2 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationService.cs @@ -67,6 +67,12 @@ internal interface ICultivationService /// 是否保存成功 Task SaveConsumptionAsync(CultivateType type, int itemId, List items); + /// + /// 保存养成物品状态 + /// + /// 养成物品 + void SaveCultivateItem(Model.Entity.CultivateItem item); + /// /// 保存单个物品 /// diff --git a/src/Snap.Hutao/Snap.Hutao/View/Dialog/CultivatePromotionDeltaDialog.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Dialog/CultivatePromotionDeltaDialog.xaml.cs index cc6b50b87d..7f35ba2df1 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Dialog/CultivatePromotionDeltaDialog.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/View/Dialog/CultivatePromotionDeltaDialog.xaml.cs @@ -14,7 +14,7 @@ namespace Snap.Hutao.View.Dialog; public sealed partial class CultivatePromotionDeltaDialog : ContentDialog { private static readonly DependencyProperty AvatarProperty = Property.Depend(nameof(Avatar)); - private static readonly DependencyProperty WeaponProperty = Property.Depend(nameof(Weapon)); + private static readonly DependencyProperty WeaponProperty = Property.Depend(nameof(Weapon)); /// /// һµɼԻ diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/CultivationPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/CultivationPage.xaml index 56d9d952dc..83a7bd2918 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/CultivationPage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/CultivationPage.xaml @@ -2,7 +2,8 @@ x:Class="Snap.Hutao.View.Page.CultivationPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:cwuc="using:CommunityToolkit.WinUI.UI.Controls" + xmlns:cwucont="using:CommunityToolkit.WinUI.UI.Controls" + xmlns:cwuconv="using:CommunityToolkit.WinUI.UI.Converters" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mxi="using:Microsoft.Xaml.Interactivity" @@ -19,6 +20,15 @@ + + + + 0.4 + + + 1 + + @@ -59,13 +69,13 @@ - - + @@ -80,7 +90,6 @@ - + @@ -180,16 +207,16 @@ - - + + - - + - - + + diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/HutaoDatabasePage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/HutaoDatabasePage.xaml index 271510a1d0..35d97f2b10 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/HutaoDatabasePage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/HutaoDatabasePage.xaml @@ -31,6 +31,7 @@ MinWidth="240" Margin="0,-32,0,0" Header="数据来自「胡桃数据库」"> + diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiWeaponPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiWeaponPage.xaml index 1e54bea534..0d211b2428 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiWeaponPage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiWeaponPage.xaml @@ -44,7 +44,11 @@ - + public ICommand ExportAsImageCommand { get; } - private static unsafe void ProcessSoftwareBitmap(SoftwareBitmap softwareBitmap, Bgra8 tint) + private static unsafe void NormalBlend(SoftwareBitmap softwareBitmap, Bgra8 tint) { using (BitmapBuffer buffer = softwareBitmap.LockBuffer(BitmapBufferAccessMode.ReadWrite)) { @@ -108,10 +109,10 @@ private static unsafe void ProcessSoftwareBitmap(SoftwareBitmap softwareBitmap, for (int i = 0; i < length; i += 4) { Bgra8* pixel = (Bgra8*)(data + i); - - pixel->B = (byte)(((pixel->B * pixel->A) + (tint.B * (0xFF - pixel->A))) / 0xFF); - pixel->G = (byte)(((pixel->G * pixel->A) + (tint.G * (0xFF - pixel->A))) / 0xFF); - pixel->R = (byte)(((pixel->R * pixel->A) + (tint.R * (0xFF - pixel->A))) / 0xFF); + byte baseAlpha = pixel->A; + pixel->B = (byte)(((pixel->B * baseAlpha) + (tint.B * (0xFF - baseAlpha))) / 0xFF); + pixel->G = (byte)(((pixel->G * baseAlpha) + (tint.G * (0xFF - baseAlpha))) / 0xFF); + pixel->R = (byte)(((pixel->R * baseAlpha) + (tint.R * (0xFF - baseAlpha))) / 0xFF); pixel->A = 0xFF; } } @@ -191,7 +192,7 @@ private async Task RefreshCoreAsync(UserAndRole userAndRole, RefreshOption optio switch (result) { case RefreshResult.APIUnavailable: - infoBarService.Warning("角色信息服务当前不可用"); + infoBarService.Warning("角色信息服务 [Enak API] 当前不可用"); break; case RefreshResult.ShowcaseNotOpen: infoBarService.Warning("角色橱窗尚未开启,请前往游戏操作后重试"); @@ -216,16 +217,18 @@ private async Task ExportAsImageAsync(UIElement? element) IBuffer buffer = await bitmap.GetPixelsAsync(); SoftwareBitmap softwareBitmap = SoftwareBitmap.CreateCopyFromBuffer(buffer, BitmapPixelFormat.Bgra8, bitmap.PixelWidth, bitmap.PixelHeight, BitmapAlphaMode.Ignore); - Color systemAltHighColor = (Color)Ioc.Default.GetRequiredService().Resources["CompatBackgroundColor"]; - Bgra8 tint = Bgra8.FromColor(systemAltHighColor); - ProcessSoftwareBitmap(softwareBitmap, tint); + Color tintColor = (Color)Ioc.Default.GetRequiredService().Resources["CompatBackgroundColor"]; + Bgra8 tint = Bgra8.FromColor(tintColor); + NormalBlend(softwareBitmap, tint); using (InMemoryRandomAccessStream memory = new()) { - BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, memory); + BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, memory); encoder.SetSoftwareBitmap(softwareBitmap); await encoder.FlushAsync(); Clipboard.SetBitmapStream(memory); } + + infoBarService.Success("已导出到剪贴板"); } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiWeaponViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiWeaponViewModel.cs index b301280483..38bae40fd7 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiWeaponViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiWeaponViewModel.cs @@ -4,12 +4,21 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.WinUI.UI; using Snap.Hutao.Control; +using Snap.Hutao.Extension; using Snap.Hutao.Factory.Abstraction; +using Snap.Hutao.Model.Binding.Cultivation; using Snap.Hutao.Model.Binding.Hutao; using Snap.Hutao.Model.Metadata.Weapon; using Snap.Hutao.Model.Primitive; +using Snap.Hutao.Service.Abstraction; +using Snap.Hutao.Service.Cultivation; using Snap.Hutao.Service.Hutao; using Snap.Hutao.Service.Metadata; +using Snap.Hutao.Service.User; +using Snap.Hutao.View.Dialog; +using CalcAvatarPromotionDelta = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.AvatarPromotionDelta; +using CalcClient = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.CalculateClient; +using CalcConsumption = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.Consumption; namespace Snap.Hutao.ViewModel; @@ -43,6 +52,7 @@ public WikiWeaponViewModel(IMetadataService metadataService, IHutaoCache hutaoCa this.hutaoCache = hutaoCache; OpenUICommand = asyncRelayCommandFactory.Create(OpenUIAsync); + CultivateCommand = asyncRelayCommandFactory.Create(CultivateAsync); } /// @@ -63,6 +73,11 @@ public WikiWeaponViewModel(IMetadataService metadataService, IHutaoCache hutaoCa /// public ICommand OpenUICommand { get; } + /// + /// 养成命令 + /// + public ICommand CultivateCommand { get; } + private async Task OpenUIAsync() { if (await metadataService.InitializeAsync().ConfigureAwait(false)) @@ -91,4 +106,50 @@ private async Task CombineWithWeaponCollocationsAsync(List weapons) weapons.ForEach(w => w.Collocation = idCollocations.GetValueOrDefault(w.Id)); } } + + private async Task CultivateAsync(Weapon? weapon) + { + if (weapon != null) + { + IInfoBarService infoBarService = Ioc.Default.GetRequiredService(); + IUserService userService = Ioc.Default.GetRequiredService(); + + if (userService.Current != null) + { + MainWindow mainWindow = Ioc.Default.GetRequiredService(); + (bool isOk, CalcAvatarPromotionDelta delta) = await new CultivatePromotionDeltaDialog(mainWindow, null, weapon.ToCalculable()) + .GetPromotionDeltaAsync() + .ConfigureAwait(false); + + if (isOk) + { + CalcConsumption? consumption = await Ioc.Default + .GetRequiredService() + .ComputeAsync(userService.Current.Entity, delta) + .ConfigureAwait(false); + + if (consumption != null) + { + bool saved = await Ioc.Default + .GetRequiredService() + .SaveConsumptionAsync(CultivateType.Weapon, weapon.Id, consumption.WeaponConsume.EmptyIfNull()) + .ConfigureAwait(false); + + if (saved) + { + infoBarService.Success("已成功添加至当前养成计划"); + } + else + { + infoBarService.Warning("请先前往养成计划页面创建计划并选中"); + } + } + } + } + else + { + infoBarService.Warning("必须先选择一个用户与角色"); + } + } + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/Overview.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/Overview.cs index 2cf9d5de6a..2b3d0f909b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/Overview.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/Overview.cs @@ -37,7 +37,7 @@ public class Overview /// 数据刷新的时间 /// [JsonIgnore] - public DateTimeOffset RefreshTime { get => DateTimeOffset.FromUnixTimeSeconds(Timestamp); } + public string RefreshTime { get => $"{DateTimeOffset.FromUnixTimeMilliseconds(Timestamp).ToLocalTime():MM.dd HH:mm}"; } /// /// 总时间 diff --git a/src/Snap.Hutao/Snap.Hutao/WinRT/IMemoryBufferByteAccess.cs b/src/Snap.Hutao/Snap.Hutao/WinRT/IMemoryBufferByteAccess.cs deleted file mode 100644 index dc6c0b1d59..0000000000 --- a/src/Snap.Hutao/Snap.Hutao/WinRT/IMemoryBufferByteAccess.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -using System.Runtime.InteropServices; - -namespace Snap.Hutao.WinRT; - -/// -/// Provides access to an IMemoryBuffer as an array of bytes. -/// -[ComImport] -[Guid("5B0D3235-4DBA-4D44-865E-8F1D0E4FD04D")] -[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] -public unsafe interface IMemoryBufferByteAccess -{ - /// - /// Gets an IMemoryBuffer as an array of bytes. - /// - /// 指向包含缓冲区数据的字节数组的指针 - /// 返回数组中的字节数 - void GetBuffer(out byte* buffer, out uint capacity); -}