Merge remote-tracking branch 'upstream/CHN' into profile-visualizer
This commit is contained in:
commit
4495ee81c9
@ -22,6 +22,7 @@ namespace GameDatabase.Context
|
||||
}
|
||||
|
||||
public virtual DbSet<Card> Cards { get; set; } = null!;
|
||||
public virtual DbSet<Credential> Credentials { get; set; } = null!;
|
||||
public virtual DbSet<SongBestDatum> SongBestData { get; set; } = null!;
|
||||
public virtual DbSet<SongPlayDatum> SongPlayData { get; set; } = null!;
|
||||
public virtual DbSet<UserDatum> UserData { get; set; } = null!;
|
||||
@ -48,9 +49,25 @@ namespace GameDatabase.Context
|
||||
entity.HasKey(e => e.AccessCode);
|
||||
|
||||
entity.ToTable("Card");
|
||||
|
||||
entity.HasOne(d => d.Ba)
|
||||
.WithMany()
|
||||
.HasPrincipalKey(p => p.Baid)
|
||||
.HasForeignKey(d => d.Baid)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Credential>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Baid);
|
||||
|
||||
entity.HasIndex(e => e.Baid, "IX_Card_Baid")
|
||||
.IsUnique();
|
||||
entity.ToTable("Credential");
|
||||
|
||||
entity.HasOne(d => d.Ba)
|
||||
.WithMany()
|
||||
.HasPrincipalKey(p => p.Baid)
|
||||
.HasForeignKey(d => d.Baid)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<SongBestDatum>(entity =>
|
||||
@ -103,12 +120,6 @@ namespace GameDatabase.Context
|
||||
|
||||
entity.Property(e => e.LastPlayDatetime).HasColumnType("datetime");
|
||||
|
||||
entity.HasOne(d => d.Ba)
|
||||
.WithMany()
|
||||
.HasPrincipalKey(p => p.Baid)
|
||||
.HasForeignKey(d => d.Baid)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
entity.Property(e => e.AchievementDisplayDifficulty)
|
||||
.HasConversion<uint>();
|
||||
});
|
||||
|
@ -1,4 +1,5 @@
|
||||
using SharedProject.Enums;
|
||||
using SharedProject.Models;
|
||||
|
||||
namespace GameDatabase.Entities;
|
||||
|
||||
@ -14,5 +15,5 @@ public class AiScoreDatum
|
||||
|
||||
public List<AiSectionScoreDatum> AiSectionScoreData { get; set; } = new();
|
||||
|
||||
public virtual Card? Ba { get; set; }
|
||||
public virtual UserDatum? Ba { get; set; }
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
{
|
||||
public string AccessCode { get; set; } = null!;
|
||||
public ulong Baid { get; set; }
|
||||
public string Password { get; set; } = null!;
|
||||
public string Salt { get; set; } = null!;
|
||||
|
||||
public virtual UserDatum? Ba { get; set; }
|
||||
}
|
||||
}
|
11
GameDatabase/Entities/Credential.cs
Normal file
11
GameDatabase/Entities/Credential.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace GameDatabase.Entities
|
||||
{
|
||||
public partial class Credential
|
||||
{
|
||||
public ulong Baid { get; set; }
|
||||
public string Password { get; set; } = null!;
|
||||
public string Salt { get; set; } = null!;
|
||||
|
||||
public virtual UserDatum? Ba { get; set; }
|
||||
}
|
||||
}
|
@ -13,5 +13,5 @@ public class DanScoreDatum
|
||||
public DanClearState ClearState { get; set; }
|
||||
public List<DanStageScoreDatum> DanStageScoreData { get; set; } = new();
|
||||
|
||||
public virtual Card? Ba { get; set; }
|
||||
public virtual UserDatum? Ba { get; set; }
|
||||
}
|
@ -12,6 +12,6 @@ namespace GameDatabase.Entities
|
||||
public CrownType BestCrown { get; set; }
|
||||
public ScoreRank BestScoreRank { get; set; }
|
||||
|
||||
public virtual Card? Ba { get; set; }
|
||||
public virtual UserDatum? Ba { get; set; }
|
||||
}
|
||||
}
|
@ -24,6 +24,6 @@ namespace GameDatabase.Entities
|
||||
public bool Skipped { get; set; }
|
||||
public DateTime PlayTime { get; set; }
|
||||
|
||||
public virtual Card? Ba { get; set; }
|
||||
public virtual UserDatum? Ba { get; set; }
|
||||
}
|
||||
}
|
@ -33,6 +33,5 @@ namespace GameDatabase.Entities
|
||||
public int AiWinCount { get; set; }
|
||||
public string TokenCountDict { get; set; } = "{}";
|
||||
public string UnlockedSongIdList { get; set; } = "[]";
|
||||
public virtual Card? Ba { get; set; }
|
||||
}
|
||||
}
|
491
GameDatabase/Migrations/20231111154748_AddCredentialTable.Designer.cs
generated
Normal file
491
GameDatabase/Migrations/20231111154748_AddCredentialTable.Designer.cs
generated
Normal file
@ -0,0 +1,491 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using GameDatabase.Context;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace GameDatabase.Migrations
|
||||
{
|
||||
[DbContext(typeof(TaikoDbContext))]
|
||||
[Migration("20231111154748_AddCredentialTable")]
|
||||
partial class AddCredentialTable
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.0-rc.2.23480.1");
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsWin")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty");
|
||||
|
||||
b.ToTable("AiScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("SectionIndex")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Crown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsWin")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("MissCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Score")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty", "SectionIndex");
|
||||
|
||||
b.ToTable("AiSectionScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Card", b =>
|
||||
{
|
||||
b.Property<string>("AccessCode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Salt")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("AccessCode");
|
||||
|
||||
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Card", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Credential", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Salt")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Baid");
|
||||
|
||||
b.ToTable("Credential", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DanId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DanType")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<uint>("ArrivalSongCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ClearState")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(0u);
|
||||
|
||||
b.Property<uint>("ComboCountTotal")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SoulGaugeTotal")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "DanId", "DanType");
|
||||
|
||||
b.ToTable("DanScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DanId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DanType")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<uint>("SongNumber")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BadCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ComboCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("HighScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("PlayScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("TotalHitCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "DanId", "DanType", "SongNumber");
|
||||
|
||||
b.ToTable("DanStageScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestCrown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestRate")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestScoreRank")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty");
|
||||
|
||||
b.ToTable("SongBestData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ComboCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Crown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("HitCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("MissCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("PlayTime")
|
||||
.HasColumnType("datetime");
|
||||
|
||||
b.Property<uint>("Score")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ScoreRank")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ScoreRate")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("Skipped")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongNumber")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Baid");
|
||||
|
||||
b.ToTable("SongPlayData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.UserDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("AchievementDisplayDifficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AiWinCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorBody")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorFace")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorLimb")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("CostumeData")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CostumeFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DifficultyPlayedArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DifficultySettingArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("DisplayAchievement")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("DisplayDan")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("FavoriteSongsArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("GenericInfoFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSkipOn")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsVoiceOn")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("LastPlayDatetime")
|
||||
.HasColumnType("datetime");
|
||||
|
||||
b.Property<uint>("LastPlayMode")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("MyDonName")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("MyDonNameLanguage")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("NotesPosition")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<short>("OptionSetting")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SelectedToneId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TitleFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("TitlePlateId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("TokenCountDict")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ToneFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UnlockedSongIdList")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Baid");
|
||||
|
||||
b.ToTable("UserData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.AiScoreDatum", "Parent")
|
||||
.WithMany("AiSectionScoreData")
|
||||
.HasForeignKey("Baid", "SongId", "Difficulty")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.DanScoreDatum", "Parent")
|
||||
.WithMany("DanStageScoreData")
|
||||
.HasForeignKey("Baid", "DanId", "DanType")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.UserDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.Navigation("AiSectionScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.Navigation("DanStageScoreData");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
35
GameDatabase/Migrations/20231111154748_AddCredentialTable.cs
Normal file
35
GameDatabase/Migrations/20231111154748_AddCredentialTable.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace GameDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddCredentialTable : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Credential",
|
||||
columns: table => new
|
||||
{
|
||||
Baid = table.Column<ulong>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Password = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Salt = table.Column<string>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Credential", x => x.Baid);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Credential");
|
||||
}
|
||||
}
|
||||
}
|
491
GameDatabase/Migrations/20231111155016_CopyPasswordSaltFromCardToCredential.Designer.cs
generated
Normal file
491
GameDatabase/Migrations/20231111155016_CopyPasswordSaltFromCardToCredential.Designer.cs
generated
Normal file
@ -0,0 +1,491 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using GameDatabase.Context;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace GameDatabase.Migrations
|
||||
{
|
||||
[DbContext(typeof(TaikoDbContext))]
|
||||
[Migration("20231111155016_CopyPasswordSaltFromCardToCredential")]
|
||||
partial class CopyPasswordSaltFromCardToCredential
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.0-rc.2.23480.1");
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsWin")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty");
|
||||
|
||||
b.ToTable("AiScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("SectionIndex")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Crown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsWin")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("MissCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Score")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty", "SectionIndex");
|
||||
|
||||
b.ToTable("AiSectionScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Card", b =>
|
||||
{
|
||||
b.Property<string>("AccessCode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Salt")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("AccessCode");
|
||||
|
||||
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Card", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Credential", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Salt")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Baid");
|
||||
|
||||
b.ToTable("Credential", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DanId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DanType")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<uint>("ArrivalSongCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ClearState")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(0u);
|
||||
|
||||
b.Property<uint>("ComboCountTotal")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SoulGaugeTotal")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "DanId", "DanType");
|
||||
|
||||
b.ToTable("DanScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DanId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DanType")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<uint>("SongNumber")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BadCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ComboCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("HighScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("PlayScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("TotalHitCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "DanId", "DanType", "SongNumber");
|
||||
|
||||
b.ToTable("DanStageScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestCrown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestRate")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestScoreRank")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty");
|
||||
|
||||
b.ToTable("SongBestData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ComboCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Crown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("HitCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("MissCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("PlayTime")
|
||||
.HasColumnType("datetime");
|
||||
|
||||
b.Property<uint>("Score")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ScoreRank")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ScoreRate")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("Skipped")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongNumber")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Baid");
|
||||
|
||||
b.ToTable("SongPlayData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.UserDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("AchievementDisplayDifficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AiWinCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorBody")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorFace")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorLimb")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("CostumeData")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CostumeFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DifficultyPlayedArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DifficultySettingArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("DisplayAchievement")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("DisplayDan")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("FavoriteSongsArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("GenericInfoFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSkipOn")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsVoiceOn")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("LastPlayDatetime")
|
||||
.HasColumnType("datetime");
|
||||
|
||||
b.Property<uint>("LastPlayMode")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("MyDonName")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("MyDonNameLanguage")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("NotesPosition")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<short>("OptionSetting")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SelectedToneId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TitleFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("TitlePlateId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("TokenCountDict")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ToneFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UnlockedSongIdList")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Baid");
|
||||
|
||||
b.ToTable("UserData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.AiScoreDatum", "Parent")
|
||||
.WithMany("AiSectionScoreData")
|
||||
.HasForeignKey("Baid", "SongId", "Difficulty")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.DanScoreDatum", "Parent")
|
||||
.WithMany("DanStageScoreData")
|
||||
.HasForeignKey("Baid", "DanId", "DanType")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.UserDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.Navigation("AiSectionScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.Navigation("DanStageScoreData");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace GameDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class CopyPasswordSaltFromCardToCredential : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql(@"
|
||||
INSERT INTO Credential (Baid, Password, Salt)
|
||||
SELECT Baid, Password, Salt
|
||||
FROM Card
|
||||
");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql(@"
|
||||
UPDATE Card
|
||||
SET Password = (SELECT Password FROM Credential WHERE Credential.Baid = Card.Baid),
|
||||
Salt = (SELECT Salt FROM Credential WHERE Credential.Baid = Card.Baid)
|
||||
");
|
||||
}
|
||||
}
|
||||
}
|
483
GameDatabase/Migrations/20231111155305_RemovePasswordSaltFromCard.Designer.cs
generated
Normal file
483
GameDatabase/Migrations/20231111155305_RemovePasswordSaltFromCard.Designer.cs
generated
Normal file
@ -0,0 +1,483 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using GameDatabase.Context;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace GameDatabase.Migrations
|
||||
{
|
||||
[DbContext(typeof(TaikoDbContext))]
|
||||
[Migration("20231111155305_RemovePasswordSaltFromCard")]
|
||||
partial class RemovePasswordSaltFromCard
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.0-rc.2.23480.1");
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsWin")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty");
|
||||
|
||||
b.ToTable("AiScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("SectionIndex")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Crown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsWin")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("MissCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Score")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty", "SectionIndex");
|
||||
|
||||
b.ToTable("AiSectionScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Card", b =>
|
||||
{
|
||||
b.Property<string>("AccessCode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("AccessCode");
|
||||
|
||||
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Card", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Credential", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Salt")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Baid");
|
||||
|
||||
b.ToTable("Credential", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DanId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DanType")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<uint>("ArrivalSongCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ClearState")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(0u);
|
||||
|
||||
b.Property<uint>("ComboCountTotal")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SoulGaugeTotal")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "DanId", "DanType");
|
||||
|
||||
b.ToTable("DanScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DanId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DanType")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<uint>("SongNumber")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BadCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ComboCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("HighScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("PlayScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("TotalHitCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "DanId", "DanType", "SongNumber");
|
||||
|
||||
b.ToTable("DanStageScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestCrown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestRate")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestScoreRank")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty");
|
||||
|
||||
b.ToTable("SongBestData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ComboCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Crown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("HitCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("MissCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("PlayTime")
|
||||
.HasColumnType("datetime");
|
||||
|
||||
b.Property<uint>("Score")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ScoreRank")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ScoreRate")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("Skipped")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongNumber")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Baid");
|
||||
|
||||
b.ToTable("SongPlayData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.UserDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("AchievementDisplayDifficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AiWinCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorBody")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorFace")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorLimb")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("CostumeData")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CostumeFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DifficultyPlayedArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DifficultySettingArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("DisplayAchievement")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("DisplayDan")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("FavoriteSongsArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("GenericInfoFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSkipOn")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsVoiceOn")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("LastPlayDatetime")
|
||||
.HasColumnType("datetime");
|
||||
|
||||
b.Property<uint>("LastPlayMode")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("MyDonName")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("MyDonNameLanguage")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("NotesPosition")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<short>("OptionSetting")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SelectedToneId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TitleFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("TitlePlateId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("TokenCountDict")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ToneFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UnlockedSongIdList")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Baid");
|
||||
|
||||
b.ToTable("UserData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.AiScoreDatum", "Parent")
|
||||
.WithMany("AiSectionScoreData")
|
||||
.HasForeignKey("Baid", "SongId", "Difficulty")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.DanScoreDatum", "Parent")
|
||||
.WithMany("DanStageScoreData")
|
||||
.HasForeignKey("Baid", "DanId", "DanType")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.UserDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.Navigation("AiSectionScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.Navigation("DanStageScoreData");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace GameDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class RemovePasswordSaltFromCard : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Password",
|
||||
table: "Card");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Salt",
|
||||
table: "Card");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Password",
|
||||
table: "Card",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Salt",
|
||||
table: "Card",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
}
|
||||
}
|
||||
}
|
491
GameDatabase/Migrations/20231111164910_RemoveBaidUniquenessFromCard.Designer.cs
generated
Normal file
491
GameDatabase/Migrations/20231111164910_RemoveBaidUniquenessFromCard.Designer.cs
generated
Normal file
@ -0,0 +1,491 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using GameDatabase.Context;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace GameDatabase.Migrations
|
||||
{
|
||||
[DbContext(typeof(TaikoDbContext))]
|
||||
[Migration("20231111164910_RemoveBaidUniquenessFromCard")]
|
||||
partial class RemoveBaidUniquenessFromCard
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.0-rc.2.23480.1");
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsWin")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty");
|
||||
|
||||
b.ToTable("AiScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("SectionIndex")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Crown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsWin")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("MissCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Score")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty", "SectionIndex");
|
||||
|
||||
b.ToTable("AiSectionScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Card", b =>
|
||||
{
|
||||
b.Property<string>("AccessCode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("AccessCode");
|
||||
|
||||
b.ToTable("Card", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Credential", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Salt")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Baid");
|
||||
|
||||
b.ToTable("Credential", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DanId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DanType")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<uint>("ArrivalSongCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ClearState")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(0u);
|
||||
|
||||
b.Property<uint>("ComboCountTotal")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SoulGaugeTotal")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "DanId", "DanType");
|
||||
|
||||
b.ToTable("DanScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DanId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DanType")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<uint>("SongNumber")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BadCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ComboCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("HighScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("PlayScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("TotalHitCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "DanId", "DanType", "SongNumber");
|
||||
|
||||
b.ToTable("DanStageScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestCrown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestRate")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestScoreRank")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty");
|
||||
|
||||
b.ToTable("SongBestData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ComboCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Crown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("HitCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("MissCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("PlayTime")
|
||||
.HasColumnType("datetime");
|
||||
|
||||
b.Property<uint>("Score")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ScoreRank")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ScoreRate")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("Skipped")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongNumber")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Baid");
|
||||
|
||||
b.ToTable("SongPlayData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.UserDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("AchievementDisplayDifficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AiWinCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorBody")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorFace")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorLimb")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("CostumeData")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CostumeFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DifficultyPlayedArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DifficultySettingArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("DisplayAchievement")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("DisplayDan")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("FavoriteSongsArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("GenericInfoFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSkipOn")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsVoiceOn")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("LastPlayDatetime")
|
||||
.HasColumnType("datetime");
|
||||
|
||||
b.Property<uint>("LastPlayMode")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("MyDonName")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("MyDonNameLanguage")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("NotesPosition")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<short>("OptionSetting")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SelectedToneId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TitleFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("TitlePlateId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("TokenCountDict")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ToneFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UnlockedSongIdList")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Baid");
|
||||
|
||||
b.ToTable("UserData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.AiScoreDatum", "Parent")
|
||||
.WithMany("AiSectionScoreData")
|
||||
.HasForeignKey("Baid", "SongId", "Difficulty")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Credential", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.DanScoreDatum", "Parent")
|
||||
.WithMany("DanStageScoreData")
|
||||
.HasForeignKey("Baid", "DanId", "DanType")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.UserDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.Navigation("AiSectionScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.Navigation("DanStageScoreData");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace GameDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class RemoveBaidUniquenessFromCard : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Card_Baid",
|
||||
table: "Card");
|
||||
|
||||
migrationBuilder.AlterColumn<ulong>(
|
||||
name: "Baid",
|
||||
table: "Credential",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
oldClrType: typeof(ulong),
|
||||
oldType: "INTEGER")
|
||||
.OldAnnotation("Sqlite:Autoincrement", true);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Credential_Card_Baid",
|
||||
table: "Credential",
|
||||
column: "Baid",
|
||||
principalTable: "Card",
|
||||
principalColumn: "Baid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Credential_Card_Baid",
|
||||
table: "Credential");
|
||||
|
||||
migrationBuilder.AlterColumn<ulong>(
|
||||
name: "Baid",
|
||||
table: "Credential",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
oldClrType: typeof(ulong),
|
||||
oldType: "INTEGER")
|
||||
.Annotation("Sqlite:Autoincrement", true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Card_Baid",
|
||||
table: "Card",
|
||||
column: "Baid",
|
||||
unique: true);
|
||||
}
|
||||
}
|
||||
}
|
488
GameDatabase/Migrations/20231111225534_AlterForeignKeyToUserDatum.Designer.cs
generated
Normal file
488
GameDatabase/Migrations/20231111225534_AlterForeignKeyToUserDatum.Designer.cs
generated
Normal file
@ -0,0 +1,488 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using GameDatabase.Context;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace GameDatabase.Migrations
|
||||
{
|
||||
[DbContext(typeof(TaikoDbContext))]
|
||||
[Migration("20231111225534_AlterForeignKeyToUserDatum")]
|
||||
partial class AlterForeignKeyToUserDatum
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.0-rc.2.23480.1");
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsWin")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty");
|
||||
|
||||
b.ToTable("AiScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("SectionIndex")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Crown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsWin")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("MissCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Score")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty", "SectionIndex");
|
||||
|
||||
b.ToTable("AiSectionScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Card", b =>
|
||||
{
|
||||
b.Property<string>("AccessCode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("AccessCode");
|
||||
|
||||
b.HasIndex("Baid");
|
||||
|
||||
b.ToTable("Card", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Credential", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Salt")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Baid");
|
||||
|
||||
b.ToTable("Credential", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DanId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DanType")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<uint>("ArrivalSongCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ClearState")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(0u);
|
||||
|
||||
b.Property<uint>("ComboCountTotal")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SoulGaugeTotal")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "DanId", "DanType");
|
||||
|
||||
b.ToTable("DanScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DanId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DanType")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<uint>("SongNumber")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BadCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ComboCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("HighScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("PlayScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("TotalHitCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "DanId", "DanType", "SongNumber");
|
||||
|
||||
b.ToTable("DanStageScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestCrown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestRate")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestScoreRank")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty");
|
||||
|
||||
b.ToTable("SongBestData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ComboCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Crown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("HitCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("MissCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("PlayTime")
|
||||
.HasColumnType("datetime");
|
||||
|
||||
b.Property<uint>("Score")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ScoreRank")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ScoreRate")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("Skipped")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongNumber")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Baid");
|
||||
|
||||
b.ToTable("SongPlayData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.UserDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("AchievementDisplayDifficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AiWinCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorBody")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorFace")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorLimb")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("CostumeData")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CostumeFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DifficultyPlayedArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DifficultySettingArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("DisplayAchievement")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("DisplayDan")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("FavoriteSongsArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("GenericInfoFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSkipOn")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsVoiceOn")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("LastPlayDatetime")
|
||||
.HasColumnType("datetime");
|
||||
|
||||
b.Property<uint>("LastPlayMode")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("MyDonName")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("MyDonNameLanguage")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("NotesPosition")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<short>("OptionSetting")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SelectedToneId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TitleFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("TitlePlateId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("TokenCountDict")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ToneFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UnlockedSongIdList")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Baid");
|
||||
|
||||
b.ToTable("UserData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.AiScoreDatum", "Parent")
|
||||
.WithMany("AiSectionScoreData")
|
||||
.HasForeignKey("Baid", "SongId", "Difficulty")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Card", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Credential", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.DanScoreDatum", "Parent")
|
||||
.WithMany("DanStageScoreData")
|
||||
.HasForeignKey("Baid", "DanId", "DanType")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.Navigation("AiSectionScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.Navigation("DanStageScoreData");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace GameDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AlterForeignKeyToUserDatum : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_AiScoreData_Card_Baid",
|
||||
table: "AiScoreData");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Credential_Card_Baid",
|
||||
table: "Credential");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_DanScoreData_Card_Baid",
|
||||
table: "DanScoreData");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_SongBestData_Card_Baid",
|
||||
table: "SongBestData");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_SongPlayData_Card_Baid",
|
||||
table: "SongPlayData");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_UserData_Card_Baid",
|
||||
table: "UserData");
|
||||
|
||||
migrationBuilder.DropUniqueConstraint(
|
||||
name: "AK_Card_Baid",
|
||||
table: "Card");
|
||||
|
||||
migrationBuilder.AlterColumn<ulong>(
|
||||
name: "Baid",
|
||||
table: "UserData",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
oldClrType: typeof(ulong),
|
||||
oldType: "INTEGER")
|
||||
.Annotation("Sqlite:Autoincrement", true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Card_Baid",
|
||||
table: "Card",
|
||||
column: "Baid");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_AiScoreData_UserData_Baid",
|
||||
table: "AiScoreData",
|
||||
column: "Baid",
|
||||
principalTable: "UserData",
|
||||
principalColumn: "Baid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Card_UserData_Baid",
|
||||
table: "Card",
|
||||
column: "Baid",
|
||||
principalTable: "UserData",
|
||||
principalColumn: "Baid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Credential_UserData_Baid",
|
||||
table: "Credential",
|
||||
column: "Baid",
|
||||
principalTable: "UserData",
|
||||
principalColumn: "Baid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_DanScoreData_UserData_Baid",
|
||||
table: "DanScoreData",
|
||||
column: "Baid",
|
||||
principalTable: "UserData",
|
||||
principalColumn: "Baid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_SongBestData_UserData_Baid",
|
||||
table: "SongBestData",
|
||||
column: "Baid",
|
||||
principalTable: "UserData",
|
||||
principalColumn: "Baid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_SongPlayData_UserData_Baid",
|
||||
table: "SongPlayData",
|
||||
column: "Baid",
|
||||
principalTable: "UserData",
|
||||
principalColumn: "Baid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_AiScoreData_UserData_Baid",
|
||||
table: "AiScoreData");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Card_UserData_Baid",
|
||||
table: "Card");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Credential_UserData_Baid",
|
||||
table: "Credential");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_DanScoreData_UserData_Baid",
|
||||
table: "DanScoreData");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_SongBestData_UserData_Baid",
|
||||
table: "SongBestData");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_SongPlayData_UserData_Baid",
|
||||
table: "SongPlayData");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Card_Baid",
|
||||
table: "Card");
|
||||
|
||||
migrationBuilder.AlterColumn<ulong>(
|
||||
name: "Baid",
|
||||
table: "UserData",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
oldClrType: typeof(ulong),
|
||||
oldType: "INTEGER")
|
||||
.OldAnnotation("Sqlite:Autoincrement", true);
|
||||
|
||||
migrationBuilder.AddUniqueConstraint(
|
||||
name: "AK_Card_Baid",
|
||||
table: "Card",
|
||||
column: "Baid");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_AiScoreData_Card_Baid",
|
||||
table: "AiScoreData",
|
||||
column: "Baid",
|
||||
principalTable: "Card",
|
||||
principalColumn: "Baid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Credential_Card_Baid",
|
||||
table: "Credential",
|
||||
column: "Baid",
|
||||
principalTable: "Card",
|
||||
principalColumn: "Baid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_DanScoreData_Card_Baid",
|
||||
table: "DanScoreData",
|
||||
column: "Baid",
|
||||
principalTable: "Card",
|
||||
principalColumn: "Baid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_SongBestData_Card_Baid",
|
||||
table: "SongBestData",
|
||||
column: "Baid",
|
||||
principalTable: "Card",
|
||||
principalColumn: "Baid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_SongPlayData_Card_Baid",
|
||||
table: "SongPlayData",
|
||||
column: "Baid",
|
||||
principalTable: "Card",
|
||||
principalColumn: "Baid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_UserData_Card_Baid",
|
||||
table: "UserData",
|
||||
column: "Baid",
|
||||
principalTable: "Card",
|
||||
principalColumn: "Baid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ namespace TaikoLocalServer.Migrations
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.0-rc.1.23419.6");
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.0-rc.2.23480.1");
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
@ -84,6 +84,18 @@ namespace TaikoLocalServer.Migrations
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("AccessCode");
|
||||
|
||||
b.HasIndex("Baid");
|
||||
|
||||
b.ToTable("Card", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Credential", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
@ -92,12 +104,9 @@ namespace TaikoLocalServer.Migrations
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("AccessCode");
|
||||
b.HasKey("Baid");
|
||||
|
||||
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Card", (string)null);
|
||||
b.ToTable("Credential", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
@ -109,6 +118,7 @@ namespace TaikoLocalServer.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DanType")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
@ -140,6 +150,7 @@ namespace TaikoLocalServer.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DanType")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
@ -267,6 +278,7 @@ namespace TaikoLocalServer.Migrations
|
||||
modelBuilder.Entity("GameDatabase.Entities.UserDatum", b =>
|
||||
{
|
||||
b.Property<ulong>("Baid")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("AchievementDisplayDifficulty")
|
||||
@ -372,10 +384,9 @@ namespace TaikoLocalServer.Migrations
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
@ -393,12 +404,33 @@ namespace TaikoLocalServer.Migrations
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
modelBuilder.Entity("GameDatabase.Entities.Card", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Credential", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
@ -418,10 +450,9 @@ namespace TaikoLocalServer.Migrations
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
@ -430,22 +461,9 @@ namespace TaikoLocalServer.Migrations
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.UserDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.Card", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.HasPrincipalKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
|
169
README.md
169
README.md
@ -24,12 +24,125 @@ This is a server for Taiko no Tatsujin Nijiiro ver CHN
|
||||
|
||||
There are various data json files under wwwroot/data that can be customized.
|
||||
|
||||
- dan_data.json: This is used customize normal dans. TODO: Details
|
||||
- gaiden_data.json: This is used to customize gaiden dans.
|
||||
```json
|
||||
- dan_data.json: This is used customize normal dans.
|
||||
```
|
||||
[
|
||||
{
|
||||
"danId":20, // The danId of the gaiden dan, can be the same value as normal dans, but has to be unique in all gaidens
|
||||
"danId":1, // The danId of the dan, has to be unique in all dans in dan_data.json
|
||||
"verupNo":1, // Used to control whether the client should update to a new dan when offline cache files are still present
|
||||
"title":"5kyuu", // Title of the dan, for example, "5kyuu" = 5級, "9dan" = 九段, "14dan" = 達人, etc.
|
||||
"aryOdaiSong":[
|
||||
{
|
||||
"songNo":420, // The uniqueId of the first song
|
||||
"level":2, // The level of the first song, 1 = easy, 4 = oni, 5 = ura, etc.
|
||||
"isHiddenSongName":false // If set to true, the song name will be displayed as ??? in dani selection in-game
|
||||
},
|
||||
{
|
||||
"songNo":881, // The uniqueId of the second song
|
||||
"level":2,
|
||||
"isHiddenSongName":false
|
||||
},
|
||||
{
|
||||
"songNo":995, // The uniqueId of the third song
|
||||
"level":2,
|
||||
"isHiddenSongName":false
|
||||
}
|
||||
],
|
||||
"aryOdaiBorder":[
|
||||
{
|
||||
"odaiType":1, // The odai type, 1 = soul gauge percentage, 2 = good count, 3 = ok count, 4 = bad count, 5 = combo count, 6 = renda count, 7 = score, 8 = hit count
|
||||
"borderType":1, // Controls whether this odai requirement is shared, 1 means all 3 songs share this same odai requirement, 2 means 3 songs have separate odai requirements, to see how to set separate odai requirements, see the next dan example
|
||||
"redBorderTotal":92, // The odai requirement to get a red pass for this dan
|
||||
"goldBorderTotal":95 // The odai requirement to get a gold pass for this dan
|
||||
},
|
||||
{
|
||||
"odaiType":8,
|
||||
"borderType":1,
|
||||
"redBorderTotal":884,
|
||||
"goldBorderTotal":936
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"danId":14,
|
||||
"verupNo":1,
|
||||
"title":"9dan",
|
||||
"aryOdaiSong":[
|
||||
{
|
||||
"songNo":568,
|
||||
"level":4,
|
||||
"isHiddenSongName":false
|
||||
},
|
||||
{
|
||||
"songNo":117,
|
||||
"level":4,
|
||||
"isHiddenSongName":false
|
||||
},
|
||||
{
|
||||
"songNo":21,
|
||||
"level":4,
|
||||
"isHiddenSongName":false
|
||||
}
|
||||
],
|
||||
"aryOdaiBorder":[
|
||||
{
|
||||
"odaiType":1,
|
||||
"borderType":1,
|
||||
"redBorderTotal":100,
|
||||
"goldBorderTotal":100
|
||||
},
|
||||
{
|
||||
"odaiType":2,
|
||||
"borderType":1,
|
||||
"redBorderTotal":2045,
|
||||
"goldBorderTotal":2100
|
||||
},
|
||||
{
|
||||
"odaiType":4,
|
||||
"borderType":1,
|
||||
"redBorderTotal":10,
|
||||
"goldBorderTotal":5
|
||||
},
|
||||
{
|
||||
"odaiType":6, // This is set to 6, which means this is the renda requirement odai
|
||||
"borderType":2, // This is set to 2, which means the 3 songs have individual odai requirements
|
||||
"redBorder_1":107, // This means to get a red pass, you have to get above or equal to 107 rendas in song 1
|
||||
"goldBorder_1":114, // This means to get a gold pass, you have to get above or equal to 114 rendas in song 1
|
||||
"redBorder_2":74, // This means to get a red pass, you have to get above or equal to 74 rendas in song 2
|
||||
"goldBorder_2":79, // This means to get a gold pass, you have to get above or equal to 79 rendas in song 2
|
||||
"redBorder_3":54, // This means to get a red pass, you have to get above or equal to 54 rendas in song 3
|
||||
"goldBorder_3":59 // This means to get a gold pass, you have to get above or equal to 59 rendas in song 3
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
- event_folder_data.json: This is used to populate event folders/genres
|
||||
```
|
||||
[
|
||||
{
|
||||
"folderId": 1, // The folderId of the event folder, find corresponding folderId in wordlist.bin by searching keys called folder_eventX, where X is the folderId
|
||||
"verupNo": 1, // Used to control whether the client should update to a new event folder when offline cache files are still present
|
||||
"priority": 1,
|
||||
"songNo": [] // The uniqueId of the songs to be added to this event folder, if left empty, this folder will not show up in-game
|
||||
},
|
||||
{
|
||||
"folderId": 2,
|
||||
"verupNo": 1,
|
||||
"priority": 1,
|
||||
"songNo": [
|
||||
478, 153, 200, 482, 511, 672, 675, 646, 644, 645, 676, 671, 479,
|
||||
707, 480, 481, 203, 204, 483, 205, 202, 241, 14, 387, 197, 281, 226,
|
||||
484, 543, 512, 709, 35
|
||||
] // A populated event folder example
|
||||
}
|
||||
]
|
||||
```
|
||||
- gaiden_data.json: This is used to customize gaiden dans.
|
||||
```
|
||||
[
|
||||
{
|
||||
"danId":20, // The danId of the gaiden dan, can be the same value as a dan in dan_data.json, but has to be unique in all gaidens in gaiden_data.json
|
||||
"verupNo":1, // Used to control whether the client should update to a new dan when offline cache files are still present
|
||||
"title":"[JPN]=復活!ブルー十段,[ENG]=Blue 10Dan", // The title of the gaiden dan, which will be displayed when scanning the QR code and in dani select interface. Use language code to specify each language's entry. [JPN], [CHS], [CHT], [KOR], [ENG] are supported. Use comma to separate each language's entry.
|
||||
"aryOdaiSong":[ // Starting from here, it uses the same format as dan_data.json
|
||||
@ -72,8 +185,25 @@ There are various data json files under wwwroot/data that can be customized.
|
||||
}
|
||||
]
|
||||
```
|
||||
- intro_data.json: This is used to customize the song intro displayed before entering the game
|
||||
```
|
||||
[
|
||||
{
|
||||
"setId":1, // The setId of the intro, has to be unique in all intros in intro_data.json
|
||||
"verupNo":1, // Used to control whether the client should update to a new intro when offline cache files are still present
|
||||
"mainSongNo":1115, // The uniqueId of the main song, which will be displayed at the top of the four other songs
|
||||
"subSongNo":[1022,7,1089,1059] // The uniqueId of the four other songs, which will be displayed below the main song, there has to be 4 songs exactly
|
||||
},
|
||||
{
|
||||
"setId":2,
|
||||
"verupNo":1,
|
||||
"mainSongNo":1102,
|
||||
"subSongNo":[1065,966,1008,916]
|
||||
}
|
||||
]
|
||||
```
|
||||
- locked_songs_data.json: This is used to customize locked songs.
|
||||
```json
|
||||
```
|
||||
{
|
||||
"songNo": [
|
||||
// Fill in the uniqueId of songs you wish to lock
|
||||
@ -84,8 +214,17 @@ There are various data json files under wwwroot/data that can be customized.
|
||||
]
|
||||
}
|
||||
```
|
||||
- movie_data.json: This is used to control which in-game movie is displayed before entering the game
|
||||
```
|
||||
[
|
||||
{
|
||||
"movie_id": 0, // The movie id, 8 = iM@S 15th anniversary collab, 9 = iM@S 15th anniversary collab (en), 10 = ONE PIECE collab, 12 = ONE PIECE collab 2 (special mode here), 14 = Touhou collab 2021,15 = Taiko no Tatsujin 20th anniversary Soshina collab, 16 = Taiko no Tatsujin 20th anniversary Soshina collab (en), 17 = Taiko no Tatsujin 20th anniversary Soshina collab (zh-tw), 18 = Taiko no Tatsujin 20th anniversary Soshina collab (ko)
|
||||
"enable_days": 0 // Simply set to 999 for the movie to always be displayed
|
||||
}
|
||||
]
|
||||
```
|
||||
- qrcode_data.json: This is used to customize which qrcode's uniqueId is invoked when a qrcode request is received.
|
||||
```json
|
||||
```
|
||||
[
|
||||
{
|
||||
"serial": "gaiden_blue_10dan", // QR serial data sent by TAL
|
||||
@ -98,7 +237,7 @@ There are various data json files under wwwroot/data that can be customized.
|
||||
]
|
||||
```
|
||||
- shop_folder_data.json: This is used to customize the in-game shop folder content.
|
||||
```json
|
||||
```
|
||||
[
|
||||
{
|
||||
"songNo": 100, // The uniqueId of the song
|
||||
@ -111,11 +250,25 @@ There are various data json files under wwwroot/data that can be customized.
|
||||
]
|
||||
```
|
||||
- token_data.json: This is used to customize in-game reward tokens.
|
||||
```json
|
||||
```
|
||||
{
|
||||
"shopTokenId": -1, // The token id used in shop, a.k.a. don coin, can be from 1 to 11, 1=spring, 2=summer, 3=autumn, 4=winter, 5=spring(again), etc. By default, this is turned off by setting it to -1
|
||||
"kaTokenId": -1, // The token id of ka coins, can be 1000 or 1001, corresponding to reward entrys in reward.bin in the client's datatable. By default, this is turned off by setting it to -1
|
||||
"onePieceTokenId": 100100, // The token id representing onePiece collab mode's win count, should not be changed
|
||||
"soshinaTokenId": 100200 // The token id representing soshina collab mode's win count, should not be changed
|
||||
}
|
||||
```
|
||||
|
||||
## TaikoWebUI appsettings.json config
|
||||
This section is for configuring the TaikoWebUI appsettings.json file found under the ```wwwroot``` folder.
|
||||
This file is used to configure the web UI.
|
||||
```
|
||||
{
|
||||
"WebUiSettings": {
|
||||
"LoginRequired": "false", // Whether a login is required to access personal profiles, default to false
|
||||
"AdminUserName": "admin", // The username of the admin account, if LoginRequired is set to false, this is ignored, admin account can always access all personal profiles
|
||||
"AdminPassword": "admin", // The password of the admin account, if LoginRequired is set to false, this is ignored
|
||||
"OnlyAdmin": "false" // Whether only the admin account can access personal profiles, if set to true, register will be unavailable and only admins can login, default to false
|
||||
}
|
||||
}
|
||||
```
|
8
SharedProject/Models/Requests/BindAccessCodeRequest.cs
Normal file
8
SharedProject/Models/Requests/BindAccessCodeRequest.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace SharedProject.Models.Requests;
|
||||
|
||||
public class BindAccessCodeRequest
|
||||
{
|
||||
public string AccessCode { get; set; } = string.Empty;
|
||||
|
||||
public uint Baid { get; set; }
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
|
||||
public class SetPasswordRequest
|
||||
{
|
||||
public string AccessCode { get; set; } = default!;
|
||||
public uint Baid { get; set; }
|
||||
public string Password { get; set; } = default!;
|
||||
public string Salt { get; set; } = default!;
|
||||
}
|
@ -3,4 +3,6 @@
|
||||
public class DashboardResponse
|
||||
{
|
||||
public List<User> Users { get; set; } = new();
|
||||
|
||||
public List<UserCredential> UserCredentials { get; set; } = new();
|
||||
}
|
@ -2,11 +2,7 @@
|
||||
|
||||
public class User
|
||||
{
|
||||
public string AccessCode { get; set; } = string.Empty;
|
||||
|
||||
public uint Baid { get; set; }
|
||||
|
||||
public string Password { get; set; } = string.Empty;
|
||||
|
||||
public string Salt { get; set; } = string.Empty;
|
||||
|
||||
public List<string> AccessCodes { get; set; } = new();
|
||||
}
|
10
SharedProject/Models/UserCredential.cs
Normal file
10
SharedProject/Models/UserCredential.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace SharedProject.Models;
|
||||
|
||||
public class UserCredential
|
||||
{
|
||||
public uint Baid { get; set; }
|
||||
|
||||
public string Password { get; set; } = string.Empty;
|
||||
|
||||
public string Salt { get; set; } = string.Empty;
|
||||
}
|
@ -53,11 +53,14 @@ public class UserSetting
|
||||
public List<uint> UnlockedFace { get; set; } = new();
|
||||
|
||||
public List<uint> UnlockedPuchi { get; set; } = new();
|
||||
|
||||
public List<uint> UnlockedTitle { get; set; } = new();
|
||||
|
||||
public uint FaceColor { get; set; }
|
||||
|
||||
public uint BodyColor { get; set; }
|
||||
|
||||
public uint LimbColor { get; set; }
|
||||
|
||||
|
||||
public DateTime LastPlayDateTime { get; set; }
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using SharedProject.Models.Requests;
|
||||
using GameDatabase.Entities;
|
||||
using SharedProject.Models.Requests;
|
||||
|
||||
namespace TaikoLocalServer.Controllers.Api;
|
||||
|
||||
@ -12,7 +13,7 @@ public class CardsController : BaseController<CardsController>
|
||||
{
|
||||
this.cardService = cardService;
|
||||
}
|
||||
|
||||
|
||||
[HttpDelete("{accessCode}")]
|
||||
public async Task<IActionResult> DeleteUser(string accessCode)
|
||||
{
|
||||
@ -22,12 +23,21 @@ public class CardsController : BaseController<CardsController>
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> UpdatePassword(SetPasswordRequest request)
|
||||
public async Task<IActionResult> BindAccessCode(BindAccessCodeRequest request)
|
||||
{
|
||||
var accessCode = request.AccessCode;
|
||||
var password = request.Password;
|
||||
var salt = request.Salt;
|
||||
var result = await cardService.UpdatePassword(accessCode, password, salt);
|
||||
return result ? NoContent() : NotFound();
|
||||
var baid = request.Baid;
|
||||
var existingCard = await cardService.GetCardByAccessCode(accessCode);
|
||||
if (existingCard is not null)
|
||||
{
|
||||
return BadRequest("Access code already exists");
|
||||
}
|
||||
var newCard = new Card
|
||||
{
|
||||
Baid = baid,
|
||||
AccessCode = accessCode
|
||||
};
|
||||
await cardService.AddCard(newCard);
|
||||
return NoContent();
|
||||
}
|
||||
}
|
25
TaikoLocalServer/Controllers/Api/CredentialsController.cs
Normal file
25
TaikoLocalServer/Controllers/Api/CredentialsController.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using SharedProject.Models.Requests;
|
||||
|
||||
namespace TaikoLocalServer.Controllers.Api;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class CredentialsController : BaseController<CredentialsController>
|
||||
{
|
||||
private readonly ICredentialService credentialService;
|
||||
|
||||
public CredentialsController(ICredentialService credentialService)
|
||||
{
|
||||
this.credentialService = credentialService;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> UpdatePassword(SetPasswordRequest request)
|
||||
{
|
||||
var baid = request.Baid;
|
||||
var password = request.Password;
|
||||
var salt = request.Salt;
|
||||
var result = await credentialService.UpdatePassword(baid, password, salt);
|
||||
return result ? NoContent() : NotFound();
|
||||
}
|
||||
}
|
@ -7,19 +7,23 @@ namespace TaikoLocalServer.Controllers.Api;
|
||||
public class DashboardController : BaseController<DashboardController>
|
||||
{
|
||||
private readonly ICardService cardService;
|
||||
private readonly ICredentialService credentialService;
|
||||
|
||||
public DashboardController(ICardService cardService)
|
||||
public DashboardController(ICardService cardService, ICredentialService credentialService)
|
||||
{
|
||||
this.cardService = cardService;
|
||||
this.credentialService = credentialService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<DashboardResponse> GetDashboard()
|
||||
{
|
||||
var users = await cardService.GetUsersFromCards();
|
||||
var credentials = await credentialService.GetUserCredentialsFromCredentials();
|
||||
return new DashboardResponse
|
||||
{
|
||||
Users = users
|
||||
Users = users,
|
||||
UserCredentials = credentials
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
using SharedProject.Models;
|
||||
using SharedProject.Utils;
|
||||
using System.Text.Json;
|
||||
using Throw;
|
||||
|
||||
namespace TaikoLocalServer.Controllers.Api;
|
||||
|
||||
@ -25,12 +26,24 @@ public class UserSettingsController : BaseController<UserSettingsController>
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var difficultySettingArray = JsonHelper.GetUIntArrayFromJson(user.DifficultySettingArray, 3, Logger, nameof(user.DifficultySettingArray));
|
||||
var difficultySettingArray = JsonHelper.GetUIntArrayFromJson(user.DifficultySettingArray, 3, Logger,
|
||||
nameof(user.DifficultySettingArray));
|
||||
|
||||
var costumeData = JsonHelper.GetCostumeDataFromUserData(user, Logger);
|
||||
|
||||
var costumeUnlockData = JsonHelper.GetCostumeUnlockDataFromUserData(user, Logger);
|
||||
|
||||
var unlockedTitle = JsonHelper.GetUIntArrayFromJson(user.TitleFlgArray, 0, Logger, nameof(user.TitleFlgArray))
|
||||
.ToList();
|
||||
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
if (!costumeUnlockData[i].Contains(0))
|
||||
{
|
||||
costumeUnlockData[i].Add(0);
|
||||
}
|
||||
}
|
||||
|
||||
var response = new UserSetting
|
||||
{
|
||||
AchievementDisplayDifficulty = user.AchievementDisplayDifficulty,
|
||||
@ -58,9 +71,11 @@ public class UserSettingsController : BaseController<UserSettingsController>
|
||||
UnlockedBody = costumeUnlockData[2],
|
||||
UnlockedFace = costumeUnlockData[3],
|
||||
UnlockedPuchi = costumeUnlockData[4],
|
||||
UnlockedTitle = unlockedTitle,
|
||||
BodyColor = user.ColorBody,
|
||||
FaceColor = user.ColorFace,
|
||||
LimbColor = user.ColorLimb
|
||||
LimbColor = user.ColorLimb,
|
||||
LastPlayDateTime = user.LastPlayDatetime
|
||||
};
|
||||
return Ok(response);
|
||||
}
|
||||
@ -109,6 +124,21 @@ public class UserSettingsController : BaseController<UserSettingsController>
|
||||
user.ColorLimb = userSetting.LimbColor;
|
||||
user.CostumeData = JsonSerializer.Serialize(costumes);
|
||||
|
||||
// If a locked tone is selected, unlock it
|
||||
uint[] toneFlg = { 0u };
|
||||
try
|
||||
{
|
||||
toneFlg = JsonSerializer.Deserialize<uint[]>(user.ToneFlgArray)!;
|
||||
}
|
||||
catch (JsonException e)
|
||||
{
|
||||
Logger.LogError(e, "Parsing tone flg json data failed");
|
||||
}
|
||||
toneFlg.ThrowIfNull("Tone flg should never be null!");
|
||||
toneFlg = toneFlg.Append(0u).Append(userSetting.ToneId).Distinct().ToArray();
|
||||
|
||||
user.ToneFlgArray = JsonSerializer.Serialize(toneFlg);
|
||||
|
||||
await userDatumService.UpdateUserDatum(user);
|
||||
|
||||
return NoContent();
|
||||
|
23
TaikoLocalServer/Controllers/Api/UsersController.cs
Normal file
23
TaikoLocalServer/Controllers/Api/UsersController.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using SharedProject.Models.Requests;
|
||||
|
||||
namespace TaikoLocalServer.Controllers.Api;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class UsersController : BaseController<UsersController>
|
||||
{
|
||||
private readonly IUserDatumService userDatumService;
|
||||
|
||||
public UsersController(IUserDatumService userDatumService)
|
||||
{
|
||||
this.userDatumService = userDatumService;
|
||||
}
|
||||
|
||||
[HttpDelete("{baid}")]
|
||||
public async Task<IActionResult> DeleteUser(uint baid)
|
||||
{
|
||||
var result = await userDatumService.DeleteUser(baid);
|
||||
|
||||
return result ? NoContent() : NotFound();
|
||||
}
|
||||
}
|
@ -9,11 +9,14 @@ public class MyDonEntryController : BaseController<MyDonEntryController>
|
||||
private readonly IUserDatumService userDatumService;
|
||||
|
||||
private readonly ICardService cardService;
|
||||
|
||||
private readonly ICredentialService credentialService;
|
||||
|
||||
public MyDonEntryController(IUserDatumService userDatumService, ICardService cardService)
|
||||
public MyDonEntryController(IUserDatumService userDatumService, ICardService cardService, ICredentialService credentialService)
|
||||
{
|
||||
this.userDatumService = userDatumService;
|
||||
this.cardService = cardService;
|
||||
this.credentialService = credentialService;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
@ -23,13 +26,6 @@ public class MyDonEntryController : BaseController<MyDonEntryController>
|
||||
Logger.LogInformation("MyDonEntry request : {Request}", request.Stringify());
|
||||
|
||||
var newId = cardService.GetNextBaid();
|
||||
await cardService.AddCard(new Card
|
||||
{
|
||||
AccessCode = request.WechatQrStr,
|
||||
Baid = newId,
|
||||
Password = "",
|
||||
Salt = ""
|
||||
});
|
||||
|
||||
var newUser = new UserDatum
|
||||
{
|
||||
@ -45,14 +41,26 @@ public class MyDonEntryController : BaseController<MyDonEntryController>
|
||||
FavoriteSongsArray = "[]",
|
||||
ToneFlgArray = "[0]",
|
||||
TitleFlgArray = "[]",
|
||||
CostumeFlgArray = "[[],[],[],[],[]]",
|
||||
CostumeFlgArray = "[[0],[0],[0],[0],[0]]",
|
||||
GenericInfoFlgArray = "[]",
|
||||
TokenCountDict = "{}",
|
||||
UnlockedSongIdList = "[]"
|
||||
};
|
||||
|
||||
await userDatumService.InsertUserDatum(newUser);
|
||||
|
||||
await cardService.AddCard(new Card
|
||||
{
|
||||
AccessCode = request.WechatQrStr,
|
||||
Baid = newId
|
||||
});
|
||||
|
||||
await credentialService.AddCredential(new Credential
|
||||
{
|
||||
Baid = newId,
|
||||
Password = "",
|
||||
Salt = ""
|
||||
});
|
||||
|
||||
var response = new MydonEntryResponse
|
||||
{
|
||||
Result = 1,
|
||||
|
@ -5,8 +5,8 @@ namespace TaikoLocalServer.Models;
|
||||
public class DonCosRewardEntry
|
||||
{
|
||||
[JsonPropertyName("cosType")]
|
||||
public string cosType { get; set; } = null!;
|
||||
public string CosType { get; set; } = null!;
|
||||
|
||||
[JsonPropertyName("uniqueId")]
|
||||
public uint uniqueId { get; set; }
|
||||
public uint UniqueId { get; set; }
|
||||
}
|
@ -8,5 +8,5 @@ public class MusicInfoEntry
|
||||
public uint MusicId { get; set; }
|
||||
|
||||
[JsonPropertyName("starUra")]
|
||||
public uint starUra { get; set; }
|
||||
public uint StarUra { get; set; }
|
||||
}
|
@ -5,5 +5,5 @@ namespace TaikoLocalServer.Models;
|
||||
public class NeiroEntry
|
||||
{
|
||||
[JsonPropertyName("uniqueId")]
|
||||
public uint uniqueId { get; set; }
|
||||
public uint UniqueId { get; set; }
|
||||
}
|
@ -5,5 +5,8 @@ namespace TaikoLocalServer.Models;
|
||||
public class ShougouEntry
|
||||
{
|
||||
[JsonPropertyName("uniqueId")]
|
||||
public uint uniqueId { get; set; }
|
||||
public uint UniqueId { get; set; }
|
||||
|
||||
[JsonPropertyName("rarity")]
|
||||
public uint Rarity { get; set; }
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
using GameDatabase.Context;
|
||||
using GameDatabase.Entities;
|
||||
using OneOf.Types;
|
||||
using SharedProject.Models;
|
||||
using Swan.Mapping;
|
||||
|
||||
@ -26,7 +27,30 @@ public class CardService : ICardService
|
||||
|
||||
public async Task<List<User>> GetUsersFromCards()
|
||||
{
|
||||
return await context.Cards.Select(card => card.CopyPropertiesToNew<User>(null)).ToListAsync();
|
||||
var cardEntries = await context.Cards.ToListAsync();
|
||||
List<User> users = new();
|
||||
var found = false;
|
||||
foreach (var cardEntry in cardEntries)
|
||||
{
|
||||
foreach (var user in users.Where(user => user.Baid == cardEntry.Baid))
|
||||
{
|
||||
user.AccessCodes.Add(cardEntry.AccessCode);
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
var user = new User
|
||||
{
|
||||
Baid = (uint)cardEntry.Baid,
|
||||
AccessCodes = new List<string> {cardEntry.AccessCode}
|
||||
};
|
||||
users.Add(user);
|
||||
}
|
||||
|
||||
found = false;
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
public async Task AddCard(Card card)
|
||||
@ -34,32 +58,13 @@ public class CardService : ICardService
|
||||
context.Add(card);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool> DeleteCard(string accessCode)
|
||||
{
|
||||
var card = await context.Cards.FindAsync(accessCode);
|
||||
|
||||
if (card is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (card == null) return false;
|
||||
context.Cards.Remove(card);
|
||||
await context.SaveChangesAsync();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdatePassword(string accessCode, string password, string salt)
|
||||
{
|
||||
var card = await context.Cards.FindAsync(accessCode);
|
||||
|
||||
if (card is null) return false;
|
||||
|
||||
card.Password = password;
|
||||
card.Salt = salt;
|
||||
await context.SaveChangesAsync();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
52
TaikoLocalServer/Services/CredentialService.cs
Normal file
52
TaikoLocalServer/Services/CredentialService.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using GameDatabase.Context;
|
||||
using GameDatabase.Entities;
|
||||
using SharedProject.Models;
|
||||
using Swan.Mapping;
|
||||
|
||||
namespace TaikoLocalServer.Services;
|
||||
|
||||
public class CredentialService : ICredentialService
|
||||
{
|
||||
private readonly TaikoDbContext context;
|
||||
|
||||
public CredentialService(TaikoDbContext context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public async Task<List<UserCredential>> GetUserCredentialsFromCredentials()
|
||||
{
|
||||
return await context.Credentials.Select(credential => credential.CopyPropertiesToNew<UserCredential>(null)).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task AddCredential(Credential credential)
|
||||
{
|
||||
context.Add(credential);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteCredential(uint baid)
|
||||
{
|
||||
var credential = await context.Credentials.FindAsync((ulong)baid);
|
||||
|
||||
if (credential is null) return false;
|
||||
|
||||
context.Credentials.Remove(credential);
|
||||
await context.SaveChangesAsync();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdatePassword(uint baid, string password, string salt)
|
||||
{
|
||||
var credential = await context.Credentials.FindAsync((ulong)baid);
|
||||
|
||||
if (credential is null) return false;
|
||||
|
||||
credential.Password = password;
|
||||
credential.Salt = salt;
|
||||
await context.SaveChangesAsync();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ public static class ServiceExtensions
|
||||
public static IServiceCollection AddTaikoDbServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<ICardService, CardService>();
|
||||
services.AddScoped<ICredentialService, CredentialService>();
|
||||
services.AddScoped<IUserDatumService, UserDatumService>();
|
||||
services.AddScoped<ISongPlayDatumService, SongPlayDatumService>();
|
||||
services.AddScoped<ISongBestDatumService, SongBestDatumService>();
|
||||
|
@ -331,7 +331,7 @@ public class GameDataService : IGameDataService
|
||||
.ToList();
|
||||
musics.Sort();
|
||||
|
||||
musicsWithUra = musicInfoes.Where(info => info.Value.starUra > 0)
|
||||
musicsWithUra = musicInfoes.Where(info => info.Value.StarUra > 0)
|
||||
.Select(pair => pair.Key)
|
||||
.ToList();
|
||||
musicsWithUra.Sort();
|
||||
@ -362,20 +362,20 @@ public class GameDataService : IGameDataService
|
||||
{
|
||||
donCosRewardData.ThrowIfNull("Shouldn't happen!");
|
||||
var kigurumiUniqueIdList = donCosRewardData.DonCosRewardEntries
|
||||
.Where(entry => entry.cosType == "kigurumi")
|
||||
.Select(entry => entry.uniqueId);
|
||||
.Where(entry => entry.CosType == "kigurumi")
|
||||
.Select(entry => entry.UniqueId);
|
||||
var headUniqueIdList = donCosRewardData.DonCosRewardEntries
|
||||
.Where(entry => entry.cosType == "head")
|
||||
.Select(entry => entry.uniqueId);
|
||||
.Where(entry => entry.CosType == "head")
|
||||
.Select(entry => entry.UniqueId);
|
||||
var bodyUniqueIdList = donCosRewardData.DonCosRewardEntries
|
||||
.Where(entry => entry.cosType == "body")
|
||||
.Select(entry => entry.uniqueId);
|
||||
.Where(entry => entry.CosType == "body")
|
||||
.Select(entry => entry.UniqueId);
|
||||
var faceUniqueIdList = donCosRewardData.DonCosRewardEntries
|
||||
.Where(entry => entry.cosType == "face")
|
||||
.Select(entry => entry.uniqueId);
|
||||
.Where(entry => entry.CosType == "face")
|
||||
.Select(entry => entry.UniqueId);
|
||||
var puchiUniqueIdList = donCosRewardData.DonCosRewardEntries
|
||||
.Where(entry => entry.cosType == "puchi")
|
||||
.Select(entry => entry.uniqueId);
|
||||
.Where(entry => entry.CosType == "puchi")
|
||||
.Select(entry => entry.UniqueId);
|
||||
|
||||
costumeFlagArraySizes = new List<int>
|
||||
{
|
||||
@ -390,13 +390,13 @@ public class GameDataService : IGameDataService
|
||||
private void InitializeTitleFlagArraySize(Shougous? shougouData)
|
||||
{
|
||||
shougouData.ThrowIfNull("Shouldn't happen!");
|
||||
titleFlagArraySize = (int)shougouData.ShougouEntries.Max(entry => entry.uniqueId) + 1;
|
||||
titleFlagArraySize = (int)shougouData.ShougouEntries.Max(entry => entry.UniqueId) + 1;
|
||||
}
|
||||
|
||||
private void InitializeToneFlagArraySize(Neiros? neiroData)
|
||||
{
|
||||
neiroData.ThrowIfNull("Shouldn't happen!");
|
||||
toneFlagArraySize = (int)neiroData.NeiroEntries.Max(entry => entry.uniqueId) + 1;
|
||||
toneFlagArraySize = (int)neiroData.NeiroEntries.Max(entry => entry.UniqueId) + 1;
|
||||
}
|
||||
|
||||
private void InitializeQrCodeData(List<QRCodeData>? qrCodeData)
|
||||
|
@ -12,8 +12,6 @@ public interface ICardService
|
||||
public Task<List<User>> GetUsersFromCards();
|
||||
|
||||
public Task AddCard(Card card);
|
||||
|
||||
public Task<bool> DeleteCard(string accessCode);
|
||||
|
||||
public Task<bool> UpdatePassword(string accessCode, string password, string salt);
|
||||
public Task<bool> DeleteCard(string accessCode);
|
||||
}
|
15
TaikoLocalServer/Services/Interfaces/ICredentialService.cs
Normal file
15
TaikoLocalServer/Services/Interfaces/ICredentialService.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using GameDatabase.Entities;
|
||||
using SharedProject.Models;
|
||||
|
||||
namespace TaikoLocalServer.Services.Interfaces;
|
||||
|
||||
public interface ICredentialService
|
||||
{
|
||||
public Task<List<UserCredential>> GetUserCredentialsFromCredentials();
|
||||
|
||||
public Task AddCredential(Credential credential);
|
||||
|
||||
public Task<bool> DeleteCredential(uint baid);
|
||||
|
||||
public Task<bool> UpdatePassword(uint baid, string password, string salt);
|
||||
}
|
@ -16,9 +16,9 @@ public interface IUserDatumService
|
||||
|
||||
public Task UpdateUserDatum(UserDatum userDatum);
|
||||
|
||||
public Task<bool> DeleteUser(uint baid);
|
||||
|
||||
public Task<List<uint>> GetFavoriteSongIds(ulong baid);
|
||||
|
||||
public Task UpdateFavoriteSong(ulong baid, uint songId, bool isFavorite);
|
||||
|
||||
|
||||
}
|
@ -56,6 +56,16 @@ public class UserDatumService : IUserDatumService
|
||||
context.Update(userDatum);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteUser(uint baid)
|
||||
{
|
||||
var userDatum = await context.UserData.FindAsync((ulong)baid);
|
||||
if (userDatum == null) return false;
|
||||
context.UserData.Remove(userDatum);
|
||||
await context.SaveChangesAsync();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<List<uint>> GetFavoriteSongIds(ulong baid)
|
||||
{
|
||||
|
87
TaikoWebUI/Pages/AccessCode.razor
Normal file
87
TaikoWebUI/Pages/AccessCode.razor
Normal file
@ -0,0 +1,87 @@
|
||||
@page "/Users/{baid:int}/AccessCode"
|
||||
@inject HttpClient Client
|
||||
@inject IDialogService DialogService
|
||||
@inject LoginService LoginService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<MudBreadcrumbs Items="breadcrumbs" Class="px-0"></MudBreadcrumbs>
|
||||
|
||||
<h1>Access Code Management</h1>
|
||||
<MudText Typo="Typo.caption">User: @Baid</MudText>
|
||||
|
||||
@if (response is null)
|
||||
{
|
||||
@for (uint i = 0; i < 3; i++)
|
||||
{
|
||||
<MudItem xs="12" md="6" lg="4">
|
||||
<MudCard Outlined="true">
|
||||
<MudCardContent>
|
||||
<MudSkeleton Width="30%" Height="42px;" Class="mb-5"/>
|
||||
<MudSkeleton Width="80%"/>
|
||||
<MudSkeleton Width="100%"/>
|
||||
</MudCardContent>
|
||||
<MudCardActions>
|
||||
<MudStack Row="true" Style="width:100%" Spacing="4" Justify="Justify.FlexEnd">
|
||||
<MudSkeleton Width="64px" Height="40px"/>
|
||||
<MudSkeleton Width="64px" Height="40px"/>
|
||||
</MudStack>
|
||||
</MudCardActions>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@if ((LoginService.LoginRequired && (!LoginService.IsLoggedIn || (LoginService.GetLoggedInUser().Baid != Baid && !LoginService.IsAdmin))) || User is null)
|
||||
{
|
||||
<MudItem xs="12" md="6" lg="4">
|
||||
<MudText Align="Align.Center" Class="my-8">
|
||||
Please log in by clicking on "Users" tab first.
|
||||
</MudText>
|
||||
</MudItem>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudGrid Justify="Justify.Center">
|
||||
<MudItem xs="12" md="6" lg="4">
|
||||
<MudCard>
|
||||
<MudCardContent>
|
||||
<MudForm @ref="bindAccessCodeForm">
|
||||
<MudText Typo="Typo.h4" Align="Align.Center">Bind New Access Code</MudText>
|
||||
<MudTextField @bind-value="inputAccessCode" InputType="InputType.Text" T="string"
|
||||
FullWidth="true" Required="@true" RequiredError="Access Code is required"
|
||||
Label="New Access Code"/>
|
||||
<MudButton OnClick="OnBind" FullWidth="true" Class="mt-3" StartIcon="@Icons.Material.Filled.AddCard" Color="Color.Primary" Variant="Variant.Filled">Bind</MudButton>
|
||||
</MudForm>
|
||||
</MudCardContent>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
<MudDivider/>
|
||||
@for (var idx = 0; idx < User.AccessCodes.Count; idx++)
|
||||
{
|
||||
var accessCode = User.AccessCodes[idx];
|
||||
var localIdx = idx + 1;
|
||||
<MudItem xs="12" md="6" lg="4">
|
||||
<MudCard Outlined="true">
|
||||
<MudCardHeader>
|
||||
<CardHeaderContent>
|
||||
<MudText Typo="Typo.h6" Style="font-weight:bold">User Access Code @localIdx</MudText>
|
||||
</CardHeaderContent>
|
||||
</MudCardHeader>
|
||||
<MudCardContent>
|
||||
<MudText Style="font-weight:bold">@accessCode</MudText>
|
||||
</MudCardContent>
|
||||
<MudCardActions>
|
||||
<MudButton OnClick="@(_ => DeleteAccessCode(accessCode))"
|
||||
Size="Size.Small" Variant="Variant.Text" StartIcon="@Icons.Material.Filled.Delete"
|
||||
Color="Color.Primary">
|
||||
Delete Access Code
|
||||
</MudButton>
|
||||
</MudCardActions>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
<MudDivider/>
|
||||
}
|
||||
</MudGrid>
|
||||
}
|
||||
}
|
105
TaikoWebUI/Pages/AccessCode.razor.cs
Normal file
105
TaikoWebUI/Pages/AccessCode.razor.cs
Normal file
@ -0,0 +1,105 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Linq;
|
||||
using TaikoWebUI.Pages.Dialogs;
|
||||
|
||||
namespace TaikoWebUI.Pages;
|
||||
|
||||
public partial class AccessCode
|
||||
{
|
||||
[Parameter]
|
||||
public int Baid { get; set; }
|
||||
|
||||
private string inputAccessCode = "";
|
||||
private MudForm bindAccessCodeForm = default!;
|
||||
|
||||
private User? User { get; set; } = new();
|
||||
|
||||
private DashboardResponse? response;
|
||||
|
||||
private readonly List<BreadcrumbItem> breadcrumbs = new()
|
||||
{
|
||||
new BreadcrumbItem("Users", href: "/Users"),
|
||||
};
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
await InitializeUser();
|
||||
breadcrumbs.Add(new BreadcrumbItem($"User: {Baid}", href: null, disabled: true));
|
||||
breadcrumbs.Add(new BreadcrumbItem("Access Code Management", href: $"/Users/{Baid}/AccessCode", disabled: false));
|
||||
}
|
||||
|
||||
private async Task InitializeUser()
|
||||
{
|
||||
response = await Client.GetFromJsonAsync<DashboardResponse>("api/Dashboard");
|
||||
LoginService.ResetLoggedInUser(response);
|
||||
if (LoginService.IsAdmin || !LoginService.LoginRequired)
|
||||
{
|
||||
if (response is not null)
|
||||
{
|
||||
User = response.Users.FirstOrDefault(u => u.Baid == Baid);
|
||||
}
|
||||
}
|
||||
else if (LoginService.IsLoggedIn)
|
||||
{
|
||||
User = LoginService.GetLoggedInUser();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteAccessCode(string accessCode)
|
||||
{
|
||||
var parameters = new DialogParameters<AccessCodeDeleteConfirmDialog>
|
||||
{
|
||||
{ x => x.User, User },
|
||||
{ x => x.AccessCode, accessCode }
|
||||
};
|
||||
|
||||
var dialog = DialogService.Show<AccessCodeDeleteConfirmDialog>("Delete Access Code", parameters);
|
||||
var result = await dialog.Result;
|
||||
|
||||
if (result.Canceled) return;
|
||||
|
||||
await InitializeUser();
|
||||
NavigationManager.NavigateTo(NavigationManager.Uri);
|
||||
}
|
||||
|
||||
private async Task OnBind()
|
||||
{
|
||||
if (response != null)
|
||||
{
|
||||
var result = await LoginService.BindAccessCode(inputAccessCode, Client);
|
||||
switch (result)
|
||||
{
|
||||
case 0:
|
||||
await DialogService.ShowMessageBox(
|
||||
"Error",
|
||||
(MarkupString)
|
||||
"Not logged in.<br />Please log in first and try again.",
|
||||
"Ok");
|
||||
break;
|
||||
case 1:
|
||||
await DialogService.ShowMessageBox(
|
||||
"Success",
|
||||
"New access code bound successfully.",
|
||||
"Ok");
|
||||
await InitializeUser();
|
||||
NavigationManager.NavigateTo(NavigationManager.Uri);
|
||||
break;
|
||||
case 2:
|
||||
await DialogService.ShowMessageBox(
|
||||
"Error",
|
||||
(MarkupString)
|
||||
"Bound access code upper limit reached.<br />Please delete one access code first.",
|
||||
"Ok");
|
||||
break;
|
||||
case 3:
|
||||
await DialogService.ShowMessageBox(
|
||||
"Error",
|
||||
(MarkupString)
|
||||
"Access code already bound.<br />Please delete it from the bound user first.",
|
||||
"Ok");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,186 +0,0 @@
|
||||
@inject HttpClient Client
|
||||
@inject IDialogService DialogService
|
||||
@inject LoginService LoginService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
@page "/Cards"
|
||||
|
||||
<h1>Cards</h1>
|
||||
<MudGrid Class="my-8">
|
||||
@if (response is null)
|
||||
{
|
||||
@for (uint i = 0; i < 3; i++)
|
||||
{
|
||||
<MudItem xs="12" md="6" lg="4">
|
||||
<MudCard Outlined="true">
|
||||
<MudCardContent>
|
||||
<MudSkeleton Width="30%" Height="42px;" Class="mb-5"/>
|
||||
<MudSkeleton Width="80%"/>
|
||||
<MudSkeleton Width="100%"/>
|
||||
</MudCardContent>
|
||||
<MudCardActions>
|
||||
<MudStack Row="true" Style="width:100%" Spacing="4" Justify="Justify.FlexEnd">
|
||||
<MudSkeleton Width="64px" Height="40px"/>
|
||||
<MudSkeleton Width="64px" Height="40px"/>
|
||||
</MudStack>
|
||||
</MudCardActions>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
}
|
||||
}
|
||||
else if (response.Users.Count != 0)
|
||||
{
|
||||
if (LoginService.IsAdmin || !LoginService.LoginRequired)
|
||||
{
|
||||
@foreach (var user in response.Users)
|
||||
{
|
||||
<MudItem xs="12" md="6" lg="4">
|
||||
<MudCard Outlined="true">
|
||||
<MudCardHeader>
|
||||
<CardHeaderContent>
|
||||
<MudText Typo="Typo.h6" Style="font-weight:bold">@user.Baid</MudText>
|
||||
</CardHeaderContent>
|
||||
<CardHeaderActions>
|
||||
<MudMenu Icon="@Icons.Material.Filled.MoreVert" Dense="true" AnchorOrigin="Origin.BottomLeft"
|
||||
TransformOrigin="Origin.TopLeft" Size="Size.Small">
|
||||
<MudMenuItem Icon="@Icons.Material.Filled.QrCode"
|
||||
OnClick="@(_ => ShowQrCode(user))"
|
||||
IconColor="@Color.Primary">
|
||||
Show QR Code
|
||||
</MudMenuItem>
|
||||
<MudDivider/>
|
||||
<MudMenuItem Icon="@Icons.Material.Filled.Delete"
|
||||
OnClick="@(_ => DeleteCard(user))"
|
||||
IconColor="@Color.Error">
|
||||
Delete Card
|
||||
</MudMenuItem>
|
||||
</MudMenu>
|
||||
</CardHeaderActions>
|
||||
</MudCardHeader>
|
||||
<MudCardContent>
|
||||
<MudText Style="font-weight:bold">Access Code</MudText>
|
||||
<MudText Style="font-family:monospace;overflow:hidden;overflow-x:scroll">@user.AccessCode</MudText>
|
||||
</MudCardContent>
|
||||
<MudCardActions>
|
||||
<MudStack Row="true" Style="width:100%" Spacing="4" Justify="Justify.FlexEnd">
|
||||
<MudButton Href="@($"Cards/{user.Baid}/Profile")"
|
||||
Size="Size.Small" Variant="Variant.Text" StartIcon="@Icons.Material.Filled.Edit"
|
||||
Color="Color.Primary">
|
||||
Edit Profile
|
||||
</MudButton>
|
||||
<MudMenu Size="Size.Small"
|
||||
Dense="true"
|
||||
Color="Color.Primary"
|
||||
Label="View Play Data"
|
||||
StartIcon="@Icons.Material.Filled.FeaturedPlayList"
|
||||
EndIcon="@Icons.Material.Filled.KeyboardArrowDown"
|
||||
FullWidth="true"
|
||||
AnchorOrigin="Origin.BottomCenter"
|
||||
TransformOrigin="Origin.TopCenter">
|
||||
<MudMenuItem Href="@($"Cards/{user.Baid}/HighScores")">High Scores</MudMenuItem>
|
||||
<MudMenuItem Href="@($"Cards/{user.Baid}/DaniDojo")">Dani Dojo</MudMenuItem>
|
||||
</MudMenu>
|
||||
</MudStack>
|
||||
</MudCardActions>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (!LoginService.IsLoggedIn)
|
||||
{
|
||||
<MudContainer>
|
||||
<MudGrid Justify="Justify.Center">
|
||||
<MudItem xs="4" class="mt-8">
|
||||
<MudCard>
|
||||
<MudCardContent>
|
||||
<MudForm @ref="loginForm">
|
||||
<MudText Typo="Typo.h4" Align="Align.Center">Login</MudText>
|
||||
<MudTextField @bind-value="cardNum" InputType="InputType.Text" T="string"
|
||||
FullWidth="true" Required="@true" RequiredError="Card Number is required"
|
||||
Label="Card Number"/>
|
||||
<MudTextField @bind-Value="password" InputType="InputType.Password"
|
||||
T="string" FullWidth="true" Required="@true"
|
||||
RequiredError="Password is required"
|
||||
Label="Password">
|
||||
</MudTextField>
|
||||
<MudStack Row="true">
|
||||
<MudButton OnClick="OnLogin" FullWidth="true" Class="mt-3" StartIcon="@Icons.Material.Filled.Login" Color="Color.Primary" Variant="Variant.Filled">Login</MudButton>
|
||||
@if (!LoginService.OnlyAdmin)
|
||||
{
|
||||
<MudButton Href="@("Cards/Register")" FullWidth="true" Class="mt-3" StartIcon="@Icons.Material.Filled.AddCard" Color="Color.Primary" Variant="Variant.Filled">Register</MudButton>
|
||||
}
|
||||
</MudStack>
|
||||
</MudForm>
|
||||
</MudCardContent>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
</MudContainer>
|
||||
}
|
||||
else
|
||||
{
|
||||
var user = response.Users[LoginService.GetBaid() - 1];
|
||||
<MudItem xs="12" md="6" lg="4">
|
||||
<MudCard Outlined="true">
|
||||
<MudCardHeader>
|
||||
<CardHeaderContent>
|
||||
<MudText Typo="Typo.h6" Style="font-weight:bold">@user.Baid</MudText>
|
||||
</CardHeaderContent>
|
||||
<CardHeaderActions>
|
||||
<MudMenu Icon="@Icons.Material.Filled.MoreVert" Dense="true" AnchorOrigin="Origin.BottomLeft"
|
||||
TransformOrigin="Origin.TopLeft" Size="Size.Small">
|
||||
<MudMenuItem Icon="@Icons.Material.Filled.QrCode"
|
||||
OnClick="@(_ => ShowQrCode(user))"
|
||||
IconColor="@Color.Primary">
|
||||
Show QR Code
|
||||
</MudMenuItem>
|
||||
<MudDivider/>
|
||||
<MudMenuItem Icon="@Icons.Material.Filled.Delete"
|
||||
OnClick="@(_ => DeleteCard(user))"
|
||||
IconColor="@Color.Error">
|
||||
Delete Card
|
||||
</MudMenuItem>
|
||||
</MudMenu>
|
||||
</CardHeaderActions>
|
||||
</MudCardHeader>
|
||||
<MudCardContent>
|
||||
<MudText Style="font-weight:bold">Access Code</MudText>
|
||||
<MudText Style="font-family:monospace;overflow:hidden;overflow-x:scroll">@user.AccessCode</MudText>
|
||||
</MudCardContent>
|
||||
<MudCardActions>
|
||||
<MudStack Row="true" Style="width:100%" Spacing="4" Justify="Justify.FlexEnd">
|
||||
<MudButton Href="@($"Cards/{user.Baid}/Profile")"
|
||||
Size="Size.Small" Variant="Variant.Text" StartIcon="@Icons.Material.Filled.Edit"
|
||||
Color="Color.Primary">
|
||||
Edit Profile
|
||||
</MudButton>
|
||||
<MudMenu Size="Size.Small"
|
||||
Dense="true"
|
||||
Color="Color.Primary"
|
||||
Label="View Play Data"
|
||||
StartIcon="@Icons.Material.Filled.FeaturedPlayList"
|
||||
EndIcon="@Icons.Material.Filled.KeyboardArrowDown"
|
||||
FullWidth="true"
|
||||
AnchorOrigin="Origin.BottomCenter"
|
||||
TransformOrigin="Origin.TopCenter">
|
||||
<MudMenuItem Href="@($"Cards/{user.Baid}/HighScores")">High Scores</MudMenuItem>
|
||||
<MudMenuItem Href="@($"Cards/{user.Baid}/DaniDojo")">Dani Dojo</MudMenuItem>
|
||||
</MudMenu>
|
||||
</MudStack>
|
||||
</MudCardActions>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudItem xs="12">
|
||||
<MudText Align="Align.Center" Class="my-8">
|
||||
No data.
|
||||
</MudText>
|
||||
</MudItem>
|
||||
}
|
||||
</MudGrid>
|
@ -3,9 +3,9 @@
|
||||
@inject LoginService LoginService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
@page "/Cards/ChangePassword"
|
||||
@page "/Users/ChangePassword"
|
||||
|
||||
<h1>Cards</h1>
|
||||
<h1>Users</h1>
|
||||
|
||||
@if (LoginService.OnlyAdmin || !LoginService.LoginRequired)
|
||||
{
|
||||
@ -15,14 +15,14 @@ else
|
||||
{
|
||||
<MudContainer>
|
||||
<MudGrid Justify="Justify.Center">
|
||||
<MudItem xs="4" class="mt-8">
|
||||
<MudItem xs="12" md="6" lg="4" class="mt-8">
|
||||
<MudCard>
|
||||
<MudCardContent>
|
||||
<MudForm @ref="changePasswordForm">
|
||||
<MudText Typo="Typo.h4" Align="Align.Center">Change Password</MudText>
|
||||
<MudTextField @bind-value="cardNum" InputType="InputType.Text" T="string"
|
||||
FullWidth="true" Required="@true" RequiredError="Card Number is required"
|
||||
Label="Card Number"/>
|
||||
FullWidth="true" Required="@true" RequiredError="Access code is required"
|
||||
Label="Access Code"/>
|
||||
<MudTextField @bind-Value="oldPassword" InputType="InputType.Password"
|
||||
T="string" FullWidth="true" Required="@true"
|
||||
RequiredError="Old Password is required"
|
||||
|
@ -29,14 +29,14 @@ public partial class ChangePassword
|
||||
"Error",
|
||||
"Only admin can log in.",
|
||||
"Ok");
|
||||
NavigationManager.NavigateTo("/Cards");
|
||||
NavigationManager.NavigateTo("/Users");
|
||||
break;
|
||||
case 1:
|
||||
await DialogService.ShowMessageBox(
|
||||
"Success",
|
||||
"Password changed successfully.",
|
||||
"Ok");
|
||||
NavigationManager.NavigateTo("/Cards");
|
||||
NavigationManager.NavigateTo("/Users");
|
||||
break;
|
||||
case 2:
|
||||
await DialogService.ShowMessageBox(
|
||||
|
@ -2,25 +2,18 @@
|
||||
@inject HttpClient Client
|
||||
@inject LoginService LoginService
|
||||
|
||||
@page "/Cards/{baid:int}/DaniDojo"
|
||||
@page "/Users/{baid:int}/DaniDojo"
|
||||
|
||||
<MudBreadcrumbs Items="breadcrumbs" Class="px-0"></MudBreadcrumbs>
|
||||
|
||||
<h1>Dani Dojo</h1>
|
||||
@if (LoginService.LoginRequired)
|
||||
{
|
||||
<MudText Typo="Typo.caption">Card: @LoginService.GetCardNum()</MudText>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudText Typo="Typo.caption">Card: @Baid</MudText>
|
||||
}
|
||||
<MudText Typo="Typo.caption">User: @Baid</MudText>
|
||||
|
||||
@if (LoginService.LoginRequired && (!LoginService.IsLoggedIn || (LoginService.Baid != Baid && !LoginService.IsAdmin)))
|
||||
@if (LoginService.LoginRequired && (!LoginService.IsLoggedIn || (LoginService.GetLoggedInUser().Baid != Baid && !LoginService.IsAdmin)))
|
||||
{
|
||||
<MudItem xs="12">
|
||||
<MudText Align="Align.Center" Class="my-8">
|
||||
Please log in by clicking on "cards" tab first.
|
||||
Please log in by clicking on "Users" tab first.
|
||||
</MudText>
|
||||
</MudItem>
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ public partial class DaniDojo
|
||||
|
||||
private readonly List<BreadcrumbItem> breadcrumbs = new()
|
||||
{
|
||||
new BreadcrumbItem("Cards", href: "/Cards"),
|
||||
new BreadcrumbItem("Users", href: "/Users"),
|
||||
};
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
@ -23,8 +23,8 @@ public partial class DaniDojo
|
||||
.Sort((stageData, otherStageData) => stageData.SongNumber.CompareTo(otherStageData.SongNumber)));
|
||||
bestDataMap = response.DanBestDataList.ToDictionary(data => data.DanId);
|
||||
|
||||
breadcrumbs.Add(new BreadcrumbItem($"Card: {Baid}", href: null, disabled: true));
|
||||
breadcrumbs.Add(new BreadcrumbItem("Dani Dojo", href: $"/Cards/{Baid}/DaniDojo", disabled: false));
|
||||
breadcrumbs.Add(new BreadcrumbItem($"User: {Baid}", href: null, disabled: true));
|
||||
breadcrumbs.Add(new BreadcrumbItem("Dani Dojo", href: $"/Users/{Baid}/DaniDojo", disabled: false));
|
||||
}
|
||||
|
||||
private static string GetDanClearStateString(DanClearState danClearState)
|
||||
|
@ -5,19 +5,19 @@
|
||||
<TitleContent>
|
||||
<MudText Typo="Typo.h6">
|
||||
<MudIcon Icon="@Icons.Material.Filled.DeleteForever" Class="mr-3 mb-n1"/>
|
||||
Delete card?
|
||||
Delete user?
|
||||
</MudText>
|
||||
</TitleContent>
|
||||
<DialogContent>
|
||||
<MudText>
|
||||
Do you really want to delete the card?
|
||||
All the related data will also be deleted and this process cannot be undone!
|
||||
Do you really want to delete the access code @AccessCode?
|
||||
This process cannot be undone!
|
||||
</MudText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<MudButton OnClick="Cancel">Cancel</MudButton>
|
||||
<MudButton Color="Color.Error" OnClick="DeleteCard">
|
||||
<MudText>Delete Card</MudText>
|
||||
<MudButton OnClick="Cancel">CANCEL</MudButton>
|
||||
<MudButton Color="Color.Error" OnClick="DeleteAccessCode">
|
||||
<MudText>DELETE</MudText>
|
||||
</MudButton>
|
||||
</DialogActions>
|
||||
</MudDialog>
|
@ -0,0 +1,38 @@
|
||||
namespace TaikoWebUI.Pages.Dialogs;
|
||||
|
||||
public partial class AccessCodeDeleteConfirmDialog
|
||||
{
|
||||
|
||||
[CascadingParameter]
|
||||
MudDialogInstance MudDialog { get; set; } = null!;
|
||||
|
||||
[Parameter]
|
||||
public User User { get; set; } = new();
|
||||
|
||||
[Parameter]
|
||||
public string AccessCode { get; set; } = "";
|
||||
|
||||
private void Cancel() => MudDialog.Cancel();
|
||||
|
||||
private async Task DeleteAccessCode()
|
||||
{
|
||||
if (User.AccessCodes.Count == 1)
|
||||
{
|
||||
Snackbar.Add("Cannot delete last access code!", Severity.Error);
|
||||
MudDialog.Close(DialogResult.Ok(false));
|
||||
return;
|
||||
}
|
||||
|
||||
var cardResponseMessage = await Client.DeleteAsync($"api/Cards/{AccessCode}");
|
||||
|
||||
if (!cardResponseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
Snackbar.Add("Something went wrong when deleting access code!", Severity.Error);
|
||||
MudDialog.Close(DialogResult.Ok(false));
|
||||
return;
|
||||
}
|
||||
|
||||
Snackbar.Add("Delete success!", Severity.Success);
|
||||
MudDialog.Close(DialogResult.Ok(true));
|
||||
}
|
||||
}
|
@ -57,6 +57,9 @@
|
||||
[Parameter]
|
||||
public UserSetting UserSetting { get; set; } = new();
|
||||
|
||||
[Parameter]
|
||||
public bool AllowFreeProfileEditing { get; set; }
|
||||
|
||||
private IEnumerable<Title> titles = new List<Title>();
|
||||
|
||||
private Title? selectedTitle;
|
||||
@ -67,6 +70,11 @@
|
||||
{
|
||||
base.OnInitialized();
|
||||
var titleSet = GameDataService.GetTitles();
|
||||
if (!AllowFreeProfileEditing)
|
||||
{
|
||||
var unlockedTitle = UserSetting.UnlockedTitle;
|
||||
titleSet = titleSet.Where(title => unlockedTitle.Contains((uint)title.TitleId)).ToImmutableHashSet();
|
||||
}
|
||||
titles = titleSet.ToImmutableList().Sort((title, title1) => title.TitleId.CompareTo(title1.TitleId));
|
||||
var currentTitle = new Title
|
||||
{
|
||||
@ -96,6 +104,7 @@
|
||||
if (selectedTitle is not null)
|
||||
{
|
||||
UserSetting.Title = selectedTitle.TitleName;
|
||||
UserSetting.TitlePlateId = selectedTitle.TitleRarity;
|
||||
}
|
||||
MudDialog.Close(DialogResult.Ok(true));
|
||||
}
|
||||
|
23
TaikoWebUI/Pages/Dialogs/UserDeleteConfirmDialog.razor
Normal file
23
TaikoWebUI/Pages/Dialogs/UserDeleteConfirmDialog.razor
Normal file
@ -0,0 +1,23 @@
|
||||
@inject HttpClient Client
|
||||
@inject ISnackbar Snackbar
|
||||
|
||||
<MudDialog>
|
||||
<TitleContent>
|
||||
<MudText Typo="Typo.h6">
|
||||
<MudIcon Icon="@Icons.Material.Filled.DeleteForever" Class="mr-3 mb-n1"/>
|
||||
Delete user?
|
||||
</MudText>
|
||||
</TitleContent>
|
||||
<DialogContent>
|
||||
<MudText>
|
||||
Do you really want to delete this user's data?
|
||||
All the related data will be deleted and this process cannot be undone!
|
||||
</MudText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<MudButton OnClick="Cancel">CANCEL</MudButton>
|
||||
<MudButton Color="Color.Error" OnClick="DeleteUser">
|
||||
<MudText>DELETE</MudText>
|
||||
</MudButton>
|
||||
</DialogActions>
|
||||
</MudDialog>
|
@ -1,6 +1,6 @@
|
||||
namespace TaikoWebUI.Pages.Dialogs;
|
||||
|
||||
public partial class CardDeleteConfirmDialog
|
||||
public partial class UserDeleteConfirmDialog
|
||||
{
|
||||
|
||||
[CascadingParameter]
|
||||
@ -11,17 +11,17 @@ public partial class CardDeleteConfirmDialog
|
||||
|
||||
private void Cancel() => MudDialog.Cancel();
|
||||
|
||||
private async Task DeleteCard()
|
||||
private async Task DeleteUser()
|
||||
{
|
||||
var responseMessage = await Client.DeleteAsync($"api/Cards/{User.AccessCode}");
|
||||
var responseMessage = await Client.DeleteAsync($"api/Users/{User.Baid}");
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
Snackbar.Add("Something went wrong when deleting card!", Severity.Error);
|
||||
Snackbar.Add("Something went wrong when deleting user!", Severity.Error);
|
||||
MudDialog.Close(DialogResult.Ok(false));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Snackbar.Add("Delete success!", Severity.Success);
|
||||
MudDialog.Close(DialogResult.Ok(true));
|
||||
}
|
@ -28,7 +28,7 @@
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
qrCode = "BNTTCNID" + User.AccessCode;
|
||||
qrCode = "BNTTCNID" + User.AccessCodes.First();
|
||||
}
|
||||
|
||||
private void Submit()
|
||||
|
@ -2,19 +2,13 @@
|
||||
@inject HttpClient Client
|
||||
@inject LoginService LoginService
|
||||
|
||||
@page "/Cards/{baid:int}/HighScores"
|
||||
@page "/Users/{baid:int}/HighScores"
|
||||
|
||||
<MudBreadcrumbs Items="breadcrumbs" Class="px-0"></MudBreadcrumbs>
|
||||
|
||||
<h1>High Scores</h1>
|
||||
@if (LoginService.LoginRequired)
|
||||
{
|
||||
<MudText Typo="Typo.caption">Card: @LoginService.GetCardNum()</MudText>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudText Typo="Typo.caption">Card: @Baid</MudText>
|
||||
}
|
||||
<MudText Typo="Typo.caption">User: @Baid</MudText>
|
||||
|
||||
|
||||
<MudGrid Class="my-8">
|
||||
@if (response is null)
|
||||
@ -27,11 +21,11 @@ else
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (LoginService.LoginRequired && (!LoginService.IsLoggedIn || (LoginService.Baid != Baid && !LoginService.IsAdmin)))
|
||||
@if (LoginService.LoginRequired && (!LoginService.IsLoggedIn || (LoginService.GetLoggedInUser().Baid != Baid && !LoginService.IsAdmin)))
|
||||
{
|
||||
<MudItem xs="12">
|
||||
<MudText Align="Align.Center" Class="my-8">
|
||||
Please log in by clicking on "cards" tab first.
|
||||
Please log in by clicking on "Users" tab first.
|
||||
</MudText>
|
||||
</MudItem>
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public partial class HighScores
|
||||
|
||||
private readonly List<BreadcrumbItem> breadcrumbs = new()
|
||||
{
|
||||
new BreadcrumbItem("Cards", href: "/Cards"),
|
||||
new BreadcrumbItem("Users", href: "/Users"),
|
||||
};
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
@ -43,8 +43,8 @@ public partial class HighScores
|
||||
}
|
||||
|
||||
|
||||
breadcrumbs.Add(new BreadcrumbItem($"Card: {Baid}", href: null, disabled: true));
|
||||
breadcrumbs.Add(new BreadcrumbItem("High Scores", href: $"/Cards/{Baid}/HighScores", disabled: false));
|
||||
breadcrumbs.Add(new BreadcrumbItem($"User: {Baid}", href: null, disabled: true));
|
||||
breadcrumbs.Add(new BreadcrumbItem("High Scores", href: $"/Users/{Baid}/HighScores", disabled: false));
|
||||
}
|
||||
|
||||
private async Task OnFavoriteToggled(SongBestData data)
|
||||
|
@ -1,30 +1,23 @@
|
||||
@page "/Cards/{baid:int}/Profile"
|
||||
@page "/Users/{baid:int}/Profile"
|
||||
@inject HttpClient Client
|
||||
@inject IGameDataService GameDataService
|
||||
@inject IDialogService DialogService
|
||||
@inject LoginService LoginService
|
||||
@inject IJSRuntime JS
|
||||
@inject IJSRuntime Js
|
||||
|
||||
<MudBreadcrumbs Items="breadcrumbs" Class="px-0"></MudBreadcrumbs>
|
||||
|
||||
|
||||
<h1>Profile</h1>
|
||||
@if (LoginService.LoginRequired)
|
||||
{
|
||||
<MudText Typo="Typo.caption">Card: @LoginService.GetCardNum()</MudText>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudText Typo="Typo.caption">Card: @Baid</MudText>
|
||||
}
|
||||
<MudText Typo="Typo.caption">User: @Baid</MudText>
|
||||
|
||||
@if (response is not null)
|
||||
{
|
||||
@if (LoginService.LoginRequired && (!LoginService.IsLoggedIn || (LoginService.Baid != Baid && !LoginService.IsAdmin)))
|
||||
@if (LoginService.LoginRequired && (!LoginService.IsLoggedIn || (LoginService.GetLoggedInUser().Baid != Baid && !LoginService.IsAdmin)))
|
||||
{
|
||||
<MudItem xs="12">
|
||||
<MudText Align="Align.Center" Class="my-8">
|
||||
Please log in by clicking on "cards" tab first.
|
||||
Please log in by clicking on "Users" tab first.
|
||||
</MudText>
|
||||
</MudItem>
|
||||
}
|
||||
@ -54,20 +47,30 @@ else
|
||||
|
||||
<MudGrid>
|
||||
<MudItem xs="12" md="8">
|
||||
<MudTextField TextChanged="UpdateTitle" @bind-Value="@response.Title" Label="Title" />
|
||||
<MudButton Color="Color.Primary" Class="mt-1" Size="Size.Small" OnClick="@((_)=>OpenChooseTitleDialog())">
|
||||
@if (LoginService.AllowFreeProfileEditing)
|
||||
{
|
||||
<MudTextField TextChanged="UpdateTitle" @bind-Value="@response.Title" Label="Title"/>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudTextField ReadOnly="true" @bind-Value="@response.Title" Label="Title"/>
|
||||
}
|
||||
<MudButton Color="Color.Primary" Class="mt-1" Size="Size.Small" OnClick="@((_) => OpenChooseTitleDialog())">
|
||||
Select a Title
|
||||
</MudButton>
|
||||
</MudItem>
|
||||
<MudItem xs="12" md="4">
|
||||
<MudSelect @bind-Value="@response.TitlePlateId" Label="Title Plate">
|
||||
@for (uint i = 0; i < TitlePlateStrings.Length; i++)
|
||||
{
|
||||
var index = i;
|
||||
<MudSelectItem Value="@i">@TitlePlateStrings[index]</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
</MudItem>
|
||||
@if (LoginService.AllowFreeProfileEditing)
|
||||
{
|
||||
<MudItem xs="12" md="4">
|
||||
<MudSelect @bind-Value="@response.TitlePlateId" Label="Title Plate">
|
||||
@for (uint i = 0; i < TitlePlateStrings.Length; i++)
|
||||
{
|
||||
var index = i;
|
||||
<MudSelectItem Value="@i">@TitlePlateStrings[index]</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
</MudItem>
|
||||
}
|
||||
</MudGrid>
|
||||
|
||||
<MudSelect T="Difficulty" ValueChanged=@UpdateScoreboard Value=@response.AchievementDisplayDifficulty Label="Achievement Panel Difficulty">
|
||||
@ -121,50 +124,100 @@ else
|
||||
<MudGrid>
|
||||
<MudItem xs="12">
|
||||
<MudStack Spacing="4" Class="mb-8">
|
||||
<MudSelect @bind-Value="@response.Head" Label="Head">
|
||||
@for (var i = 0; i < costumeFlagArraySizes[1]; i++)
|
||||
{
|
||||
var index = (uint)i;
|
||||
var costumeTitle = GameDataService.GetHeadTitle(index);
|
||||
<MudSelectItem Value="@index">@index - @costumeTitle</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
@if (LoginService.AllowFreeProfileEditing)
|
||||
{
|
||||
<MudSelect @bind-Value="@response.Head" Label="Head">
|
||||
@for (var i = 0; i < costumeFlagArraySizes[1]; i++)
|
||||
{
|
||||
var index = (uint)i;
|
||||
var costumeTitle = GameDataService.GetHeadTitle(index);
|
||||
<MudSelectItem Value="@index">@index - @costumeTitle</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
|
||||
<MudSelect @bind-Value="@response.Body" Label="Body">
|
||||
@for (var i = 0; i < costumeFlagArraySizes[2]; i++)
|
||||
{
|
||||
var index = (uint)i;
|
||||
var costumeTitle = GameDataService.GetBodyTitle(index);
|
||||
<MudSelectItem Value="@index">@index - @costumeTitle</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
<MudSelect @bind-Value="@response.Body" Label="Body">
|
||||
@for (var i = 0; i < costumeFlagArraySizes[2]; i++)
|
||||
{
|
||||
var index = (uint)i;
|
||||
var costumeTitle = GameDataService.GetBodyTitle(index);
|
||||
<MudSelectItem Value="@index">@index - @costumeTitle</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
|
||||
<MudSelect @bind-Value="@response.Face" Label="Face">
|
||||
@for (var i = 0; i < costumeFlagArraySizes[3]; i++)
|
||||
{
|
||||
var index = (uint)i;
|
||||
var costumeTitle = GameDataService.GetFaceTitle(index);
|
||||
<MudSelectItem Value="@index">@index - @costumeTitle</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
<MudSelect @bind-Value="@response.Face" Label="Face">
|
||||
@for (var i = 0; i < costumeFlagArraySizes[3]; i++)
|
||||
{
|
||||
var index = (uint)i;
|
||||
var costumeTitle = GameDataService.GetFaceTitle(index);
|
||||
<MudSelectItem Value="@index">@index - @costumeTitle</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
|
||||
<MudSelect @bind-Value="@response.Kigurumi" Label="Kigurumi">
|
||||
@for (var i = 0; i < costumeFlagArraySizes[0]; i++)
|
||||
{
|
||||
var index = (uint)i;
|
||||
var costumeTitle = GameDataService.GetKigurumiTitle(index);
|
||||
<MudSelectItem Value="@index">@index - @costumeTitle</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
<MudSelect @bind-Value="@response.Kigurumi" Label="Kigurumi">
|
||||
@for (var i = 0; i < costumeFlagArraySizes[0]; i++)
|
||||
{
|
||||
var index = (uint)i;
|
||||
var costumeTitle = GameDataService.GetKigurumiTitle(index);
|
||||
<MudSelectItem Value="@index">@index - @costumeTitle</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
|
||||
<MudSelect @bind-Value="@response.Puchi" Label="Puchi">
|
||||
@for (var i = 0; i < costumeFlagArraySizes[4]; i++)
|
||||
{
|
||||
var index = (uint)i;
|
||||
var costumeTitle = GameDataService.GetPuchiTitle(index);
|
||||
<MudSelectItem Value="@index">@index - @costumeTitle</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
<MudSelect @bind-Value="@response.Puchi" Label="Puchi">
|
||||
@for (var i = 0; i < costumeFlagArraySizes[4]; i++)
|
||||
{
|
||||
var index = (uint)i;
|
||||
var costumeTitle = GameDataService.GetPuchiTitle(index);
|
||||
<MudSelectItem Value="@index">@index - @costumeTitle</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudSelect @bind-Value="@response.Head" Label="Head">
|
||||
@foreach (var i in unlockedHeadCostumes)
|
||||
{
|
||||
var index = i;
|
||||
var costumeTitle = GameDataService.GetHeadTitle(index);
|
||||
<MudSelectItem Value="@index">@index - @costumeTitle</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
|
||||
<MudSelect @bind-Value="@response.Body" Label="Body">
|
||||
@foreach (var i in unlockedBodyCostumes)
|
||||
{
|
||||
var index = i;
|
||||
var costumeTitle = GameDataService.GetBodyTitle(index);
|
||||
<MudSelectItem Value="@index">@index - @costumeTitle</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
|
||||
<MudSelect @bind-Value="@response.Face" Label="Face">
|
||||
@foreach (var i in unlockedFaceCostumes)
|
||||
{
|
||||
var index = i;
|
||||
var costumeTitle = GameDataService.GetFaceTitle(index);
|
||||
<MudSelectItem Value="@index">@index - @costumeTitle</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
|
||||
<MudSelect @bind-Value="@response.Kigurumi" Label="Kigurumi">
|
||||
@foreach (var i in unlockedKigurumiCostumes)
|
||||
{
|
||||
var index = i;
|
||||
var costumeTitle = GameDataService.GetKigurumiTitle(index);
|
||||
<MudSelectItem Value="@index">@index - @costumeTitle</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
|
||||
<MudSelect @bind-Value="@response.Puchi" Label="Puchi">
|
||||
@foreach (var i in unlockedPuchiCostumes)
|
||||
{
|
||||
var index = i;
|
||||
var costumeTitle = GameDataService.GetPuchiTitle(index);
|
||||
<MudSelectItem Value="@index">@index - @costumeTitle</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
}
|
||||
</MudStack>
|
||||
|
||||
<MudStack Row="true">
|
||||
|
@ -170,7 +170,7 @@ public partial class Profile
|
||||
|
||||
private readonly List<BreadcrumbItem> breadcrumbs = new()
|
||||
{
|
||||
new BreadcrumbItem("Cards", href: "/Cards"),
|
||||
new BreadcrumbItem("Users", href: "/Users"),
|
||||
};
|
||||
|
||||
private Dictionary<Difficulty, List<SongBestData>> songBestDataMap = new();
|
||||
@ -179,6 +179,12 @@ public partial class Profile
|
||||
|
||||
private List<int> costumeFlagArraySizes = new();
|
||||
|
||||
private List<uint> unlockedHeadCostumes = new();
|
||||
private List<uint> unlockedBodyCostumes = new();
|
||||
private List<uint> unlockedFaceCostumes = new();
|
||||
private List<uint> unlockedKigurumiCostumes = new();
|
||||
private List<uint> unlockedPuchiCostumes = new();
|
||||
|
||||
private int[] scoresArray = new int[10];
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
@ -188,8 +194,17 @@ public partial class Profile
|
||||
response = await Client.GetFromJsonAsync<UserSetting>($"api/UserSettings/{Baid}");
|
||||
response.ThrowIfNull();
|
||||
|
||||
breadcrumbs.Add(new BreadcrumbItem($"Card: {Baid}", href: null, disabled: true));
|
||||
breadcrumbs.Add(new BreadcrumbItem("Profile", href: $"/Cards/{Baid}/Profile", disabled: false));
|
||||
breadcrumbs.Add(new BreadcrumbItem($"User: {Baid}", href: null, disabled: true));
|
||||
breadcrumbs.Add(new BreadcrumbItem("Profile", href: $"/Users/{Baid}/Profile", disabled: false));
|
||||
|
||||
if (response != null)
|
||||
{
|
||||
unlockedHeadCostumes = response.UnlockedHead.Distinct().OrderBy(x => x).ToList();
|
||||
unlockedBodyCostumes = response.UnlockedBody.Distinct().OrderBy(x => x).ToList();
|
||||
unlockedFaceCostumes = response.UnlockedFace.Distinct().OrderBy(x => x).ToList();
|
||||
unlockedKigurumiCostumes = response.UnlockedKigurumi.Distinct().OrderBy(x => x).ToList();
|
||||
unlockedPuchiCostumes = response.UnlockedPuchi.Distinct().OrderBy(x => x).ToList();
|
||||
}
|
||||
|
||||
costumeFlagArraySizes = GameDataService.GetCostumeFlagArraySizes();
|
||||
|
||||
@ -218,7 +233,7 @@ public partial class Profile
|
||||
{
|
||||
highestDifficulty = (Difficulty)i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
UpdateScores(response.AchievementDisplayDifficulty);
|
||||
}
|
||||
@ -305,9 +320,10 @@ public partial class Profile
|
||||
MaxWidth = MaxWidth.Medium,
|
||||
FullWidth = true
|
||||
};
|
||||
var parameters = new DialogParameters
|
||||
var parameters = new DialogParameters<ChooseTitleDialog>
|
||||
{
|
||||
["UserSetting"] = response
|
||||
{x => x.UserSetting, response},
|
||||
{x => x.AllowFreeProfileEditing, LoginService.AllowFreeProfileEditing}
|
||||
};
|
||||
var dialog = DialogService.Show<ChooseTitleDialog>("Player Titles", parameters, options);
|
||||
var result = await dialog.Result;
|
||||
|
@ -3,9 +3,9 @@
|
||||
@inject LoginService LoginService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
@page "/Cards/Register"
|
||||
@page "/Users/Register"
|
||||
|
||||
<h1>Cards</h1>
|
||||
<h1>Users</h1>
|
||||
|
||||
@if (LoginService.OnlyAdmin || !LoginService.LoginRequired)
|
||||
{
|
||||
@ -15,14 +15,19 @@ else
|
||||
{
|
||||
<MudContainer>
|
||||
<MudGrid Justify="Justify.Center">
|
||||
<MudItem xs="4" class="mt-8">
|
||||
<MudItem xs="12" md="6" lg="4" class="mt-8">
|
||||
<MudCard>
|
||||
<MudCardContent>
|
||||
<MudForm @ref="registerForm">
|
||||
<MudText Typo="Typo.h4" Align="Align.Center">Register</MudText>
|
||||
<MudTextField @bind-value="cardNum" InputType="InputType.Text" T="string"
|
||||
FullWidth="true" Required="@true" RequiredError="Card Number is required"
|
||||
Label="Card Number"/>
|
||||
<MudTextField @bind-value="accessCode" InputType="InputType.Text" T="string"
|
||||
FullWidth="true" Required="@true" RequiredError="Access Code is required"
|
||||
Label="Access Code"/>
|
||||
@if (LoginService.RegisterWithLastPlayTime)
|
||||
{
|
||||
<MudDatePicker @ref="datePicker" Label="Last Play Date" @bind-Date="date" AutoClose="true"/>
|
||||
<MudTimePicker @ref="timePicker" AmPm="true" Label="Last Play Time(5 min around credit end)" @bind-Time="time" AutoClose="true"/>
|
||||
}
|
||||
<MudTextField @bind-Value="password" InputType="InputType.Password"
|
||||
T="string" FullWidth="true" Required="@true"
|
||||
RequiredError="Password is required"
|
||||
@ -40,4 +45,4 @@ else
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
</MudContainer>
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,15 @@
|
||||
|
||||
public partial class Register
|
||||
{
|
||||
private string cardNum = "";
|
||||
private string accessCode = "";
|
||||
private string confirmPassword = "";
|
||||
private string password = "";
|
||||
private MudForm registerForm = default!;
|
||||
|
||||
private MudDatePicker datePicker = new();
|
||||
private MudTimePicker timePicker = new();
|
||||
private DateTime? date = DateTime.Today;
|
||||
private TimeSpan? time = new TimeSpan(00, 45, 00);
|
||||
|
||||
private DashboardResponse? response;
|
||||
|
||||
@ -17,9 +22,10 @@ public partial class Register
|
||||
|
||||
private async Task OnRegister()
|
||||
{
|
||||
var inputDateTime = date!.Value.Date + time!.Value;
|
||||
if (response != null)
|
||||
{
|
||||
var result = await LoginService.Register(cardNum, password, confirmPassword, response, Client);
|
||||
var result = await LoginService.Register(accessCode, inputDateTime, password, confirmPassword, response, Client);
|
||||
switch (result)
|
||||
{
|
||||
case 0:
|
||||
@ -27,14 +33,14 @@ public partial class Register
|
||||
"Error",
|
||||
"Only admin can log in.",
|
||||
"Ok");
|
||||
NavigationManager.NavigateTo("/Cards");
|
||||
NavigationManager.NavigateTo("/Users");
|
||||
break;
|
||||
case 1:
|
||||
await DialogService.ShowMessageBox(
|
||||
"Success",
|
||||
"Card registered successfully.",
|
||||
"Access code registered successfully.",
|
||||
"Ok");
|
||||
NavigationManager.NavigateTo("/Cards");
|
||||
NavigationManager.NavigateTo("/Users");
|
||||
break;
|
||||
case 2:
|
||||
await DialogService.ShowMessageBox(
|
||||
@ -46,16 +52,23 @@ public partial class Register
|
||||
await DialogService.ShowMessageBox(
|
||||
"Error",
|
||||
(MarkupString)
|
||||
"Card number not found.<br />Please play one game with this card number to register it.",
|
||||
"Access code not found.<br />Please play one game with this access code to register it.",
|
||||
"Ok");
|
||||
break;
|
||||
case 4:
|
||||
await DialogService.ShowMessageBox(
|
||||
"Error",
|
||||
(MarkupString)
|
||||
"Card is already registered, please use set password to login.",
|
||||
"Access code is already registered, please use set password to login.",
|
||||
"Ok");
|
||||
NavigationManager.NavigateTo("/Users");
|
||||
break;
|
||||
case 5:
|
||||
await DialogService.ShowMessageBox(
|
||||
"Error",
|
||||
(MarkupString)
|
||||
"Wrong last play time.<br />If you have forgotten when you last played, please play another game with this access code.",
|
||||
"Ok");
|
||||
NavigationManager.NavigateTo("/Cards");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
214
TaikoWebUI/Pages/Users.razor
Normal file
214
TaikoWebUI/Pages/Users.razor
Normal file
@ -0,0 +1,214 @@
|
||||
@inject HttpClient Client
|
||||
@inject IDialogService DialogService
|
||||
@inject LoginService LoginService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
@page "/Users"
|
||||
|
||||
<h1>Users</h1>
|
||||
<MudGrid Class="my-8">
|
||||
@if (response is null)
|
||||
{
|
||||
@for (uint i = 0; i < 3; i++)
|
||||
{
|
||||
<MudItem xs="12" md="6" lg="4">
|
||||
<MudCard Outlined="true">
|
||||
<MudCardContent>
|
||||
<MudSkeleton Width="30%" Height="42px;" Class="mb-5"/>
|
||||
<MudSkeleton Width="80%"/>
|
||||
<MudSkeleton Width="100%"/>
|
||||
</MudCardContent>
|
||||
<MudCardActions>
|
||||
<MudStack Row="true" Style="width:100%" Spacing="4" Justify="Justify.FlexEnd">
|
||||
<MudSkeleton Width="64px" Height="40px"/>
|
||||
<MudSkeleton Width="64px" Height="40px"/>
|
||||
</MudStack>
|
||||
</MudCardActions>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
}
|
||||
}
|
||||
else if (response.Users.Count != 0)
|
||||
{
|
||||
if (LoginService.IsAdmin || !LoginService.LoginRequired) // Admin mode, can see all users
|
||||
{
|
||||
@foreach (var user in response.Users)
|
||||
{
|
||||
<MudItem xs="12" md="6" lg="4">
|
||||
<MudCard Outlined="true">
|
||||
<MudCardHeader>
|
||||
<CardHeaderContent>
|
||||
<MudText Typo="Typo.h6" Style="font-weight:bold">User: @user.Baid</MudText>
|
||||
</CardHeaderContent>
|
||||
<CardHeaderActions>
|
||||
<MudMenu Icon="@Icons.Material.Filled.MoreVert" Dense="true" AnchorOrigin="Origin.BottomLeft"
|
||||
TransformOrigin="Origin.TopLeft" Size="Size.Small">
|
||||
<MudMenuItem Icon="@Icons.Material.Filled.QrCode"
|
||||
OnClick="@(_ => ShowQrCode(user))"
|
||||
IconColor="@Color.Primary">
|
||||
Show QR Code
|
||||
</MudMenuItem>
|
||||
<MudDivider/>
|
||||
<MudMenuItem Icon="@Icons.Material.Filled.FeaturedPlayList"
|
||||
Href="@($"Users/{user.Baid}/AccessCode")"
|
||||
IconColor="@Color.Primary">
|
||||
Manage Access Codes
|
||||
</MudMenuItem>
|
||||
@if (LoginService.AllowUserDelete)
|
||||
{
|
||||
<MudDivider/>
|
||||
<MudMenuItem Icon="@Icons.Material.Filled.Delete"
|
||||
OnClick="@(_ => DeleteUser(user))"
|
||||
IconColor="@Color.Error">
|
||||
Delete User
|
||||
</MudMenuItem>
|
||||
}
|
||||
</MudMenu>
|
||||
</CardHeaderActions>
|
||||
</MudCardHeader>
|
||||
<MudCardContent>
|
||||
<MudText Style="font-weight:bold">Access Code</MudText>
|
||||
<MudText Style="font-family:monospace;overflow:hidden;overflow-x:scroll">@user.AccessCodes[0]</MudText>
|
||||
@if (user.AccessCodes.Count > 1)
|
||||
{
|
||||
<MudText Style="font-family:monospace;overflow:hidden;overflow-x:scroll">... and @(user.AccessCodes.Count-1) other access code(s)</MudText>
|
||||
}
|
||||
</MudCardContent>
|
||||
<MudCardActions>
|
||||
<MudStack Row="true" Style="width:100%" Spacing="4" Justify="Justify.FlexEnd">
|
||||
<MudButton Href="@($"Users/{user.Baid}/Profile")"
|
||||
Size="Size.Small" Variant="Variant.Text" StartIcon="@Icons.Material.Filled.Edit"
|
||||
Color="Color.Primary">
|
||||
Edit Profile
|
||||
</MudButton>
|
||||
<MudMenu Size="Size.Small"
|
||||
Dense="true"
|
||||
Color="Color.Primary"
|
||||
Label="View Play Data"
|
||||
StartIcon="@Icons.Material.Filled.FeaturedPlayList"
|
||||
EndIcon="@Icons.Material.Filled.KeyboardArrowDown"
|
||||
FullWidth="true"
|
||||
AnchorOrigin="Origin.BottomCenter"
|
||||
TransformOrigin="Origin.TopCenter">
|
||||
<MudMenuItem Href="@($"Users/{user.Baid}/HighScores")">High Scores</MudMenuItem>
|
||||
<MudMenuItem Href="@($"Users/{user.Baid}/DaniDojo")">Dani Dojo</MudMenuItem>
|
||||
</MudMenu>
|
||||
</MudStack>
|
||||
</MudCardActions>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (!LoginService.IsLoggedIn) // Not logged in, show login form
|
||||
{
|
||||
<MudContainer>
|
||||
<MudGrid Justify="Justify.Center">
|
||||
<MudItem xs="12" md="6" lg="4" class="mt-8">
|
||||
<MudCard>
|
||||
<MudCardContent>
|
||||
<MudForm @ref="loginForm">
|
||||
<MudText Typo="Typo.h4" Align="Align.Center">Login</MudText>
|
||||
<MudTextField @bind-value="inputAccessCode" InputType="InputType.Text" T="string"
|
||||
FullWidth="true" Required="@true" RequiredError="Access code is required"
|
||||
Label="Access code"/>
|
||||
<MudTextField @bind-Value="inputPassword" InputType="InputType.Password"
|
||||
T="string" FullWidth="true" Required="@true"
|
||||
RequiredError="Password is required"
|
||||
Label="Password">
|
||||
</MudTextField>
|
||||
<MudStack Row="true">
|
||||
<MudButton OnClick="OnLogin" FullWidth="true" Class="mt-3" StartIcon="@Icons.Material.Filled.Login" Color="Color.Primary" Variant="Variant.Filled">Login</MudButton>
|
||||
@if (!LoginService.OnlyAdmin)
|
||||
{
|
||||
<MudButton Href="@("Users/Register")" FullWidth="true" Class="mt-3" StartIcon="@Icons.Material.Filled.AddCard" Color="Color.Primary" Variant="Variant.Filled">Register</MudButton>
|
||||
}
|
||||
</MudStack>
|
||||
</MudForm>
|
||||
</MudCardContent>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
</MudContainer>
|
||||
}
|
||||
else
|
||||
{
|
||||
var user = LoginService.GetLoggedInUser(); // Logged in, show only own user
|
||||
<MudGrid Justify="Justify.Center">
|
||||
<MudItem xs="12" md="6" lg="4">
|
||||
<MudCard Outlined="true">
|
||||
<MudCardHeader>
|
||||
<CardHeaderContent>
|
||||
<MudText Typo="Typo.h6" Style="font-weight:bold">User: @user.Baid</MudText>
|
||||
</CardHeaderContent>
|
||||
<CardHeaderActions>
|
||||
<MudMenu Icon="@Icons.Material.Filled.MoreVert" Dense="true" AnchorOrigin="Origin.BottomLeft"
|
||||
TransformOrigin="Origin.TopLeft" Size="Size.Small">
|
||||
<MudMenuItem Icon="@Icons.Material.Filled.QrCode"
|
||||
OnClick="@(_ => ShowQrCode(user))"
|
||||
IconColor="@Color.Primary">
|
||||
Show QR Code
|
||||
</MudMenuItem>
|
||||
<MudDivider/>
|
||||
<MudMenuItem Icon="@Icons.Material.Filled.FeaturedPlayList"
|
||||
Href="@($"Users/{user.Baid}/AccessCode")"
|
||||
IconColor="@Color.Primary">
|
||||
Manage Access Codes
|
||||
</MudMenuItem>
|
||||
@if (LoginService.AllowUserDelete)
|
||||
{
|
||||
<MudDivider/>
|
||||
<MudMenuItem Icon="@Icons.Material.Filled.Delete"
|
||||
OnClick="@(_ => DeleteUser(user))"
|
||||
IconColor="@Color.Error">
|
||||
Delete User
|
||||
</MudMenuItem>
|
||||
}
|
||||
</MudMenu>
|
||||
</CardHeaderActions>
|
||||
</MudCardHeader>
|
||||
<MudCardContent>
|
||||
<MudText Style="font-weight:bold">Access Code</MudText>
|
||||
<MudText Style="font-family:monospace;overflow:hidden;overflow-x:scroll">@user.AccessCodes[0]</MudText>
|
||||
@if (user.AccessCodes.Count > 1)
|
||||
{
|
||||
<MudText Style="font-family:monospace;overflow:hidden;overflow-x:scroll">... and @(user.AccessCodes.Count-1) other access code(s)</MudText>
|
||||
}
|
||||
</MudCardContent>
|
||||
<MudCardActions>
|
||||
<MudStack Row="true" Style="width:100%" Spacing="4" Justify="Justify.FlexEnd">
|
||||
<MudButton Href="@($"Users/{user.Baid}/Profile")"
|
||||
Size="Size.Small" Variant="Variant.Text" StartIcon="@Icons.Material.Filled.Edit"
|
||||
Color="Color.Primary">
|
||||
Edit Profile
|
||||
</MudButton>
|
||||
<MudMenu Size="Size.Small"
|
||||
Dense="true"
|
||||
Color="Color.Primary"
|
||||
Label="View Play Data"
|
||||
StartIcon="@Icons.Material.Filled.DataExploration"
|
||||
EndIcon="@Icons.Material.Filled.KeyboardArrowDown"
|
||||
FullWidth="true"
|
||||
AnchorOrigin="Origin.BottomCenter"
|
||||
TransformOrigin="Origin.TopCenter">
|
||||
<MudMenuItem Href="@($"Users/{user.Baid}/HighScores")">High Scores</MudMenuItem>
|
||||
<MudMenuItem Href="@($"Users/{user.Baid}/DaniDojo")">Dani Dojo</MudMenuItem>
|
||||
</MudMenu>
|
||||
</MudStack>
|
||||
</MudCardActions>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // No users in the database
|
||||
<MudItem xs="12">
|
||||
<MudText Align="Align.Center" Class="my-8">
|
||||
No data.
|
||||
</MudText>
|
||||
</MudItem>
|
||||
}
|
||||
</MudGrid>
|
@ -2,11 +2,11 @@
|
||||
|
||||
namespace TaikoWebUI.Pages;
|
||||
|
||||
public partial class Cards
|
||||
public partial class Users
|
||||
{
|
||||
private string cardNum = "";
|
||||
private string inputAccessCode = "";
|
||||
private MudForm loginForm = default!;
|
||||
private string password = "";
|
||||
private string inputPassword = "";
|
||||
private DashboardResponse? response;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
@ -15,26 +15,35 @@ public partial class Cards
|
||||
response = await Client.GetFromJsonAsync<DashboardResponse>("api/Dashboard");
|
||||
}
|
||||
|
||||
private async Task DeleteCard(User user)
|
||||
private async Task DeleteUser(User user)
|
||||
{
|
||||
if (!LoginService.AllowUserDelete)
|
||||
{
|
||||
await DialogService.ShowMessageBox(
|
||||
"Error",
|
||||
"User deletion is disabled by admin.",
|
||||
"Ok");
|
||||
return;
|
||||
}
|
||||
var parameters = new DialogParameters
|
||||
{
|
||||
["user"] = user
|
||||
};
|
||||
|
||||
var dialog = DialogService.Show<CardDeleteConfirmDialog>("Delete Card", parameters);
|
||||
var dialog = DialogService.Show<UserDeleteConfirmDialog>("Delete User", parameters);
|
||||
var result = await dialog.Result;
|
||||
|
||||
if (result.Canceled) return;
|
||||
|
||||
response = await Client.GetFromJsonAsync<DashboardResponse>("api/Dashboard");
|
||||
OnLogout();
|
||||
}
|
||||
|
||||
private async Task OnLogin()
|
||||
{
|
||||
if (response != null)
|
||||
{
|
||||
var result = LoginService.Login(cardNum, password, response);
|
||||
var result = LoginService.Login(inputAccessCode, inputPassword, response);
|
||||
switch (result)
|
||||
{
|
||||
case 0:
|
||||
@ -45,7 +54,7 @@ public partial class Cards
|
||||
await loginForm.ResetAsync();
|
||||
break;
|
||||
case 1:
|
||||
NavigationManager.NavigateTo("/Cards");
|
||||
NavigationManager.NavigateTo("/Users");
|
||||
break;
|
||||
case 2:
|
||||
await DialogService.ShowMessageBox(
|
||||
@ -57,14 +66,14 @@ public partial class Cards
|
||||
await DialogService.ShowMessageBox(
|
||||
"Error",
|
||||
(MarkupString)
|
||||
"Card number not found.<br />Please play one game with this card number to register it.",
|
||||
"Access code not found.<br />Please play one game with this access code to register it.",
|
||||
"Ok");
|
||||
break;
|
||||
case 4:
|
||||
await DialogService.ShowMessageBox(
|
||||
"Error",
|
||||
(MarkupString)
|
||||
"Card number not registered.<br />Please use register button to create a password first.",
|
||||
"Access code not registered.<br />Please use register button to create a password first.",
|
||||
"Ok");
|
||||
break;
|
||||
}
|
||||
@ -74,7 +83,7 @@ public partial class Cards
|
||||
private void OnLogout()
|
||||
{
|
||||
LoginService.Logout();
|
||||
NavigationManager.NavigateTo("/Cards");
|
||||
NavigationManager.NavigateTo("/Users");
|
||||
}
|
||||
|
||||
private Task ShowQrCode(User user)
|
@ -55,7 +55,7 @@ public class GameDataService : IGameDataService
|
||||
await Task.Run(() => InitializeBodyTitles(dict));
|
||||
await Task.Run(() => InitializePuchiTitles(dict));
|
||||
await Task.Run(() => InitializeKigurumiTitles(dict));
|
||||
await Task.Run(() => InitializeTitles(dict));
|
||||
await Task.Run(() => InitializeTitles(dict, shougouData));
|
||||
}
|
||||
|
||||
private async Task<T> GetData<T>(string dataBaseUrl, string fileBaseName) where T : notnull
|
||||
@ -143,21 +143,29 @@ public class GameDataService : IGameDataService
|
||||
private void InitializeTitleFlagArraySize(Shougous? shougouData)
|
||||
{
|
||||
shougouData.ThrowIfNull("Shouldn't happen!");
|
||||
titleFlagArraySize = (int)shougouData.ShougouEntries.Max(entry => entry.uniqueId) + 1;
|
||||
titleFlagArraySize = (int)shougouData.ShougouEntries.Max(entry => entry.UniqueId) + 1;
|
||||
}
|
||||
|
||||
private void InitializeTitles(ImmutableDictionary<string, WordListEntry> dict)
|
||||
private void InitializeTitles(ImmutableDictionary<string, WordListEntry> dict, Shougous? shougouData)
|
||||
{
|
||||
shougouData.ThrowIfNull("Shouldn't happen!");
|
||||
|
||||
var set = ImmutableHashSet.CreateBuilder<Title>();
|
||||
for (var i = 1; i < titleFlagArraySize; i++)
|
||||
{
|
||||
var key = $"syougou_{i}";
|
||||
|
||||
var titleWordlistItem = dict.GetValueOrDefault(key, new WordListEntry());
|
||||
|
||||
var titleRarity = shougouData.ShougouEntries
|
||||
.Where(entry => entry.UniqueId == i)
|
||||
.Select(entry => entry.Rarity)
|
||||
.FirstOrDefault();
|
||||
|
||||
set.Add(new Title{
|
||||
TitleName = titleWordlistItem.JapaneseText,
|
||||
TitleId = i
|
||||
TitleId = i,
|
||||
TitleRarity = titleRarity
|
||||
});
|
||||
}
|
||||
|
||||
@ -168,20 +176,20 @@ public class GameDataService : IGameDataService
|
||||
{
|
||||
donCosRewardData.ThrowIfNull("Shouldn't happen!");
|
||||
var kigurumiUniqueIdList = donCosRewardData.DonCosRewardEntries
|
||||
.Where(entry => entry.cosType == "kigurumi")
|
||||
.Select(entry => entry.uniqueId);
|
||||
.Where(entry => entry.CosType == "kigurumi")
|
||||
.Select(entry => entry.UniqueId);
|
||||
var headUniqueIdList = donCosRewardData.DonCosRewardEntries
|
||||
.Where(entry => entry.cosType == "head")
|
||||
.Select(entry => entry.uniqueId);
|
||||
.Where(entry => entry.CosType == "head")
|
||||
.Select(entry => entry.UniqueId);
|
||||
var bodyUniqueIdList = donCosRewardData.DonCosRewardEntries
|
||||
.Where(entry => entry.cosType == "body")
|
||||
.Select(entry => entry.uniqueId);
|
||||
.Where(entry => entry.CosType == "body")
|
||||
.Select(entry => entry.UniqueId);
|
||||
var faceUniqueIdList = donCosRewardData.DonCosRewardEntries
|
||||
.Where(entry => entry.cosType == "face")
|
||||
.Select(entry => entry.uniqueId);
|
||||
.Where(entry => entry.CosType == "face")
|
||||
.Select(entry => entry.UniqueId);
|
||||
var puchiUniqueIdList = donCosRewardData.DonCosRewardEntries
|
||||
.Where(entry => entry.cosType == "puchi")
|
||||
.Select(entry => entry.uniqueId);
|
||||
.Where(entry => entry.CosType == "puchi")
|
||||
.Select(entry => entry.UniqueId);
|
||||
|
||||
costumeFlagArraySizes = new List<int>
|
||||
{
|
||||
|
@ -9,34 +9,36 @@ public class LoginService
|
||||
{
|
||||
private readonly string adminPassword;
|
||||
private readonly string adminUsername;
|
||||
public bool LoginRequired { get; }
|
||||
public bool OnlyAdmin { get; }
|
||||
private readonly int boundAccessCodeUpperLimit;
|
||||
public bool RegisterWithLastPlayTime { get; }
|
||||
public bool AllowUserDelete { get; }
|
||||
public bool AllowFreeProfileEditing { get; }
|
||||
|
||||
public LoginService(IOptions<WebUiSettings> settings)
|
||||
{
|
||||
IsLoggedIn = false;
|
||||
Baid = 0;
|
||||
CardNum = 0;
|
||||
IsAdmin = false;
|
||||
var webUiSettings = settings.Value;
|
||||
adminUsername = webUiSettings.AdminUsername;
|
||||
adminPassword = webUiSettings.AdminPassword;
|
||||
LoginRequired = webUiSettings.LoginRequired;
|
||||
OnlyAdmin = webUiSettings.OnlyAdmin;
|
||||
boundAccessCodeUpperLimit = webUiSettings.BoundAccessCodeUpperLimit;
|
||||
RegisterWithLastPlayTime = webUiSettings.RegisterWithLastPlayTime;
|
||||
AllowUserDelete = webUiSettings.AllowUserDelete;
|
||||
AllowFreeProfileEditing = webUiSettings.AllowFreeProfileEditing;
|
||||
}
|
||||
|
||||
public bool IsLoggedIn { get; private set; }
|
||||
public uint Baid { get; private set; }
|
||||
private int CardNum { get; set; }
|
||||
private User LoggedInUser { get; set; } = new();
|
||||
public bool IsAdmin { get; private set; }
|
||||
|
||||
public bool LoginRequired { get; }
|
||||
public bool OnlyAdmin { get; }
|
||||
|
||||
public int Login(string inputCardNum, string inputPassword, DashboardResponse response)
|
||||
{
|
||||
if (inputCardNum == adminUsername && inputPassword == adminPassword)
|
||||
{
|
||||
CardNum = 0;
|
||||
Baid = 0;
|
||||
IsLoggedIn = true;
|
||||
IsAdmin = true;
|
||||
return 1;
|
||||
@ -44,37 +46,50 @@ public class LoginService
|
||||
|
||||
if (OnlyAdmin) return 0;
|
||||
|
||||
foreach (var user in response.Users.Where(user => user.AccessCode == inputCardNum))
|
||||
foreach (var user in response.Users.Where(user => user.AccessCodes.Contains(inputCardNum)))
|
||||
{
|
||||
if (user.Password == "") return 4;
|
||||
if (ComputeHash(inputPassword, user.Salt) != user.Password) return 2;
|
||||
CardNum = int.Parse(user.AccessCode);
|
||||
Baid = user.Baid;
|
||||
IsLoggedIn = true;
|
||||
IsAdmin = false;
|
||||
return 1;
|
||||
foreach (var userCredential in response.UserCredentials.Where(userCredential => userCredential.Baid == user.Baid))
|
||||
{
|
||||
if (userCredential.Password == "") return 4;
|
||||
if (ComputeHash(inputPassword, userCredential.Salt) != userCredential.Password) return 2;
|
||||
IsLoggedIn = true;
|
||||
LoggedInUser = user;
|
||||
IsAdmin = false;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
public async Task<int> Register(string inputCardNum, string inputPassword, string inputConfirmPassword,
|
||||
public async Task<int> Register(string inputCardNum, DateTime inputDateTime, string inputPassword, string inputConfirmPassword,
|
||||
DashboardResponse response, HttpClient client)
|
||||
{
|
||||
if (OnlyAdmin) return 0;
|
||||
foreach (var user in response.Users.Where(user => user.AccessCode == inputCardNum))
|
||||
|
||||
foreach (var user in response.Users.Where(user => user.AccessCodes.Contains(inputCardNum)))
|
||||
{
|
||||
if (user.Password != "") return 4;
|
||||
if (inputPassword != inputConfirmPassword) return 2;
|
||||
var salt = CreateSalt();
|
||||
var request = new SetPasswordRequest
|
||||
foreach (var userCredential in response.UserCredentials.Where(userCredential => userCredential.Baid == user.Baid))
|
||||
{
|
||||
AccessCode = user.AccessCode,
|
||||
Password = ComputeHash(inputPassword, salt),
|
||||
Salt = salt
|
||||
};
|
||||
var responseMessage = await client.PostAsJsonAsync("api/Cards", request);
|
||||
return responseMessage.IsSuccessStatusCode ? 1 : 3;
|
||||
if (RegisterWithLastPlayTime)
|
||||
{
|
||||
var userSettingResponse = await client.GetFromJsonAsync<UserSetting>($"api/UserSettings/{user.Baid}");
|
||||
if (userSettingResponse is null) return 3;
|
||||
var lastPlayDateTime = userSettingResponse.LastPlayDateTime;
|
||||
var diffMinutes = (inputDateTime - lastPlayDateTime).Duration().TotalMinutes;
|
||||
if (diffMinutes > 5) return 5;
|
||||
}
|
||||
if (userCredential.Password != "") return 4;
|
||||
if (inputPassword != inputConfirmPassword) return 2;
|
||||
var salt = CreateSalt();
|
||||
var request = new SetPasswordRequest
|
||||
{
|
||||
Baid = user.Baid,
|
||||
Password = ComputeHash(inputPassword, salt),
|
||||
Salt = salt
|
||||
};
|
||||
var responseMessage = await client.PostAsJsonAsync("api/Credentials", request);
|
||||
return responseMessage.IsSuccessStatusCode ? 1 : 3;
|
||||
}
|
||||
}
|
||||
|
||||
return 3;
|
||||
@ -109,18 +124,21 @@ public class LoginService
|
||||
string inputConfirmNewPassword, DashboardResponse response, HttpClient client)
|
||||
{
|
||||
if (OnlyAdmin) return 0;
|
||||
foreach (var user in response.Users.Where(user => user.AccessCode == inputCardNum))
|
||||
foreach (var user in response.Users.Where(user => user.AccessCodes.Contains(inputCardNum)))
|
||||
{
|
||||
if (user.Password != ComputeHash(inputOldPassword, user.Salt)) return 4;
|
||||
if (inputNewPassword != inputConfirmNewPassword) return 2;
|
||||
var request = new SetPasswordRequest
|
||||
foreach (var userCredential in response.UserCredentials.Where(userCredential => userCredential.Baid == user.Baid))
|
||||
{
|
||||
AccessCode = user.AccessCode,
|
||||
Password = ComputeHash(inputNewPassword, user.Salt),
|
||||
Salt = user.Salt
|
||||
};
|
||||
var responseMessage = await client.PostAsJsonAsync("api/Cards", request);
|
||||
return responseMessage.IsSuccessStatusCode ? 1 : 3;
|
||||
if (userCredential.Password != ComputeHash(inputOldPassword, userCredential.Salt)) return 4;
|
||||
if (inputNewPassword != inputConfirmNewPassword) return 2;
|
||||
var request = new SetPasswordRequest
|
||||
{
|
||||
Baid = user.Baid,
|
||||
Password = ComputeHash(inputNewPassword, userCredential.Salt),
|
||||
Salt = userCredential.Salt
|
||||
};
|
||||
var responseMessage = await client.PostAsJsonAsync("api/Credentials", request);
|
||||
return responseMessage.IsSuccessStatusCode ? 1 : 3;
|
||||
}
|
||||
}
|
||||
|
||||
return 3;
|
||||
@ -129,19 +147,34 @@ public class LoginService
|
||||
public void Logout()
|
||||
{
|
||||
IsLoggedIn = false;
|
||||
LoggedInUser = new User();
|
||||
IsAdmin = false;
|
||||
Baid = 0;
|
||||
CardNum = 0;
|
||||
}
|
||||
|
||||
public int GetBaid()
|
||||
public User GetLoggedInUser()
|
||||
{
|
||||
return checked((int)Baid);
|
||||
return LoggedInUser;
|
||||
}
|
||||
|
||||
public string GetCardNum()
|
||||
|
||||
public void ResetLoggedInUser(DashboardResponse? response)
|
||||
{
|
||||
if (IsAdmin) return "Admin";
|
||||
return CardNum == 0 ? "Not logged in" : CardNum.ToString();
|
||||
if (response is null) return;
|
||||
var baid = LoggedInUser.Baid;
|
||||
var newLoggedInUser = response.Users.FirstOrDefault(u => u.Baid == baid);
|
||||
if (newLoggedInUser is null) return;
|
||||
LoggedInUser = newLoggedInUser;
|
||||
}
|
||||
|
||||
public async Task<int> BindAccessCode(string inputAccessCode, HttpClient client)
|
||||
{
|
||||
if (!IsLoggedIn) return 0;
|
||||
if (LoggedInUser.AccessCodes.Count >= boundAccessCodeUpperLimit) return 2;
|
||||
var request = new BindAccessCodeRequest
|
||||
{
|
||||
AccessCode = inputAccessCode,
|
||||
Baid = LoggedInUser.Baid
|
||||
};
|
||||
var responseMessage = await client.PostAsJsonAsync("api/Cards", request);
|
||||
return responseMessage.IsSuccessStatusCode ? 1 : 3;
|
||||
}
|
||||
}
|
@ -6,4 +6,8 @@ public class WebUiSettings
|
||||
public string AdminUsername { get; set; } = string.Empty;
|
||||
public string AdminPassword { get; set; } = string.Empty;
|
||||
public bool OnlyAdmin { get; set; }
|
||||
public int BoundAccessCodeUpperLimit { get; set; }
|
||||
public bool RegisterWithLastPlayTime { get; set; }
|
||||
public bool AllowUserDelete { get; set; }
|
||||
public bool AllowFreeProfileEditing { get; set; }
|
||||
}
|
@ -5,8 +5,8 @@ namespace TaikoWebUI.Shared.Models;
|
||||
public class DonCosRewardEntry
|
||||
{
|
||||
[JsonPropertyName("cosType")]
|
||||
public string cosType { get; set; } = null!;
|
||||
public string CosType { get; set; } = null!;
|
||||
|
||||
[JsonPropertyName("uniqueId")]
|
||||
public uint uniqueId { get; set; }
|
||||
public uint UniqueId { get; set; }
|
||||
}
|
@ -5,5 +5,5 @@ namespace TaikoWebUI.Shared.Models;
|
||||
public class NeiroEntry
|
||||
{
|
||||
[JsonPropertyName("uniqueId")]
|
||||
public uint uniqueId { get; set; }
|
||||
public uint UniqueId { get; set; }
|
||||
}
|
@ -5,5 +5,8 @@ namespace TaikoWebUI.Shared.Models;
|
||||
public class ShougouEntry
|
||||
{
|
||||
[JsonPropertyName("uniqueId")]
|
||||
public uint uniqueId { get; set; }
|
||||
public uint UniqueId { get; set; }
|
||||
|
||||
[JsonPropertyName("rarity")]
|
||||
public uint Rarity { get; set; }
|
||||
}
|
@ -5,6 +5,8 @@ public class Title
|
||||
public int TitleId { get; set; }
|
||||
|
||||
public string TitleName { get; init; } = string.Empty;
|
||||
|
||||
public uint TitleRarity { get; init; }
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
<MudNavMenu>
|
||||
<MudNavLink Href="/" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Dashboard">Dashboard</MudNavLink>
|
||||
<MudNavLink Href="/Cards" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.CreditCard">Cards</MudNavLink>
|
||||
<MudNavLink Href="/Users" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.CreditCard">Users</MudNavLink>
|
||||
</MudNavMenu>
|
@ -46,5 +46,20 @@
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_ContentIncludedByDefault Remove="Pages\Pages\AccessCode.razor" />
|
||||
<_ContentIncludedByDefault Remove="Pages\Pages\ChangePassword.razor" />
|
||||
<_ContentIncludedByDefault Remove="Pages\Pages\DaniDojo.razor" />
|
||||
<_ContentIncludedByDefault Remove="Pages\Pages\Dashboard.razor" />
|
||||
<_ContentIncludedByDefault Remove="Pages\Pages\Dialogs\AccessCodeDeleteConfirmDialog.razor" />
|
||||
<_ContentIncludedByDefault Remove="Pages\Pages\Dialogs\ChooseTitleDialog.razor" />
|
||||
<_ContentIncludedByDefault Remove="Pages\Pages\Dialogs\UserDeleteConfirmDialog.razor" />
|
||||
<_ContentIncludedByDefault Remove="Pages\Pages\Dialogs\UserQrCodeDialog.razor" />
|
||||
<_ContentIncludedByDefault Remove="Pages\Pages\HighScores.razor" />
|
||||
<_ContentIncludedByDefault Remove="Pages\Pages\Profile.razor" />
|
||||
<_ContentIncludedByDefault Remove="Pages\Pages\Register.razor" />
|
||||
<_ContentIncludedByDefault Remove="Pages\Pages\Users.razor" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
@ -3,6 +3,10 @@
|
||||
"LoginRequired": "false",
|
||||
"AdminUserName": "admin",
|
||||
"AdminPassword": "admin",
|
||||
"OnlyAdmin": "false"
|
||||
"OnlyAdmin": "false",
|
||||
"BoundAccessCodeUpperLimit": "3",
|
||||
"RegisterWithLastPlayTime": "false",
|
||||
"AllowUserDelete": "true",
|
||||
"AllowFreeProfileEditing": "true"
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user