1
0
mirror of synced 2024-12-18 01:15:55 +01:00

initial commit

This commit is contained in:
esuo1198 2023-09-09 21:58:20 +09:00
commit 8b56689822
234 changed files with 17624 additions and 0 deletions

399
.gitignore vendored Normal file
View File

@ -0,0 +1,399 @@
/.idea/
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
*.sln.iml
TaikoLocalServer/wwwroot/data/music_attribute.bin

View File

@ -0,0 +1,121 @@
using GameDatabase.Entities;
using Microsoft.EntityFrameworkCore;
using SharedProject.Utils;
namespace GameDatabase.Context
{
public partial class TaikoDbContext : DbContext
{
private string? dbFilePath;
public TaikoDbContext()
{
}
public TaikoDbContext(DbContextOptions<TaikoDbContext> options)
: base(options)
{
}
public TaikoDbContext(string dbFilePath)
{
this.dbFilePath = dbFilePath;
}
public virtual DbSet<Card> Cards { 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!;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (optionsBuilder.IsConfigured)
{
return;
}
var path = Path.Combine(PathHelper.GetRootPath(), "taiko.db3");
if (dbFilePath is not null)
{
path = dbFilePath;
}
optionsBuilder.UseSqlite($"Data Source={path}");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Card>(entity =>
{
entity.HasKey(e => e.AccessCode);
entity.ToTable("Card");
entity.HasIndex(e => e.Baid, "IX_Card_Baid")
.IsUnique();
});
modelBuilder.Entity<SongBestDatum>(entity =>
{
entity.HasKey(e => new { e.Baid, e.SongId, e.Difficulty });
entity.HasOne(d => d.Ba)
.WithMany()
.HasPrincipalKey(p => p.Baid)
.HasForeignKey(d => d.Baid)
.OnDelete(DeleteBehavior.Cascade);
entity.Property(e => e.Difficulty)
.HasConversion<uint>();
entity.Property(e => e.BestCrown)
.HasConversion<uint>();
entity.Property(e => e.BestScoreRank)
.HasConversion<uint>();
});
modelBuilder.Entity<SongPlayDatum>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Id).ValueGeneratedOnAdd();
entity.Property(e => e.PlayTime).HasColumnType("datetime");
entity.HasOne(d => d.Ba)
.WithMany()
.HasPrincipalKey(p => p.Baid)
.HasForeignKey(d => d.Baid)
.OnDelete(DeleteBehavior.Cascade);
entity.Property(e => e.Difficulty)
.HasConversion<uint>();
entity.Property(e => e.ScoreRank)
.HasConversion<uint>();
entity.Property(e => e.Crown)
.HasConversion<uint>();
});
modelBuilder.Entity<UserDatum>(entity =>
{
entity.HasKey(e => e.Baid);
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>();
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}

View File

@ -0,0 +1,63 @@
using GameDatabase.Entities;
using Microsoft.EntityFrameworkCore;
using SharedProject.Enums;
namespace GameDatabase.Context;
public partial class TaikoDbContext
{
public virtual DbSet<DanScoreDatum> DanScoreData { get; set; } = null!;
public virtual DbSet<DanStageScoreDatum> DanStageScoreData { get; set; } = null!;
public virtual DbSet<AiScoreDatum> AiScoreData { get; set; } = null!;
public virtual DbSet<AiSectionScoreDatum> AiSectionScoreData { get; set; } = null!;
partial void OnModelCreatingPartial(ModelBuilder modelBuilder)
{
modelBuilder.Entity<DanScoreDatum>(entity =>
{
entity.HasKey(e => new { e.Baid, e.DanId });
entity.HasOne(d => d.Ba)
.WithMany()
.HasPrincipalKey(p => p.Baid)
.HasForeignKey(d => d.Baid)
.OnDelete(DeleteBehavior.Cascade);
entity.Property(e => e.ClearState).HasConversion<uint>().HasDefaultValue(DanClearState.NotClear);
});
modelBuilder.Entity<DanStageScoreDatum>(entity =>
{
entity.HasKey(e => new { e.Baid, e.DanId, e.SongNumber });
entity.HasOne(d => d.Parent)
.WithMany(p => p.DanStageScoreData)
.HasPrincipalKey(p => new { p.Baid, p.DanId })
.HasForeignKey(d => new { d.Baid, d.DanId })
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity<AiScoreDatum>(entity =>
{
entity.HasKey(e => new { e.Baid, e.SongId, e.Difficulty });
entity.HasOne(d => d.Ba)
.WithMany()
.HasPrincipalKey(p => p.Baid)
.HasForeignKey(d => d.Baid)
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity<AiSectionScoreDatum>(entity =>
{
entity.HasKey(e => new { e.Baid, e.SongId, e.Difficulty, e.SectionIndex });
entity.HasOne(d => d.Parent)
.WithMany(p => p.AiSectionScoreData)
.HasPrincipalKey(p => new { p.Baid, p.SongId, p.Difficulty })
.HasForeignKey(d => new { d.Baid, d.SongId, d.Difficulty })
.OnDelete(DeleteBehavior.Cascade);
});
}
}

View File

@ -0,0 +1,18 @@
using SharedProject.Enums;
namespace GameDatabase.Entities;
public class AiScoreDatum
{
public ulong Baid { get; set; }
public uint SongId { get; set; }
public Difficulty Difficulty { get; set; }
public bool IsWin { get; set; }
public List<AiSectionScoreDatum> AiSectionScoreData { get; set; } = new();
public virtual Card? Ba { get; set; }
}

View File

@ -0,0 +1,30 @@
using SharedProject.Enums;
namespace GameDatabase.Entities;
public class AiSectionScoreDatum
{
public ulong Baid { get; set; }
public uint SongId { get; set; }
public Difficulty Difficulty { get; set; }
public int SectionIndex { get; set; }
public CrownType Crown { get; set; }
public bool IsWin { get; set; }
public uint Score { get; set; }
public uint GoodCount { get; set; }
public uint OkCount { get; set; }
public uint MissCount { get; set; }
public uint DrumrollCount { get; set; }
public AiScoreDatum Parent { get; set; } = null!;
}

View File

@ -0,0 +1,8 @@
namespace GameDatabase.Entities
{
public partial class Card
{
public string AccessCode { get; set; } = null!;
public ulong Baid { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using SharedProject.Enums;
namespace GameDatabase.Entities;
public class DanScoreDatum
{
public ulong Baid { get; set; }
public uint DanId { get; set; }
public uint ArrivalSongCount { get; set; }
public uint SoulGaugeTotal { get; set; }
public uint ComboCountTotal { get; set; }
public DanClearState ClearState { get; set; }
public List<DanStageScoreDatum> DanStageScoreData { get; set; } = new();
public virtual Card? Ba { get; set; }
}

View File

@ -0,0 +1,28 @@
namespace GameDatabase.Entities;
public class DanStageScoreDatum
{
public ulong Baid { get; set; }
public uint DanId { get; set; }
public uint SongNumber { get; set; }
public uint PlayScore { get; set; }
public uint GoodCount { get; set; }
public uint OkCount { get; set; }
public uint BadCount { get; set; }
public uint DrumrollCount { get; set; }
public uint TotalHitCount { get; set; }
public uint ComboCount { get; set; }
public uint HighScore { get; set; }
public DanScoreDatum Parent { get; set; } = null!;
}

View File

@ -0,0 +1,17 @@
using SharedProject.Enums;
namespace GameDatabase.Entities
{
public partial class SongBestDatum
{
public ulong Baid { get; set; }
public uint SongId { get; set; }
public Difficulty Difficulty { get; set; }
public uint BestScore { get; set; }
public uint BestRate { get; set; }
public CrownType BestCrown { get; set; }
public ScoreRank BestScoreRank { get; set; }
public virtual Card? Ba { get; set; }
}
}

View File

@ -0,0 +1,29 @@
using SharedProject.Enums;
namespace GameDatabase.Entities;
public partial class SongBestDatum
{
public void UpdateBestData(CrownType crown, uint scoreRank, uint playScore, uint scoreRate)
{
if (BestCrown < crown)
{
BestCrown = crown;
}
if ((uint)BestScoreRank < scoreRank)
{
BestScoreRank = (ScoreRank)scoreRank;
}
if (BestScore < playScore)
{
BestScore = playScore;
}
if (BestRate < scoreRate)
{
BestRate = scoreRate;
}
}
}

View File

@ -0,0 +1,29 @@
using SharedProject.Enums;
namespace GameDatabase.Entities
{
public partial class SongPlayDatum
{
public long Id { get; set; }
public ulong Baid { get; set; }
public uint SongNumber { get; set; }
public uint SongId { get; set; }
public Difficulty Difficulty { get; set; }
public CrownType Crown { get; set; }
public uint Score { get; set; }
public uint ScoreRate { get; set; }
public ScoreRank ScoreRank { get; set; }
public uint GoodCount { get; set; }
public uint OkCount { get; set; }
public uint MissCount { get; set; }
public uint ComboCount { get; set; }
public uint HitCount { get; set; }
public uint DrumrollCount { get; set; }
public bool Skipped { get; set; }
public DateTime PlayTime { get; set; }
public virtual Card? Ba { get; set; }
}
}

View File

@ -0,0 +1,34 @@
using SharedProject.Enums;
namespace GameDatabase.Entities
{
public partial class UserDatum
{
public ulong Baid { get; set; }
public string MyDonName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public uint TitlePlateId { get; set; }
public string FavoriteSongsArray { get; set; } = "[]";
public string ToneFlgArray { get; set; } = "[]";
public string TitleFlgArray { get; set; } = "[]";
public string CostumeFlgArray { get; set; } = "[[],[],[],[],[]]";
public string GenericInfoFlgArray { get; set; } = "[]";
public short OptionSetting { get; set; }
public int NotesPosition { get; set; }
public bool IsVoiceOn { get; set; }
public bool IsSkipOn { get; set; }
public uint SelectedToneId { get; set; }
public DateTime LastPlayDatetime { get; set; }
public uint LastPlayMode { get; set; }
public uint ColorBody { get; set; }
public uint ColorFace { get; set; }
public uint ColorLimb { get; set; }
public string CostumeData { get; set; } = "[[],[],[],[],[]]";
public bool DisplayDan { get; set; }
public bool DisplayAchievement { get; set; }
public Difficulty AchievementDisplayDifficulty { get; set; }
public int AiWinCount { get; set; }
public virtual Card? Ba { get; set; }
}
}

View File

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SharedProject\SharedProject.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.0-rc.1.22426.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.0-rc.1.22426.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.0-rc.1.22426.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,222 @@
// <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 TaikoLocalServer.Migrations
{
[DbContext(typeof(TaikoDbContext))]
[Migration("20220825070549_Initial")]
partial class Initial
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.7.22376.2");
modelBuilder.Entity("TaikoLocalServer.Entities.Card", b =>
{
b.Property<string>("AccessCode")
.HasColumnType("TEXT");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.HasKey("AccessCode");
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
.IsUnique();
b.ToTable("Card", (string)null);
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("ComboCount")
.HasColumnType("INTEGER");
b.Property<uint>("Crown")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.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.HasKey("Id");
b.HasIndex("Baid");
b.ToTable("SongPlayData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("AchievementDisplayDifficulty")
.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<bool>("DisplayAchievement")
.HasColumnType("INTEGER");
b.Property<bool>("DisplayDan")
.HasColumnType("INTEGER");
b.Property<string>("FavoriteSongsArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("IsSkipOn")
.HasColumnType("INTEGER");
b.Property<bool>("IsVoiceOn")
.HasColumnType("INTEGER");
b.Property<DateTime>("LastPlayDatetime")
.HasColumnType("datetime");
b.Property<long>("LastPlayMode")
.HasColumnType("INTEGER");
b.Property<string>("MyDonName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("OptionSetting")
.HasColumnType("INTEGER");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("TitlePlateId")
.HasColumnType("INTEGER");
b.HasKey("Baid");
b.ToTable("UserData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,143 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace TaikoLocalServer.Migrations
{
/// <inheritdoc />
public partial class Initial : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Card",
columns: table => new
{
AccessCode = table.Column<string>(type: "TEXT", nullable: false),
Baid = table.Column<uint>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Card", x => x.AccessCode);
table.UniqueConstraint("AK_Card_Baid", x => x.Baid);
});
migrationBuilder.CreateTable(
name: "SongBestData",
columns: table => new
{
Baid = table.Column<uint>(type: "INTEGER", nullable: false),
SongId = table.Column<uint>(type: "INTEGER", nullable: false),
Difficulty = table.Column<uint>(type: "INTEGER", nullable: false),
BestScore = table.Column<uint>(type: "INTEGER", nullable: false),
BestRate = table.Column<uint>(type: "INTEGER", nullable: false),
BestCrown = table.Column<uint>(type: "INTEGER", nullable: false),
BestScoreRank = table.Column<uint>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_SongBestData", x => new { x.Baid, x.SongId, x.Difficulty });
table.ForeignKey(
name: "FK_SongBestData_Card_Baid",
column: x => x.Baid,
principalTable: "Card",
principalColumn: "Baid",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "SongPlayData",
columns: table => new
{
Id = table.Column<long>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Baid = table.Column<uint>(type: "INTEGER", nullable: false),
SongId = table.Column<uint>(type: "INTEGER", nullable: false),
Difficulty = table.Column<uint>(type: "INTEGER", nullable: false),
Crown = table.Column<uint>(type: "INTEGER", nullable: false),
Score = table.Column<uint>(type: "INTEGER", nullable: false),
ScoreRate = table.Column<uint>(type: "INTEGER", nullable: false),
ScoreRank = table.Column<uint>(type: "INTEGER", nullable: false),
GoodCount = table.Column<uint>(type: "INTEGER", nullable: false),
OkCount = table.Column<uint>(type: "INTEGER", nullable: false),
MissCount = table.Column<uint>(type: "INTEGER", nullable: false),
ComboCount = table.Column<uint>(type: "INTEGER", nullable: false),
HitCount = table.Column<uint>(type: "INTEGER", nullable: false),
Skipped = table.Column<bool>(type: "INTEGER", nullable: false),
PlayTime = table.Column<DateTime>(type: "datetime", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_SongPlayData", x => x.Id);
table.ForeignKey(
name: "FK_SongPlayData_Card_Baid",
column: x => x.Baid,
principalTable: "Card",
principalColumn: "Baid",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "UserData",
columns: table => new
{
Baid = table.Column<uint>(type: "INTEGER", nullable: false),
MyDonName = table.Column<string>(type: "TEXT", nullable: false),
Title = table.Column<string>(type: "TEXT", nullable: false),
TitlePlateId = table.Column<uint>(type: "INTEGER", nullable: false),
FavoriteSongsArray = table.Column<string>(type: "TEXT", nullable: false),
OptionSetting = table.Column<int>(type: "INTEGER", nullable: false),
IsVoiceOn = table.Column<bool>(type: "INTEGER", nullable: false),
IsSkipOn = table.Column<bool>(type: "INTEGER", nullable: false),
LastPlayDatetime = table.Column<DateTime>(type: "datetime", nullable: false),
LastPlayMode = table.Column<long>(type: "INTEGER", nullable: false),
ColorBody = table.Column<uint>(type: "INTEGER", nullable: false),
ColorFace = table.Column<uint>(type: "INTEGER", nullable: false),
ColorLimb = table.Column<uint>(type: "INTEGER", nullable: false),
CostumeData = table.Column<string>(type: "TEXT", nullable: false),
DisplayDan = table.Column<bool>(type: "INTEGER", nullable: false),
DisplayAchievement = table.Column<bool>(type: "INTEGER", nullable: false),
AchievementDisplayDifficulty = table.Column<uint>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_UserData", x => x.Baid);
table.ForeignKey(
name: "FK_UserData_Card_Baid",
column: x => x.Baid,
principalTable: "Card",
principalColumn: "Baid",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Card_Baid",
table: "Card",
column: "Baid",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_SongPlayData_Baid",
table: "SongPlayData",
column: "Baid");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "SongBestData");
migrationBuilder.DropTable(
name: "SongPlayData");
migrationBuilder.DropTable(
name: "UserData");
migrationBuilder.DropTable(
name: "Card");
}
}
}

View File

@ -0,0 +1,225 @@
// <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 TaikoLocalServer.Migrations
{
[DbContext(typeof(TaikoDbContext))]
[Migration("20220827163841_FirstMigration")]
partial class FirstMigration
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.7.22376.2");
modelBuilder.Entity("TaikoLocalServer.Entities.Card", b =>
{
b.Property<string>("AccessCode")
.HasColumnType("TEXT");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.HasKey("AccessCode");
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
.IsUnique();
b.ToTable("Card", (string)null);
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("ComboCount")
.HasColumnType("INTEGER");
b.Property<uint>("Crown")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.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("TaikoLocalServer.Entities.UserDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("AchievementDisplayDifficulty")
.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<bool>("DisplayAchievement")
.HasColumnType("INTEGER");
b.Property<bool>("DisplayDan")
.HasColumnType("INTEGER");
b.Property<string>("FavoriteSongsArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("IsSkipOn")
.HasColumnType("INTEGER");
b.Property<bool>("IsVoiceOn")
.HasColumnType("INTEGER");
b.Property<DateTime>("LastPlayDatetime")
.HasColumnType("datetime");
b.Property<long>("LastPlayMode")
.HasColumnType("INTEGER");
b.Property<string>("MyDonName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("OptionSetting")
.HasColumnType("INTEGER");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("TitlePlateId")
.HasColumnType("INTEGER");
b.HasKey("Baid");
b.ToTable("UserData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace TaikoLocalServer.Migrations
{
/// <inheritdoc />
public partial class FirstMigration : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<uint>(
name: "SongNumber",
table: "SongPlayData",
type: "INTEGER",
nullable: false,
defaultValue: 0u);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "SongNumber",
table: "SongPlayData");
}
}
}

View File

@ -0,0 +1,322 @@
// <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 TaikoLocalServer.Migrations
{
[DbContext(typeof(TaikoDbContext))]
[Migration("20220828101620_AddDanDbTest")]
partial class AddDanDbTest
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.7.22376.2");
modelBuilder.Entity("TaikoLocalServer.Entities.Card", b =>
{
b.Property<string>("AccessCode")
.HasColumnType("TEXT");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.HasKey("AccessCode");
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
.IsUnique();
b.ToTable("Card", (string)null);
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
b.Property<uint>("ArrivalSongCount")
.HasColumnType("INTEGER");
b.Property<uint>("ComboCountTotal")
.HasColumnType("INTEGER");
b.Property<uint>("SoulGaugeTotal")
.HasColumnType("INTEGER");
b.HasKey("Baid", "DanId");
b.ToTable("DanScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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", "SongNumber");
b.ToTable("DanStageScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("ComboCount")
.HasColumnType("INTEGER");
b.Property<uint>("Crown")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.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("TaikoLocalServer.Entities.UserDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("AchievementDisplayDifficulty")
.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<bool>("DisplayAchievement")
.HasColumnType("INTEGER");
b.Property<bool>("DisplayDan")
.HasColumnType("INTEGER");
b.Property<string>("FavoriteSongsArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("IsSkipOn")
.HasColumnType("INTEGER");
b.Property<bool>("IsVoiceOn")
.HasColumnType("INTEGER");
b.Property<DateTime>("LastPlayDatetime")
.HasColumnType("datetime");
b.Property<long>("LastPlayMode")
.HasColumnType("INTEGER");
b.Property<string>("MyDonName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("OptionSetting")
.HasColumnType("INTEGER");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("TitlePlateId")
.HasColumnType("INTEGER");
b.HasKey("Baid");
b.ToTable("UserData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.DanScoreDatum", "Parent")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("TaikoLocalServer.Entities.DanScoreDatum", null)
.WithMany("DanStageScoreData")
.HasForeignKey("Baid", "DanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Navigation("DanStageScoreData");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,79 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace TaikoLocalServer.Migrations
{
/// <inheritdoc />
public partial class AddDanDbTest : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "DanScoreData",
columns: table => new
{
Baid = table.Column<uint>(type: "INTEGER", nullable: false),
DanId = table.Column<uint>(type: "INTEGER", nullable: false),
ArrivalSongCount = table.Column<uint>(type: "INTEGER", nullable: false),
SoulGaugeTotal = table.Column<uint>(type: "INTEGER", nullable: false),
ComboCountTotal = table.Column<uint>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_DanScoreData", x => new { x.Baid, x.DanId });
table.UniqueConstraint("AK_DanScoreData_Baid", x => x.Baid);
table.ForeignKey(
name: "FK_DanScoreData_Card_Baid",
column: x => x.Baid,
principalTable: "Card",
principalColumn: "Baid",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "DanStageScoreData",
columns: table => new
{
Baid = table.Column<uint>(type: "INTEGER", nullable: false),
DanId = table.Column<uint>(type: "INTEGER", nullable: false),
SongNumber = table.Column<uint>(type: "INTEGER", nullable: false),
PlayScore = table.Column<uint>(type: "INTEGER", nullable: false),
GoodCount = table.Column<uint>(type: "INTEGER", nullable: false),
OkCount = table.Column<uint>(type: "INTEGER", nullable: false),
BadCount = table.Column<uint>(type: "INTEGER", nullable: false),
DrumrollCount = table.Column<uint>(type: "INTEGER", nullable: false),
TotalHitCount = table.Column<uint>(type: "INTEGER", nullable: false),
ComboCount = table.Column<uint>(type: "INTEGER", nullable: false),
HighScore = table.Column<uint>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_DanStageScoreData", x => new { x.Baid, x.DanId, x.SongNumber });
table.ForeignKey(
name: "FK_DanStageScoreData_DanScoreData_Baid",
column: x => x.Baid,
principalTable: "DanScoreData",
principalColumn: "Baid",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_DanStageScoreData_DanScoreData_Baid_DanId",
columns: x => new { x.Baid, x.DanId },
principalTable: "DanScoreData",
principalColumns: new[] { "Baid", "DanId" },
onDelete: ReferentialAction.Cascade);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "DanStageScoreData");
migrationBuilder.DropTable(
name: "DanScoreData");
}
}
}

View File

@ -0,0 +1,327 @@
// <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 TaikoLocalServer.Migrations
{
[DbContext(typeof(TaikoDbContext))]
[Migration("20220828171353_AddClearState")]
partial class AddClearState
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.7.22376.2");
modelBuilder.Entity("TaikoLocalServer.Entities.Card", b =>
{
b.Property<string>("AccessCode")
.HasColumnType("TEXT");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.HasKey("AccessCode");
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
.IsUnique();
b.ToTable("Card", (string)null);
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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");
b.ToTable("DanScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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", "SongNumber");
b.ToTable("DanStageScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("ComboCount")
.HasColumnType("INTEGER");
b.Property<uint>("Crown")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.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("TaikoLocalServer.Entities.UserDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("AchievementDisplayDifficulty")
.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<bool>("DisplayAchievement")
.HasColumnType("INTEGER");
b.Property<bool>("DisplayDan")
.HasColumnType("INTEGER");
b.Property<string>("FavoriteSongsArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("IsSkipOn")
.HasColumnType("INTEGER");
b.Property<bool>("IsVoiceOn")
.HasColumnType("INTEGER");
b.Property<DateTime>("LastPlayDatetime")
.HasColumnType("datetime");
b.Property<long>("LastPlayMode")
.HasColumnType("INTEGER");
b.Property<string>("MyDonName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("OptionSetting")
.HasColumnType("INTEGER");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("TitlePlateId")
.HasColumnType("INTEGER");
b.HasKey("Baid");
b.ToTable("UserData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.DanScoreDatum", "Parent")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("TaikoLocalServer.Entities.DanScoreDatum", null)
.WithMany("DanStageScoreData")
.HasForeignKey("Baid", "DanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Navigation("DanStageScoreData");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace TaikoLocalServer.Migrations
{
/// <inheritdoc />
public partial class AddClearState : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<uint>(
name: "ClearState",
table: "DanScoreData",
type: "INTEGER",
nullable: false,
defaultValue: 0u);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ClearState",
table: "DanScoreData");
}
}
}

View File

@ -0,0 +1,332 @@
// <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 TaikoLocalServer.Migrations
{
[DbContext(typeof(TaikoDbContext))]
[Migration("20220829101052_AdjustDanDb")]
partial class AdjustDanDb
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.7.22376.2");
modelBuilder.Entity("TaikoLocalServer.Entities.Card", b =>
{
b.Property<string>("AccessCode")
.HasColumnType("TEXT");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.HasKey("AccessCode");
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
.IsUnique();
b.ToTable("Card", (string)null);
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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");
b.ToTable("DanScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
b.Property<uint>("SongNumber")
.HasColumnType("INTEGER");
b.Property<uint>("BadCount")
.HasColumnType("INTEGER");
b.Property<uint>("ComboCount")
.HasColumnType("INTEGER");
b.Property<uint?>("DanScoreDatumBaid")
.HasColumnType("INTEGER");
b.Property<uint?>("DanScoreDatumDanId")
.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", "SongNumber");
b.HasIndex("DanScoreDatumBaid", "DanScoreDatumDanId");
b.ToTable("DanStageScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("ComboCount")
.HasColumnType("INTEGER");
b.Property<uint>("Crown")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.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("TaikoLocalServer.Entities.UserDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("AchievementDisplayDifficulty")
.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<bool>("DisplayAchievement")
.HasColumnType("INTEGER");
b.Property<bool>("DisplayDan")
.HasColumnType("INTEGER");
b.Property<string>("FavoriteSongsArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("IsSkipOn")
.HasColumnType("INTEGER");
b.Property<bool>("IsVoiceOn")
.HasColumnType("INTEGER");
b.Property<DateTime>("LastPlayDatetime")
.HasColumnType("datetime");
b.Property<long>("LastPlayMode")
.HasColumnType("INTEGER");
b.Property<string>("MyDonName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("OptionSetting")
.HasColumnType("INTEGER");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("TitlePlateId")
.HasColumnType("INTEGER");
b.HasKey("Baid");
b.ToTable("UserData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.DanScoreDatum", "Parent")
.WithMany()
.HasForeignKey("Baid", "DanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("TaikoLocalServer.Entities.DanScoreDatum", null)
.WithMany("DanStageScoreData")
.HasForeignKey("DanScoreDatumBaid", "DanScoreDatumDanId");
b.Navigation("Parent");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Navigation("DanStageScoreData");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,79 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace TaikoLocalServer.Migrations
{
/// <inheritdoc />
public partial class AdjustDanDb : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_DanStageScoreData_DanScoreData_Baid",
table: "DanStageScoreData");
migrationBuilder.DropUniqueConstraint(
name: "AK_DanScoreData_Baid",
table: "DanScoreData");
migrationBuilder.AddColumn<uint>(
name: "DanScoreDatumBaid",
table: "DanStageScoreData",
type: "INTEGER",
nullable: true);
migrationBuilder.AddColumn<uint>(
name: "DanScoreDatumDanId",
table: "DanStageScoreData",
type: "INTEGER",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_DanStageScoreData_DanScoreDatumBaid_DanScoreDatumDanId",
table: "DanStageScoreData",
columns: new[] { "DanScoreDatumBaid", "DanScoreDatumDanId" });
migrationBuilder.AddForeignKey(
name: "FK_DanStageScoreData_DanScoreData_DanScoreDatumBaid_DanScoreDatumDanId",
table: "DanStageScoreData",
columns: new[] { "DanScoreDatumBaid", "DanScoreDatumDanId" },
principalTable: "DanScoreData",
principalColumns: new[] { "Baid", "DanId" });
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_DanStageScoreData_DanScoreData_DanScoreDatumBaid_DanScoreDatumDanId",
table: "DanStageScoreData");
migrationBuilder.DropIndex(
name: "IX_DanStageScoreData_DanScoreDatumBaid_DanScoreDatumDanId",
table: "DanStageScoreData");
migrationBuilder.DropColumn(
name: "DanScoreDatumBaid",
table: "DanStageScoreData");
migrationBuilder.DropColumn(
name: "DanScoreDatumDanId",
table: "DanStageScoreData");
migrationBuilder.AddUniqueConstraint(
name: "AK_DanScoreData_Baid",
table: "DanScoreData",
column: "Baid");
migrationBuilder.AddForeignKey(
name: "FK_DanStageScoreData_DanScoreData_Baid",
table: "DanStageScoreData",
column: "Baid",
principalTable: "DanScoreData",
principalColumn: "Baid",
onDelete: ReferentialAction.Cascade);
}
}
}

View File

@ -0,0 +1,320 @@
// <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 TaikoLocalServer.Migrations
{
[DbContext(typeof(TaikoDbContext))]
[Migration("20220829124927_FixNavigation")]
partial class FixNavigation
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.7.22376.2");
modelBuilder.Entity("TaikoLocalServer.Entities.Card", b =>
{
b.Property<string>("AccessCode")
.HasColumnType("TEXT");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.HasKey("AccessCode");
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
.IsUnique();
b.ToTable("Card", (string)null);
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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");
b.ToTable("DanScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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", "SongNumber");
b.ToTable("DanStageScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("ComboCount")
.HasColumnType("INTEGER");
b.Property<uint>("Crown")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.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("TaikoLocalServer.Entities.UserDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("AchievementDisplayDifficulty")
.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<bool>("DisplayAchievement")
.HasColumnType("INTEGER");
b.Property<bool>("DisplayDan")
.HasColumnType("INTEGER");
b.Property<string>("FavoriteSongsArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("IsSkipOn")
.HasColumnType("INTEGER");
b.Property<bool>("IsVoiceOn")
.HasColumnType("INTEGER");
b.Property<DateTime>("LastPlayDatetime")
.HasColumnType("datetime");
b.Property<long>("LastPlayMode")
.HasColumnType("INTEGER");
b.Property<string>("MyDonName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("OptionSetting")
.HasColumnType("INTEGER");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("TitlePlateId")
.HasColumnType("INTEGER");
b.HasKey("Baid");
b.ToTable("UserData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.DanScoreDatum", "Parent")
.WithMany("DanStageScoreData")
.HasForeignKey("Baid", "DanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Navigation("DanStageScoreData");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,58 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace TaikoLocalServer.Migrations
{
/// <inheritdoc />
public partial class FixNavigation : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_DanStageScoreData_DanScoreData_DanScoreDatumBaid_DanScoreDatumDanId",
table: "DanStageScoreData");
migrationBuilder.DropIndex(
name: "IX_DanStageScoreData_DanScoreDatumBaid_DanScoreDatumDanId",
table: "DanStageScoreData");
migrationBuilder.DropColumn(
name: "DanScoreDatumBaid",
table: "DanStageScoreData");
migrationBuilder.DropColumn(
name: "DanScoreDatumDanId",
table: "DanStageScoreData");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<uint>(
name: "DanScoreDatumBaid",
table: "DanStageScoreData",
type: "INTEGER",
nullable: true);
migrationBuilder.AddColumn<uint>(
name: "DanScoreDatumDanId",
table: "DanStageScoreData",
type: "INTEGER",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_DanStageScoreData_DanScoreDatumBaid_DanScoreDatumDanId",
table: "DanStageScoreData",
columns: new[] { "DanScoreDatumBaid", "DanScoreDatumDanId" });
migrationBuilder.AddForeignKey(
name: "FK_DanStageScoreData_DanScoreData_DanScoreDatumBaid_DanScoreDatumDanId",
table: "DanStageScoreData",
columns: new[] { "DanScoreDatumBaid", "DanScoreDatumDanId" },
principalTable: "DanScoreData",
principalColumns: new[] { "Baid", "DanId" });
}
}
}

View File

@ -0,0 +1,326 @@
// <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 TaikoLocalServer.Migrations
{
[DbContext(typeof(TaikoDbContext))]
[Migration("20220905132703_AddMoreOptions")]
partial class AddMoreOptions
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.7.22376.2");
modelBuilder.Entity("TaikoLocalServer.Entities.Card", b =>
{
b.Property<string>("AccessCode")
.HasColumnType("TEXT");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.HasKey("AccessCode");
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
.IsUnique();
b.ToTable("Card", (string)null);
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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");
b.ToTable("DanScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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", "SongNumber");
b.ToTable("DanStageScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("ComboCount")
.HasColumnType("INTEGER");
b.Property<uint>("Crown")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.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("TaikoLocalServer.Entities.UserDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("AchievementDisplayDifficulty")
.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<bool>("DisplayAchievement")
.HasColumnType("INTEGER");
b.Property<bool>("DisplayDan")
.HasColumnType("INTEGER");
b.Property<string>("FavoriteSongsArray")
.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<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<uint>("TitlePlateId")
.HasColumnType("INTEGER");
b.HasKey("Baid");
b.ToTable("UserData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.DanScoreDatum", "Parent")
.WithMany("DanStageScoreData")
.HasForeignKey("Baid", "DanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Navigation("DanStageScoreData");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,40 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace TaikoLocalServer.Migrations
{
/// <inheritdoc />
public partial class AddMoreOptions : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "NotesPosition",
table: "UserData",
type: "INTEGER",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<uint>(
name: "SelectedToneId",
table: "UserData",
type: "INTEGER",
nullable: false,
defaultValue: 0u);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "NotesPosition",
table: "UserData");
migrationBuilder.DropColumn(
name: "SelectedToneId",
table: "UserData");
}
}
}

View File

@ -0,0 +1,329 @@
// <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 TaikoLocalServer.Migrations
{
[DbContext(typeof(TaikoDbContext))]
[Migration("20220910055624_AddDrumrollCount")]
partial class AddDrumrollCount
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.7.22376.2");
modelBuilder.Entity("TaikoLocalServer.Entities.Card", b =>
{
b.Property<string>("AccessCode")
.HasColumnType("TEXT");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.HasKey("AccessCode");
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
.IsUnique();
b.ToTable("Card", (string)null);
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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");
b.ToTable("DanScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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", "SongNumber");
b.ToTable("DanStageScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("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("TaikoLocalServer.Entities.UserDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("AchievementDisplayDifficulty")
.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<bool>("DisplayAchievement")
.HasColumnType("INTEGER");
b.Property<bool>("DisplayDan")
.HasColumnType("INTEGER");
b.Property<string>("FavoriteSongsArray")
.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<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<uint>("TitlePlateId")
.HasColumnType("INTEGER");
b.HasKey("Baid");
b.ToTable("UserData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.DanScoreDatum", "Parent")
.WithMany("DanStageScoreData")
.HasForeignKey("Baid", "DanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Navigation("DanStageScoreData");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace TaikoLocalServer.Migrations
{
/// <inheritdoc />
public partial class AddDrumrollCount : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<uint>(
name: "DrumrollCount",
table: "SongPlayData",
type: "INTEGER",
nullable: false,
defaultValue: 0u);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "DrumrollCount",
table: "SongPlayData");
}
}
}

View File

@ -0,0 +1,341 @@
// <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 TaikoLocalServer.Migrations
{
[DbContext(typeof(TaikoDbContext))]
[Migration("20220914054039_AddRewardFlgs")]
partial class AddRewardFlgs
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.7.22376.2");
modelBuilder.Entity("TaikoLocalServer.Entities.Card", b =>
{
b.Property<string>("AccessCode")
.HasColumnType("TEXT");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.HasKey("AccessCode");
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
.IsUnique();
b.ToTable("Card", (string)null);
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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");
b.ToTable("DanScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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", "SongNumber");
b.ToTable("DanStageScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("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("TaikoLocalServer.Entities.UserDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("AchievementDisplayDifficulty")
.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<bool>("DisplayAchievement")
.HasColumnType("INTEGER");
b.Property<bool>("DisplayDan")
.HasColumnType("INTEGER");
b.Property<string>("FavoriteSongsArray")
.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<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>("ToneFlgArray")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Baid");
b.ToTable("UserData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.DanScoreDatum", "Parent")
.WithMany("DanStageScoreData")
.HasForeignKey("Baid", "DanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Navigation("DanStageScoreData");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,51 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace TaikoLocalServer.Migrations
{
/// <inheritdoc />
public partial class AddRewardFlgs : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "CostumeFlgArray",
table: "UserData",
type: "TEXT",
nullable: false,
defaultValue: "[[],[],[],[],[]]");
migrationBuilder.AddColumn<string>(
name: "TitleFlgArray",
table: "UserData",
type: "TEXT",
nullable: false,
defaultValue: "[]");
migrationBuilder.AddColumn<string>(
name: "ToneFlgArray",
table: "UserData",
type: "TEXT",
nullable: false,
defaultValue: "[]");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "CostumeFlgArray",
table: "UserData");
migrationBuilder.DropColumn(
name: "TitleFlgArray",
table: "UserData");
migrationBuilder.DropColumn(
name: "ToneFlgArray",
table: "UserData");
}
}
}

View File

@ -0,0 +1,345 @@
// <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 TaikoLocalServer.Migrations
{
[DbContext(typeof(TaikoDbContext))]
[Migration("20220916121143_AddGenericInfoFlg")]
partial class AddGenericInfoFlg
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.7.22376.2");
modelBuilder.Entity("TaikoLocalServer.Entities.Card", b =>
{
b.Property<string>("AccessCode")
.HasColumnType("TEXT");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.HasKey("AccessCode");
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
.IsUnique();
b.ToTable("Card", (string)null);
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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");
b.ToTable("DanScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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", "SongNumber");
b.ToTable("DanStageScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("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("TaikoLocalServer.Entities.UserDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("AchievementDisplayDifficulty")
.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<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<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>("ToneFlgArray")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Baid");
b.ToTable("UserData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.DanScoreDatum", "Parent")
.WithMany("DanStageScoreData")
.HasForeignKey("Baid", "DanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Navigation("DanStageScoreData");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace TaikoLocalServer.Migrations
{
/// <inheritdoc />
public partial class AddGenericInfoFlg : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "GenericInfoFlgArray",
table: "UserData",
type: "TEXT",
nullable: false,
defaultValue: "[]");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "GenericInfoFlgArray",
table: "UserData");
}
}
}

View File

@ -0,0 +1,432 @@
// <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 TaikoLocalServer.Migrations
{
[DbContext(typeof(TaikoDbContext))]
[Migration("20220917180457_AddAiBattle")]
partial class AddAiBattle
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.7.22376.2");
modelBuilder.Entity("TaikoLocalServer.Entities.AiScoreDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.AiSectionScoreDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.Card", b =>
{
b.Property<string>("AccessCode")
.HasColumnType("TEXT");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.HasKey("AccessCode");
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
.IsUnique();
b.ToTable("Card", (string)null);
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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");
b.ToTable("DanScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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", "SongNumber");
b.ToTable("DanStageScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("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("TaikoLocalServer.Entities.UserDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("AchievementDisplayDifficulty")
.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<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<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>("ToneFlgArray")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Baid");
b.ToTable("UserData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.AiScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.AiSectionScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.AiScoreDatum", "Parent")
.WithMany("AiSectionScoreData")
.HasForeignKey("Baid", "SongId", "Difficulty")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.DanScoreDatum", "Parent")
.WithMany("DanStageScoreData")
.HasForeignKey("Baid", "DanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.AiScoreDatum", b =>
{
b.Navigation("AiSectionScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Navigation("DanStageScoreData");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,71 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace TaikoLocalServer.Migrations
{
/// <inheritdoc />
public partial class AddAiBattle : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AiScoreData",
columns: table => new
{
Baid = table.Column<uint>(type: "INTEGER", nullable: false),
SongId = table.Column<uint>(type: "INTEGER", nullable: false),
Difficulty = table.Column<uint>(type: "INTEGER", nullable: false),
IsWin = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AiScoreData", x => new { x.Baid, x.SongId, x.Difficulty });
table.ForeignKey(
name: "FK_AiScoreData_Card_Baid",
column: x => x.Baid,
principalTable: "Card",
principalColumn: "Baid",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AiSectionScoreData",
columns: table => new
{
Baid = table.Column<uint>(type: "INTEGER", nullable: false),
SongId = table.Column<uint>(type: "INTEGER", nullable: false),
Difficulty = table.Column<uint>(type: "INTEGER", nullable: false),
SectionIndex = table.Column<int>(type: "INTEGER", nullable: false),
Crown = table.Column<int>(type: "INTEGER", nullable: false),
IsWin = table.Column<bool>(type: "INTEGER", nullable: false),
Score = table.Column<uint>(type: "INTEGER", nullable: false),
GoodCount = table.Column<uint>(type: "INTEGER", nullable: false),
OkCount = table.Column<uint>(type: "INTEGER", nullable: false),
MissCount = table.Column<uint>(type: "INTEGER", nullable: false),
DrumrollCount = table.Column<uint>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AiSectionScoreData", x => new { x.Baid, x.SongId, x.Difficulty, x.SectionIndex });
table.ForeignKey(
name: "FK_AiSectionScoreData_AiScoreData_Baid_SongId_Difficulty",
columns: x => new { x.Baid, x.SongId, x.Difficulty },
principalTable: "AiScoreData",
principalColumns: new[] { "Baid", "SongId", "Difficulty" },
onDelete: ReferentialAction.Cascade);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AiSectionScoreData");
migrationBuilder.DropTable(
name: "AiScoreData");
}
}
}

View File

@ -0,0 +1,435 @@
// <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 TaikoLocalServer.Migrations
{
[DbContext(typeof(TaikoDbContext))]
[Migration("20220919022643_AddWinCountToUserdata")]
partial class AddWinCountToUserdata
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.7.22376.2");
modelBuilder.Entity("TaikoLocalServer.Entities.AiScoreDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.AiSectionScoreDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.Card", b =>
{
b.Property<string>("AccessCode")
.HasColumnType("TEXT");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.HasKey("AccessCode");
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
.IsUnique();
b.ToTable("Card", (string)null);
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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");
b.ToTable("DanScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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", "SongNumber");
b.ToTable("DanStageScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("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("TaikoLocalServer.Entities.UserDatum", b =>
{
b.Property<uint>("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<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<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>("ToneFlgArray")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Baid");
b.ToTable("UserData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.AiScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.AiSectionScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.AiScoreDatum", "Parent")
.WithMany("AiSectionScoreData")
.HasForeignKey("Baid", "SongId", "Difficulty")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.DanScoreDatum", "Parent")
.WithMany("DanStageScoreData")
.HasForeignKey("Baid", "DanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.AiScoreDatum", b =>
{
b.Navigation("AiSectionScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Navigation("DanStageScoreData");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace TaikoLocalServer.Migrations
{
/// <inheritdoc />
public partial class AddWinCountToUserdata : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "AiWinCount",
table: "UserData",
type: "INTEGER",
nullable: false,
defaultValue: 0);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "AiWinCount",
table: "UserData");
}
}
}

View File

@ -0,0 +1,432 @@
// <auto-generated />
using System;
using GameDatabase.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace TaikoLocalServer.Migrations
{
[DbContext(typeof(TaikoDbContext))]
partial class TaikoDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.7.22376.2");
modelBuilder.Entity("TaikoLocalServer.Entities.AiScoreDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.AiSectionScoreDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.Card", b =>
{
b.Property<string>("AccessCode")
.HasColumnType("TEXT");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.HasKey("AccessCode");
b.HasIndex(new[] { "Baid" }, "IX_Card_Baid")
.IsUnique();
b.ToTable("Card", (string)null);
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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");
b.ToTable("DanScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
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", "SongNumber");
b.ToTable("DanStageScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.Property<uint>("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("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("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("TaikoLocalServer.Entities.UserDatum", b =>
{
b.Property<uint>("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<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<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>("ToneFlgArray")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Baid");
b.ToTable("UserData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.AiScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.AiSectionScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.AiScoreDatum", "Parent")
.WithMany("AiSectionScoreData")
.HasForeignKey("Baid", "SongId", "Difficulty")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.DanScoreDatum", "Parent")
.WithMany("DanStageScoreData")
.HasForeignKey("Baid", "DanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
{
b.HasOne("TaikoLocalServer.Entities.Card", "Ba")
.WithMany()
.HasForeignKey("Baid")
.HasPrincipalKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("TaikoLocalServer.Entities.AiScoreDatum", b =>
{
b.Navigation("AiSectionScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>
{
b.Navigation("DanStageScoreData");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,22 @@
using System.Diagnostics;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace LocalSaveModScoreMigrator;
public class DateTimeConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
Debug.Assert(typeToConvert == typeof(DateTime));
var dateTime = DateTime.ParseExact(reader.GetString() ?? string.Empty, "dd_MM_yy-HH_mm_ss",
CultureInfo.InvariantCulture);
return dateTime;
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture));
}
}

View File

@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>1.0.0-beta1</Version>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JorgeSerrano.Json.JsonSnakeCaseNamingPolicy" Version="0.9.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.0-rc.1.22426.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.0-rc.1.22426.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.0-rc.1.22426.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SharpZipLib" Version="1.4.0" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GameDatabase\GameDatabase.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,8 @@
using System.Text.Json.Serialization;
namespace LocalSaveModScoreMigrator;
public class MusicInfo
{
[JsonPropertyName("items")] public List<MusicInfoEntry> Items { get; set; } = new();
}

View File

@ -0,0 +1,10 @@
using System.Text.Json.Serialization;
namespace LocalSaveModScoreMigrator;
public class MusicInfoEntry
{
[JsonPropertyName("id")] public string Id { get; set; } = string.Empty;
[JsonPropertyName("uniqueId")] public uint SongId { get; set; }
}

View File

@ -0,0 +1,21 @@
using System.Text.Json.Serialization;
using SharedProject.Enums;
namespace LocalSaveModScoreMigrator;
public class PlayRecordJson
{
public string SongId { get; set; } = "tmap4";
public Difficulty Difficulty { get; set; }
[JsonPropertyName("dateTime")] public DateTime DateTime { get; set; }
public uint Score { set; get; }
public CrownType Crown { get; set; }
[JsonPropertyName("scorerank")] public ScoreRank Scorerank { get; set; }
public uint Good { get; set; }
public uint Ok { get; set; }
public uint Bad { get; set; }
public uint Combo { get; set; }
public uint Drumroll { get; set; }
}

View File

@ -0,0 +1,196 @@
using GameDatabase.Context;
using GameDatabase.Entities;
using ICSharpCode.SharpZipLib.GZip;
using JorgeSerrano.Json;
using LocalSaveModScoreMigrator;
using SharedProject.Enums;
using System.CommandLine;
using System.CommandLine.Parsing;
using System.Text;
using System.Text.Json;
var rootCommand = new RootCommand("Command-line tool to migrate saves from local save mod to local server database.");
FileInfo? Parse(SymbolResult result, string defaultFileName)
{
if (result.Tokens.Count == 0)
{
return new FileInfo(defaultFileName);
}
var filePath = result.Tokens.Single().Value;
if (File.Exists(filePath))
{
return new FileInfo(filePath);
}
result.ErrorMessage = $"File {filePath} does not exist";
return null;
}
var saveFileArgument = new Option<FileInfo?>(
name: "--save-file-path",
description: "Path to the save file from local save mod",
isDefault: true,
parseArgument: result => Parse(result, "record_enso_p1.json")
);
saveFileArgument.AddAlias("-s");
var dbFileArgument = new Option<FileInfo?>(
name: "--db-file-path",
description: "Path to the database file for local server",
isDefault: true,
parseArgument: result => Parse(result, "wwwroot/taiko.db3")
);
dbFileArgument.AddAlias("-db");
var musicInfoArgument = new Option<FileInfo?>(
name: "--musicinfo-file-path",
description: "Path to the music info json/bin file",
isDefault: true,
parseArgument: result => Parse(result, "wwwroot/data/musicinfo.json")
);
musicInfoArgument.AddAlias("-m");
var baidArgument = new Option<ulong>(
name: "--baid",
description: "Target card's baid, data will be imported to that card",
getDefaultValue: () => 1
);
baidArgument.AddAlias("-b");
rootCommand.Add(saveFileArgument);
rootCommand.Add(dbFileArgument);
rootCommand.Add(musicInfoArgument);
rootCommand.Add(baidArgument);
rootCommand.SetHandler((saveFile, dbFile, musicInfoFile, baid) => Run(saveFile!, dbFile!, musicInfoFile!, baid),
saveFileArgument, dbFileArgument, musicInfoArgument, baidArgument);
await rootCommand.InvokeAsync(args);
void Run(FileSystemInfo saveFile, FileSystemInfo dbFile, FileSystemInfo musicInfoFile, ulong baid)
{
using var db = new TaikoDbContext(dbFile.FullName);
var card = db.Cards.FirstOrDefault(card1 => card1.Baid == baid);
if (card is null)
{
Console.ResetColor();
Console.ForegroundColor = ConsoleColor.Red;
Console.Error.WriteLine($"Card with baid {baid} does not exist!");
Console.ResetColor();
return;
}
Console.ResetColor();
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine($"Baid: {card.Baid}");
Console.WriteLine($"Access code: {card.AccessCode}");
Console.ResetColor();
var localSaveJson = File.ReadAllText(saveFile.FullName);
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = new JsonSnakeCaseNamingPolicy()
};
options.Converters.Add(new DateTimeConverter());
options.Converters.Add(new ScoreRankConverter());
var playRecordJson = JsonSerializer.Deserialize<List<PlayRecordJson>>(localSaveJson, options);
if (playRecordJson is null)
{
throw new ApplicationException("Play record json is null");
}
Console.WriteLine(playRecordJson.First().SongId);
var musicInfoJson = File.ReadAllText(musicInfoFile.FullName);
if (musicInfoFile.FullName.EndsWith(".bin"))
{
var compressed = File.OpenRead(musicInfoFile.FullName);
using var gZipInputStream = new GZipInputStream(compressed);
using var decompressed = new MemoryStream();
// Decompress
gZipInputStream.CopyTo(decompressed);
// Reset stream for reading
decompressed.Position = 0;
musicInfoJson = Encoding.UTF8.GetString(decompressed.ToArray());
}
var musicInfo = JsonSerializer.Deserialize<MusicInfo>(musicInfoJson);
if (musicInfo is null)
{
throw new ApplicationException("Music info is null");
}
var user = db.UserData.First();
var musicInfoMap = musicInfo.Items.DistinctBy(entry => entry.Id)
.ToDictionary(entry => entry.Id, entry => entry.SongId);
foreach (var playRecord in playRecordJson)
{
var key = playRecord.SongId.Split("_")[1];
if (!musicInfoMap.ContainsKey(key))
{
Console.ResetColor();
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"Key {key} does not exist!!!");
Console.ResetColor();
continue;
}
var songId = musicInfoMap[key];
Console.ResetColor();
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine($"Importing song with id: {songId}");
Console.WriteLine($"Song play time: {playRecord.DateTime}");
Console.ResetColor();
var playLog = new SongPlayDatum
{
Baid = user.Baid,
Difficulty = playRecord.Difficulty,
Crown = playRecord.Crown,
Score = playRecord.Score,
ScoreRank = playRecord.Scorerank,
ComboCount = playRecord.Combo,
DrumrollCount = playRecord.Drumroll,
PlayTime = playRecord.DateTime,
GoodCount = playRecord.Good,
MissCount = playRecord.Bad,
OkCount = playRecord.Ok,
Skipped = false,
SongNumber = 0,
SongId = songId
};
db.SongPlayData.Add(playLog);
var best = new SongBestDatum
{
Baid = user.Baid,
Difficulty = playRecord.Difficulty,
BestCrown = playRecord.Crown,
BestScore = playRecord.Score,
BestScoreRank = playRecord.Scorerank,
SongId = songId
};
var existing = db.SongBestData.FirstOrDefault(datum => datum.Baid == user.Baid &&
datum.Difficulty == playLog.Difficulty &&
datum.SongId == songId);
if (existing is null)
{
db.SongBestData.Add(best);
}
else
{
existing.BestCrown = (CrownType)Math.Max((int)existing.BestCrown, (int)playRecord.Crown);
existing.BestScoreRank = (ScoreRank)Math.Max((int)existing.BestScoreRank, (int)playRecord.Scorerank);
existing.BestScore = Math.Max(existing.BestScore, playRecord.Score);
db.SongBestData.Update(existing);
}
}
db.SaveChanges();
}

View File

@ -0,0 +1,22 @@
using System.Diagnostics;
using System.Text.Json;
using System.Text.Json.Serialization;
using SharedProject.Enums;
namespace LocalSaveModScoreMigrator;
public class ScoreRankConverter : JsonConverter<ScoreRank>
{
public override ScoreRank Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
Debug.Assert(typeToConvert == typeof(ScoreRank));
var scoreRankInt = reader.GetInt32() + 1;
return (ScoreRank)scoreRankInt;
}
public override void Write(Utf8JsonWriter writer, ScoreRank value, JsonSerializerOptions options)
{
var scoreRank = (int)value - 1;
writer.WriteStringValue(scoreRank.ToString());
}
}

95
OldSetup.md Normal file
View File

@ -0,0 +1,95 @@
# Old setup
1. Download the latest release of [TaikoArcadeLoader](https://github.com/BroGamer4256/TaikoArcadeLoader) and install it. Make sure to setup TAL using the config.toml and set the `server` parameter to your local IP address.
2. Download the latest release of [TaikoReverseProxy](https://github.com/shiibe/TaikoReverseProxy).
3. In the `Data\x64\datatable` folder of the game, find the following files:
```
music_attribute.bin
musicinfo.bin
music_order.bin
wordlist.bin
```
Extract them (you can use [7zip](https://www.7-zip.org)) and rename the extracted file like so:
```
music_attribute -> music_attribute.json
musicinfo -> musicinfo.json
music_order -> music_order.json
wordlist -> wordlist.json
```
Then put these in TaikoLocalServer's `wwwroot/data` folder.
4. Modify hosts, add the following entries (this step can be done automatically with TaikoReverseProxy, check the config for it):
```
server.ip tenporouter.loc
server.ip naominet.jp
server.ip v402-front.mucha-prd.nbgi-amnet.jp
server.ip vsapi.taiko-p.jp
```
where `server.ip` is your computer's ip (or the server's ip)
5. Open command prompt as admin, navigate to game root folder (where init.ps1 is). Run `regsvr32 .\AMCUS\iauthdll.dll`. It should prompt about success
6. Run TaikoReverseProxy and TaikoLocalServer, then run the game. You can access the WebUI by going to `https://naominet.jp:10122/` in your browser.
### Server setup (for TAL<2.00 or other loaders)
1. Download the server from release page, extract anywhere
2. From game's `Data\x64\datatable` folder, find `music_attribute.bin`, `musicinfo.bin`, `music_order.bin` and `wordlist.bin`, decompress them, add `.json` prefix to them.
The result is `music_attribute.json`, `musicinfo.json`, `music_order.json` and `wordlist.json`. Put the json files under` wwwroot/data` folder in server.
3. Modify hosts, add the following entries:
```
server.ip tenporouter.loc
server.ip naominet.jp
server.ip v402-front.mucha-prd.nbgi-amnet.jp
server.ip vsapi.taiko-p.jp
```
where `server.ip` is your computers ip (or the server's ip)
4. Setup [TaikoReverseProxy](https://github.com/shiibe/TaikoReverseProxy) or [Apache](#apache-setup-optional) as reverse proxy.
5. Now run the server, if everything is setup correctly, visit http://localhost:5000, you should be able to see the web ui up and running without errors. (If you encounter errors in web ui for the first time, try visit https://naominet.jp:10122/)
6. Go to game folder, copy the config files (AMConfig.ini and WritableConfig.ini) in the AMCUS folder from server release to AMCUS folder and replace the original ones.
7. Open command prompt as admin, navigate to game root folder (where init.ps1 is). Run `regsvr32 .\AMCUS\iauthdll.dll`. It should prompt about success.
8. Run AMCUS/AMAuthd.exe, then run AMCUS/AMUpdater.exe. If the updater run and exits without issue, you are ready to run the game and connect to server.
9. Run the game, it should now connect to the server.
### Run the server on another computer
If you want to run the server on another computer, the procedure is almost identical.
Before you open browser, in `wwwroot/appsettings.json`, change `BaseUrl` to `https://naominet.jp:10122` then instead of visit localhost, visit the server using domain name to test.
Also note that now the cetificate also need to be imported on client computer, or web ui may not work. If you don't need https, change `BaseUrl` to `http://server.ip:80`, and visit on client. The game does not care about certificate.
### Apache Setup (Optional)
Notice the following assumes a windows install, the server also works on Linux, but the guide only covers windows.
1. Download [Apache](https://www.apachelounge.com/download/), extract anywhere
2. Copy the content in release rar's Apache folder to installed Apache root folder (and replace, which includes httpd.conf and httpd-vhosts.conf, if no prompt to replace files, you are extracting to wrong folder)
3. Open `conf/httpd.conf` (under installed Apache folder), find this line (line 37 by default), modify it to your Apache install (extracted) full path
```htaccess
# For example, if your Apache is extracted to C:\users\username\Apache24, then this should be "c:/users/username/Apache24"
Define SRVROOT "d:/Projects/Apache24"
```
4. Open the certs folder Apache root folder, then click on the localhost.crt file and import it to trusted root store.
If everything is correct, run bin/httpd.exe, a command prompt will open (and stay open, if it shut down, probably something is not setup correctly)

46
README.md Normal file
View File

@ -0,0 +1,46 @@
# Taiko Local Server
This is a server for Taiko no Tatsujin Nijiiro ver 08.18
## Setup
### Prerequisite
- A working game, with dongle and card reader emulation. You can use [TaikoArcadeLoader](https://github.com/BroGamer4256/TaikoArcadeLoader) for these if you haven't.
### Quick Setup
With the newest release (from [this](https://github.com/BroGamer4256/TaikoArcadeLoader/tree/95d633850d89cb7099e98ffe74cd23632fe26e56) commit) of TaikoArcadeLoader, you no longer need to run AMAuthd, AMUpdater or reverse proxy.
1. Extract the server release anywhere
2. From the game files, copy `music_attribute.bin`, `music_order.bin`, `musicinfo.bin` and `wordlist.bin` to `wwwroot/data` folder.
3. (Optional) Instead of direct copy, extract the specified game files (using 7zip), rename them by adding the file extension `.json` and copy the jsons over.
4. (Optional) In `Certificates` folder, import `root.pfx` to trusted root store, `cert.pfx` to personal store. All the other import options can be kept default.
5. Visit http://localhost:5000 and (Optional, only if you have done step 4) https://localhost:10122, if the web ui starts without errors, the config is fine.
6. Modify comfig.toml from TAL, edit the following line:
```toml
server = "https://divamodarchive.com" # Change https://divamodarchive.com to your/server's ip, like 192.168.1.100
```
7. Open command prompt as admin, navigate to game root folder (where `init.ps1` is). Run `regsvr32 .\AMCUS\iauthdll.dll`. It should prompt about success (This only need to be done once)
8. Now the game should be able to connect.
### About certificates
If you want to change the certificate used by server, just replace `cert.pfx` in `Certificates` folder. The bundled certificate includes the following DNS names:
```
DNS Name=nbgi-amnet.jp
DNS Name=v402-front.mucha-prd.nbgi-amnet.jp
DNS Name=*.mucha-prd.nbgi-amnet.jp
DNS Name=localhost
DNS Name=vsapi.taiko-p.jp
```
You will need to modify hosts file to use them.

View File

@ -0,0 +1,9 @@
namespace SharedProject.Enums;
public enum CrownType
{
None = 0,
Clear = 1,
Gold = 2,
Dondaful = 3
}

View File

@ -0,0 +1,7 @@
namespace SharedProject.Enums;
public enum DanBorderType
{
All = 1,
PerSong = 2
}

View File

@ -0,0 +1,12 @@
namespace SharedProject.Enums;
public enum DanClearState
{
NotClear = 0,
RedNormalClear,
RedFullComboClear,
RedPerfectClear,
GoldNormalClear,
GoldFullComboClear,
GoldPerfectClear,
}

View File

@ -0,0 +1,13 @@
namespace SharedProject.Enums;
public enum DanConditionType
{
SoulGauge = 1,
GoodCount = 2,
OkCount = 3,
BadCount = 4,
ComboCount = 5,
DrumrollCount = 6,
Score = 7,
TotalHitCount = 8
}

View File

@ -0,0 +1,12 @@
namespace SharedProject.Enums;
public enum Difficulty : uint
{
None = 0,
Easy = 1,
Normal = 2,
Hard = 3,
Oni = 4,
UraOni = 5
}

View File

@ -0,0 +1,9 @@
namespace SharedProject.Enums;
public enum PlayMode
{
Normal = 0,
DanMode = 1,
// Not sure about this
AiBattle = 6
}

View File

@ -0,0 +1,9 @@
// ReSharper disable UnusedMember.Global
namespace SharedProject.Enums;
public enum RandomType
{
None = 0,
Whimsical = 1,
Messy = 2
}

View File

@ -0,0 +1,13 @@
namespace SharedProject.Enums;
public enum ScoreRank
{
None = 1,
White,
Bronze,
Silver,
Gold,
Sakura,
Purple,
Dondaful
}

View File

@ -0,0 +1,13 @@
namespace SharedProject.Enums;
public enum SongGenre
{
Pop = 0,
Anime = 1,
Kids = 2,
Vocaloid = 3,
GameMusic = 4,
NamcoOriginal = 5,
Variety = 7,
Classical = 8
}

View File

@ -0,0 +1,22 @@
using SharedProject.Enums;
namespace SharedProject.Models;
public class AiSectionBestData
{
public int SectionIndex { get; set; }
public CrownType Crown { get; set; }
public bool IsWin { get; set; }
public uint Score { get; set; }
public uint GoodCount { get; set; }
public uint OkCount { get; set; }
public uint MissCount { get; set; }
public uint DrumrollCount { get; set; }
}

View File

@ -0,0 +1,16 @@
using SharedProject.Enums;
namespace SharedProject.Models;
public class DanBestData
{
public uint DanId { get; set; }
public DanClearState ClearState { get; set; }
public uint SoulGaugeTotal { get; set; }
public uint ComboCountTotal { get; set; }
public List<DanBestStageData> DanBestStageDataList { get; set; } = new();
}

View File

@ -0,0 +1,22 @@
namespace SharedProject.Models;
public class DanBestStageData
{
public uint SongNumber { get; set; }
public uint PlayScore { get; set; }
public uint GoodCount { get; set; }
public uint OkCount { get; set; }
public uint BadCount { get; set; }
public uint DrumrollCount { get; set; }
public uint TotalHitCount { get; set; }
public uint ComboCount { get; set; }
public uint HighScore { get; set; }
}

View File

@ -0,0 +1,66 @@
using System.Text.Json.Serialization;
namespace SharedProject.Models;
public class DanData
{
[JsonPropertyName("danId")]
public uint DanId { get; set; }
[JsonPropertyName("title")]
public string Title { get; set; } = string.Empty;
[JsonPropertyName("verupNo")]
public uint VerupNo { get; set; }
[JsonPropertyName("aryOdaiSong")]
public List<OdaiSong> OdaiSongList { get; set; } = new();
[JsonPropertyName("aryOdaiBorder")]
public List<OdaiBorder> OdaiBorderList { get; set; } = new();
public class OdaiSong
{
[JsonPropertyName("songNo")]
public uint SongNo { get; set; }
[JsonPropertyName("level")]
public uint Level { get; set; }
[JsonPropertyName("isHiddenSongName")]
public bool IsHiddenSongName { get; set; }
}
public class OdaiBorder
{
[JsonPropertyName("odaiType")]
public uint OdaiType { get; set; }
[JsonPropertyName("borderType")]
public uint BorderType { get; set; }
[JsonPropertyName("redBorderTotal")]
public uint RedBorderTotal { get; set; }
[JsonPropertyName("goldBorderTotal")]
public uint GoldBorderTotal { get; set; }
[JsonPropertyName("redBorder_1")]
public uint RedBorder1 { get; set; }
[JsonPropertyName("redBorder_2")]
public uint RedBorder2 { get; set; }
[JsonPropertyName("redBorder_3")]
public uint RedBorder3 { get; set; }
[JsonPropertyName("goldBorder_1")]
public uint GoldBorder1 { get; set; }
[JsonPropertyName("goldBorder_2")]
public uint GoldBorder2 { get; set; }
[JsonPropertyName("goldBorder_3")]
public uint GoldBorder3 { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using System.Text.Json.Serialization;
namespace SharedProject.Models;
public class EventFolderData
{
[JsonPropertyName("folderId")]
public uint FolderId { get; set; }
[JsonPropertyName("verupNo")]
public uint VerupNo { get; set; }
[JsonPropertyName("priority")]
public uint Priority { get; set; }
[JsonPropertyName("songNo")]
public uint[]? SongNo { get; set; }
}

View File

@ -0,0 +1,14 @@
using SharedProject.Enums;
namespace SharedProject.Models;
public class PlaySetting
{
public uint Speed { get; set; }
public bool IsVanishOn { get; set; }
public bool IsInverseOn { get; set; }
public RandomType RandomType { get; set; }
}

View File

@ -0,0 +1,8 @@
namespace SharedProject.Models.Requests;
public class SetFavoriteRequest
{
public ulong Baid { get; set; }
public uint SongId { get; set; }
public bool IsFavorite { get; set; }
}

View File

@ -0,0 +1,6 @@
namespace SharedProject.Models.Responses;
public class DanBestDataResponse
{
public List<DanBestData> DanBestDataList { get; set; } = new();
}

View File

@ -0,0 +1,6 @@
namespace SharedProject.Models.Responses;
public class DashboardResponse
{
public List<User> Users { get; set; } = new();
}

View File

@ -0,0 +1,6 @@
namespace SharedProject.Models.Responses;
public class SongBestResponse
{
public List<SongBestData> SongBestData { get; set; } = new();
}

View File

@ -0,0 +1,49 @@
using SharedProject.Enums;
namespace SharedProject.Models;
public class SongBestData
{
public uint SongId { get; set; }
public SongGenre Genre { get; set; }
public string MusicName { get; set; } = string.Empty;
public string MusicArtist { get; set; } = string.Empty;
public Difficulty Difficulty { get; set; }
public int PlayCount { get; set; }
public int ClearCount { get; set; }
public int FullComboCount { get; set; }
public int PerfectCount { get; set; }
public uint BestScore { get; set; }
public uint BestRate { get; set; }
public CrownType BestCrown { get; set; }
public ScoreRank BestScoreRank { get; set; }
public DateTime LastPlayTime { get; set; }
public bool IsFavorite { get; set; }
public uint GoodCount { get; set; }
public uint OkCount { get; set; }
public uint MissCount { get; set; }
public uint ComboCount { get; set; }
public uint HitCount { get; set; }
public uint DrumrollCount { get; set; }
public List<AiSectionBestData> AiSectionBestData { get; set; } = new();
public bool ShowAiData { get; set; }
}

View File

@ -0,0 +1,18 @@
using System.Text.Json.Serialization;
namespace SharedProject.Models;
public class SongIntroductionData
{
[JsonPropertyName("setId")]
public uint SetId { get; set; }
[JsonPropertyName("verupNo")]
public uint VerupNo { get; set; }
[JsonPropertyName("mainSongNo")]
public uint MainSongNo { get; set; }
[JsonPropertyName("subSongNo")]
public uint[]? SubSongNo { get; set; }
}

View File

@ -0,0 +1,8 @@
namespace SharedProject.Models;
public class User
{
public string AccessCode { get; set; } = string.Empty;
public ulong Baid { get; set; }
}

View File

@ -0,0 +1,55 @@
using SharedProject.Enums;
namespace SharedProject.Models;
public class UserSetting
{
public uint ToneId { get; set; }
public bool IsDisplayAchievement { get; set; }
public bool IsDisplayDanOnNamePlate { get; set; }
public bool IsVoiceOn { get; set; }
public bool IsSkipOn { get; set; }
public Difficulty AchievementDisplayDifficulty { get; set; }
public PlaySetting PlaySetting { get; set; } = new();
public int NotesPosition { get; set; }
public string MyDonName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public uint TitlePlateId { get; set; }
public uint Kigurumi { get; set; }
public uint Head { get; set; }
public uint Body { get; set; }
public uint Face { get; set; }
public uint Puchi { get; set; }
public List<uint> UnlockedKigurumi { get; set; } = new();
public List<uint> UnlockedHead { get; set; } = new();
public List<uint> UnlockedBody { get; set; } = new();
public List<uint> UnlockedFace { get; set; } = new();
public List<uint> UnlockedPuchi { get; set; } = new();
public uint FaceColor { get; set; }
public uint BodyColor { get; set; }
public uint LimbColor { get; set; }
}

3
SharedProject/README.md Normal file
View File

@ -0,0 +1,3 @@
# Shared Project
This is the shared project for shared enums/models/utils etc. between server and web ui.

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Throw" Version="1.3.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,24 @@
namespace SharedProject.Utils;
public static class PathHelper
{
public static string GetRootPath()
{
var path = Environment.ProcessPath;
if (path is null)
{
throw new ApplicationException();
}
var parentPath = Directory.GetParent(path);
if (parentPath is null)
{
throw new ApplicationException();
}
return Path.Combine(parentPath.ToString(), "wwwroot");
}
public static string GetDataPath()
{
return Path.Combine(GetRootPath(), "data");
}
}

View File

@ -0,0 +1,48 @@
using System.Buffers.Binary;
using System.Collections;
using System.Collections.Specialized;
using SharedProject.Enums;
using SharedProject.Models;
using Throw;
namespace SharedProject.Utils;
public static class PlaySettingConverter
{
public static PlaySetting ShortToPlaySetting(short input)
{
var bits = new BitVector32(input);
var speedSection = BitVector32.CreateSection(15);
var vanishSection = BitVector32.CreateSection(1, speedSection);
var inverseSection = BitVector32.CreateSection(1, vanishSection);
var randomSection = BitVector32.CreateSection(2, inverseSection);
var randomType = (RandomType)bits[randomSection];
randomType.Throw().IfOutOfRange();
var result = new PlaySetting
{
Speed = (uint)bits[speedSection],
IsVanishOn = bits[vanishSection] == 1,
IsInverseOn = bits[inverseSection] == 1,
RandomType = randomType
};
return result;
}
public static short PlaySettingToShort(PlaySetting setting)
{
var bits = new BitVector32();
var speedSection = BitVector32.CreateSection(15);
var vanishSection = BitVector32.CreateSection(1, speedSection);
var inverseSection = BitVector32.CreateSection(1, vanishSection);
var randomSection = BitVector32.CreateSection(2, inverseSection);
bits[speedSection] = (int)setting.Speed;
bits[vanishSection] = setting.IsVanishOn ? 1 : 0;
bits[inverseSection] = setting.IsInverseOn ? 1 : 0;
bits[randomSection] = (int)setting.RandomType;
return (short)bits.Data;
}
}

View File

@ -0,0 +1,14 @@
namespace SharedProject.Utils;
public static class ValueHelpers
{
public static T Min<T>(T a, T b) where T : IComparable
{
return Comparer<T>.Default.Compare(a, b) <= 0 ? a : b;
}
public static T Max<T>(T a, T b) where T : IComparable
{
return Comparer<T>.Default.Compare(a, b) >= 0 ? a : b;
}
}

49
TaikoLocalServer.sln Normal file
View File

@ -0,0 +1,49 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.32112.339
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TaikoLocalServer", "TaikoLocalServer\TaikoLocalServer.csproj", "{98FDA12C-CD3C-42D0-BEBE-4E809E6E41AC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedProject", "SharedProject\SharedProject.csproj", "{34BAE5CA-D46B-489B-8617-3CEB2C0C614F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TaikoWebUI", "TaikoWebUI\TaikoWebUI.csproj", "{3F02C2B8-D970-4E8D-89AA-1B938DA6E2FE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameDatabase", "GameDatabase\GameDatabase.csproj", "{76F2B4D1-C05E-40F4-B577-095CA7DF0528}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalSaveModScoreMigrator", "LocalSaveModScoreMigrator\LocalSaveModScoreMigrator.csproj", "{72FAD857-4791-4925-8536-22FABD5976EE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{98FDA12C-CD3C-42D0-BEBE-4E809E6E41AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98FDA12C-CD3C-42D0-BEBE-4E809E6E41AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{98FDA12C-CD3C-42D0-BEBE-4E809E6E41AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98FDA12C-CD3C-42D0-BEBE-4E809E6E41AC}.Release|Any CPU.Build.0 = Release|Any CPU
{34BAE5CA-D46B-489B-8617-3CEB2C0C614F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{34BAE5CA-D46B-489B-8617-3CEB2C0C614F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{34BAE5CA-D46B-489B-8617-3CEB2C0C614F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{34BAE5CA-D46B-489B-8617-3CEB2C0C614F}.Release|Any CPU.Build.0 = Release|Any CPU
{3F02C2B8-D970-4E8D-89AA-1B938DA6E2FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F02C2B8-D970-4E8D-89AA-1B938DA6E2FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F02C2B8-D970-4E8D-89AA-1B938DA6E2FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F02C2B8-D970-4E8D-89AA-1B938DA6E2FE}.Release|Any CPU.Build.0 = Release|Any CPU
{76F2B4D1-C05E-40F4-B577-095CA7DF0528}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{76F2B4D1-C05E-40F4-B577-095CA7DF0528}.Debug|Any CPU.Build.0 = Debug|Any CPU
{76F2B4D1-C05E-40F4-B577-095CA7DF0528}.Release|Any CPU.ActiveCfg = Release|Any CPU
{76F2B4D1-C05E-40F4-B577-095CA7DF0528}.Release|Any CPU.Build.0 = Release|Any CPU
{72FAD857-4791-4925-8536-22FABD5976EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{72FAD857-4791-4925-8536-22FABD5976EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{72FAD857-4791-4925-8536-22FABD5976EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{72FAD857-4791-4925-8536-22FABD5976EE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9CF7BC99-7D07-47BA-A735-B292D48174C4}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,6 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kigurumi/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=musicinfo/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Namco/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Puchi/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Vocaloid/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "6.0.8",
"commands": [
"dotnet-ef"
]
}
}
}

1
TaikoLocalServer/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
wwwroot/data/music_attribute.json

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,48 @@
namespace TaikoLocalServer.Common;
public static class Constants
{
public const string DATE_TIME_FORMAT = "yyyyMMddHHmmss";
public const int MUSIC_ID_MAX = 1599;
public const int MUSIC_ID_MAX_EXPANDED = 9000;
public const string DEFAULT_DB_NAME = "taiko.db3";
public const string MUSIC_INFO_FILE_NAME = "musicinfo.json";
public const string MUSIC_INFO_COMPRESSED_FILE_NAME = "musicinfo.bin";
public const string MUSIC_ATTRIBUTE_FILE_NAME = "music_attribute.json";
public const string MUSIC_ATTRIBUTE_COMPRESSED_FILE_NAME = "music_attribute.bin";
public const string DAN_DATA_FILE_NAME = "dan_data.json";
public const string INTRO_DATA_FILE_NAME = "intro_data.json";
public const string EVENT_FOLDER_DATA_FILE_NAME = "event_folder_data.json";
public static readonly int[] EVENT_FOLDER_IDS = {
1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 14
};
public const int MIN_DAN_ID = 1;
public const int MAX_DAN_ID = 19;
public const int TONE_UID_MAX = 19;
public const int TITLE_UID_MAX = 814;
private const int COSTUME_FLAG_1_ARRAY_SIZE = 154;
private const int COSTUME_FLAG_2_ARRAY_SIZE = 140;
private const int COSTUME_FLAG_3_ARRAY_SIZE = 156;
private const int COSTUME_FLAG_4_ARRAY_SIZE = 58;
private const int COSTUME_FLAG_5_ARRAY_SIZE = 129;
public static readonly int[] CostumeFlagArraySizes =
{
COSTUME_FLAG_1_ARRAY_SIZE,
COSTUME_FLAG_2_ARRAY_SIZE,
COSTUME_FLAG_3_ARRAY_SIZE,
COSTUME_FLAG_4_ARRAY_SIZE,
COSTUME_FLAG_5_ARRAY_SIZE
};
}

View File

@ -0,0 +1,73 @@
using System.Collections;
namespace TaikoLocalServer.Common;
public class OrderedSet<T> : ICollection<T> where T : notnull
{
private readonly IDictionary<T, LinkedListNode<T>> dictionary;
private readonly LinkedList<T> linkedList;
public OrderedSet()
: this(EqualityComparer<T>.Default)
{
}
public OrderedSet(IEqualityComparer<T> comparer)
{
dictionary = new Dictionary<T, LinkedListNode<T>>(comparer);
linkedList = new LinkedList<T>();
}
public int Count => dictionary.Count;
public virtual bool IsReadOnly => dictionary.IsReadOnly;
void ICollection<T>.Add(T item)
{
Add(item);
}
public bool Add(T item)
{
if (dictionary.ContainsKey(item)) return false;
var node = linkedList.AddLast(item);
dictionary.Add(item, node);
return true;
}
public void Clear()
{
linkedList.Clear();
dictionary.Clear();
}
public bool Remove(T? item)
{
if (item == null) return false;
var found = dictionary.TryGetValue(item, out var node);
if (!found) return false;
dictionary.Remove(item);
if (node != null) linkedList.Remove(node);
return true;
}
public IEnumerator<T> GetEnumerator()
{
return linkedList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public bool Contains(T? item)
{
return item != null && dictionary.ContainsKey(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
linkedList.CopyTo(array, arrayIndex);
}
}

View File

@ -0,0 +1,24 @@
using GameDatabase.Entities;
using SharedProject.Utils;
namespace TaikoLocalServer.Common.Utils;
public static class Extensions
{
public static void UpdateBest(this AiSectionScoreDatum datum, PlayResultDataRequest.StageData.AiStageSectionData sectionData)
{
var crown = (CrownType)sectionData.Crown;
if (crown == CrownType.Gold && sectionData.OkCnt == 0)
{
crown = CrownType.Dondaful;
}
datum.IsWin = sectionData.IsWin ? sectionData.IsWin : datum.IsWin;
datum.Crown = ValueHelpers.Max(crown, datum.Crown);
datum.Score = ValueHelpers.Max(sectionData.Score, datum.Score);
datum.GoodCount = ValueHelpers.Max(sectionData.GoodCnt, datum.GoodCount);
datum.OkCount = ValueHelpers.Min(sectionData.OkCnt, datum.OkCount);
datum.MissCount = ValueHelpers.Min(sectionData.NgCnt, datum.MissCount);
datum.DrumrollCount = ValueHelpers.Max(sectionData.PoundCnt, datum.DrumrollCount);
}
}

View File

@ -0,0 +1,129 @@
using System.Collections;
using System.Collections.Specialized;
using System.Runtime.InteropServices;
using GameDatabase.Entities;
namespace TaikoLocalServer.Common.Utils;
public static class FlagCalculator
{
public static byte ComputeDondafulCrownFlag(byte previous, Difficulty difficulty)
{
// ReSharper disable once ArrangeRedundantParentheses
var flag = 1 << ((int)difficulty - 1);
return (byte)(previous | flag);
}
public static ushort ComputeCrownFlag(ushort previous, CrownType crownType, Difficulty difficulty)
{
int flagBase;
switch (crownType)
{
case CrownType.Clear:
flagBase = 0b10;
break;
case CrownType.Gold:
flagBase = 0b11;
break;
case CrownType.None:
case CrownType.Dondaful:
default:
throw new ArgumentOutOfRangeException(nameof(crownType), crownType, null);
}
var offset = ((int)difficulty - 1) * 2;
var flag = (ushort)(flagBase << offset);
return (ushort)(previous | flag);
}
public static byte ComputeKiwamiScoreRankFlag(byte previous, Difficulty difficulty)
{
// ReSharper disable once ArrangeRedundantParentheses
var result = 1 << ((int)difficulty - 1);
return (byte)(previous | result);
}
public static ushort ComputeMiyabiOrIkiScoreRank(ushort previous, ScoreRank scoreRank, Difficulty difficulty)
{
int resultBase;
switch (scoreRank)
{
case ScoreRank.White:
case ScoreRank.Gold:
resultBase = 0b01;
break;
case ScoreRank.Bronze:
case ScoreRank.Sakura:
resultBase = 0b10;
break;
case ScoreRank.Silver:
case ScoreRank.Purple:
resultBase = 0b11;
break;
case ScoreRank.None:
case ScoreRank.Dondaful:
default:
throw new ArgumentOutOfRangeException(nameof(scoreRank), scoreRank, "Score rank out of range");
}
var offset = ((int)difficulty - 1) * 2;
var result = resultBase << offset;
return (ushort)(previous | result);
}
public static byte[] ComputeGotDanFlags(List<DanScoreDatum> danScoreData)
{
var gotDanFlagList = new List<int>();
var gotDanFlag = new BitVector32();
var section1 = BitVector32.CreateSection(8);
var section2 = BitVector32.CreateSection(8, section1);
var section3 = BitVector32.CreateSection(8, section2);
var section4 = BitVector32.CreateSection(8, section3);
var section5 = BitVector32.CreateSection(8, section4);
var section6 = BitVector32.CreateSection(8, section5);
var section7 = BitVector32.CreateSection(8, section6);
var section8 = BitVector32.CreateSection(8, section7);
var sections = new[] { section1, section2, section3, section4, section5, section6, section7, section8 };
for (var i = Constants.MIN_DAN_ID; i < Constants.MAX_DAN_ID; i++)
{
var danId = i;
var flag = 0;
if (danScoreData.Any(datum => datum.DanId == danId))
{
var danScore = danScoreData.First(datum => datum.DanId == danId);
flag = (int)danScore.ClearState + 1;
}
var section = sections[(danId - 1) % 8];
gotDanFlag[section] = flag;
if (!section.Equals(section8))
{
continue;
}
gotDanFlagList.Add(gotDanFlag.Data);
gotDanFlag = new BitVector32();
}
gotDanFlagList.Add(gotDanFlag.Data);
return MemoryMarshal.AsBytes(new ReadOnlySpan<int>(gotDanFlagList.ToArray())).ToArray();
}
public static byte[] GetBitArrayFromIds(IEnumerable<uint> idArray, int bitArraySize, ILogger logger)
{
var result = new byte[bitArraySize / 8 + 1];
var bitSet = new BitArray(bitArraySize + 1);
foreach (var id in idArray)
{
if (id >= bitArraySize)
{
logger.LogWarning("Id {Id} out of range!", id);
continue;
}
bitSet.Set((int)id, true);
}
bitSet.CopyTo(result, 0);
return result;
}
}

View File

@ -0,0 +1,20 @@
using System.Text;
namespace TaikoLocalServer.Common.Utils;
public static class FormOutputUtil
{
public static string ToFormOutput(Dictionary<string, string> response)
{
var responseStr = new StringBuilder();
foreach (var pair in response)
{
responseStr.Append(pair.Key)
.Append('=')
.Append(pair.Value)
.Append('&');
}
return responseStr.ToString().TrimEnd('&');
}
}

View File

@ -0,0 +1,61 @@
using System.Runtime.InteropServices;
using System.Text;
using ICSharpCode.SharpZipLib.GZip;
namespace TaikoLocalServer.Common.Utils;
public static class GZipBytesUtil
{
public static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value));
}
public static byte[] GetEmptyJsonGZipBytes()
{
var outputStream = new MemoryStream(1024);
using (var stream = new GZipOutputStream(outputStream))
using (var writer = new StreamWriter(stream, Encoding.UTF8))
{
/*writer.AutoFlush = true;
writer.WriteLine("{}");*/
stream.Write(Array.Empty<byte>());
}
return outputStream.ToArray();
}
public static byte[] GetGZipBytes(byte[] input)
{
var outputStream = new MemoryStream(1024);
using (var stream = new GZipOutputStream(outputStream))
{
stream.Write(input);
}
return outputStream.ToArray();
}
public static byte[] GetGZipBytes<T>(T[] data) where T : struct
{
var outputStream = new MemoryStream(1024);
using (var stream = new GZipOutputStream(outputStream))
{
var byteRef = MemoryMarshal.AsBytes(new ReadOnlySpan<T>(data));
stream.Write(byteRef);
}
return outputStream.ToArray();
}
public static byte[] DecompressGZipBytes(byte[] input)
{
using (var inputStream = new MemoryStream(input))
using (var stream = new GZipInputStream(inputStream))
using (var outputStream = new MemoryStream(1024))
{
stream.CopyTo(outputStream);
return outputStream.ToArray();
}
}
}

View File

@ -0,0 +1,53 @@
using System.Text.Json;
using GameDatabase.Entities;
namespace TaikoLocalServer.Common.Utils;
public static class JsonHelper
{
public static List<uint> GetCostumeDataFromUserData(UserDatum userData, ILogger logger)
{
var costumeData = new List<uint> { 0, 0, 0, 0, 0 };
try
{
costumeData = JsonSerializer.Deserialize<List<uint>>(userData.CostumeData);
}
catch (JsonException e)
{
logger.LogError(e, "Parsing costume json data failed");
}
if (costumeData != null && costumeData.Count >= 5)
{
return costumeData;
}
logger.LogWarning("Costume data is null or count less than 5!");
costumeData = new List<uint> { 0, 0, 0, 0, 0 };
return costumeData;
}
public static List<List<uint>> GetCostumeUnlockDataFromUserData(UserDatum userData, ILogger logger)
{
var costumeUnlockData = new List<List<uint>> { new(), new(), new(), new(), new() };
try
{
costumeUnlockData = JsonSerializer.Deserialize<List<List<uint>>>(userData.CostumeFlgArray);
}
catch (JsonException e)
{
logger.LogError(e, "Parsing costume json data failed");
}
if (costumeUnlockData != null && costumeUnlockData.Count >= 5)
{
return costumeUnlockData;
}
logger.LogWarning("Costume unlock data is null or count less than 5!");
costumeUnlockData = new List<List<uint>> { new(), new(), new(), new(), new() };
return costumeUnlockData;
}
}

View File

@ -0,0 +1,26 @@
using GameDatabase.Entities;
using Swan.Mapping;
namespace TaikoLocalServer.Common.Utils;
using DanScoreDataStage = GetDanScoreResponse.DanScoreData.DanScoreDataStage;
public static class ObjectMappers
{
public static readonly IObjectMap<DanStageScoreDatum, DanScoreDataStage> DanStageDbToResponseMap;
static ObjectMappers()
{
var mapper = new ObjectMapper();
DanStageDbToResponseMap = mapper.AddMap<DanStageScoreDatum, DanScoreDataStage>()
.Add(t => t.ComboCnt, s => s.ComboCount)
.Add(t => t.GoodCnt, s => s.GoodCount)
.Add(t => t.OkCnt, s => s.OkCount)
.Add(t => t.NgCnt, s => s.BadCount)
.Add(t => t.HitCnt, s => s.TotalHitCount)
.Add(t => t.PoundCnt, s => s.DrumrollCount)
.Add(t => t.PlayScore, s => s.PlayScore)
.Add(t => t.HighScore, s => s.HighScore);
}
}

View File

@ -0,0 +1,7 @@
{
"DataSettings" : {
"DanDataFileName" : "dan_data.json",
"EventFolderDataFileName" : "event_folder_data.json",
"IntroDataFileName" : "intro_data.json"
}
}

View File

@ -0,0 +1,3 @@
{
"DbFileName" : "taiko.db3"
}

View File

@ -0,0 +1,28 @@
{
"Kestrel": {
"Endpoints": {
"BaseServer": {
"Url": "http://0.0.0.0:5000"
},
"AmAuthServer": {
"Url": "http://0.0.0.0:80"
},
"MuchaServer": {
"Url": "https://0.0.0.0:10122"
},
"GameServer1": {
"Url": "https://0.0.0.0:57402"
},
"GameServer2": {
"Url": "https://0.0.0.0:54431"
}
},
"Certificates": {
"Default": {
"Path": "Certificates/cert.pfx",
"Password": "",
"AllowInvalid": true
}
}
}
}

View File

@ -0,0 +1,27 @@
{
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.AspNetCore": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"Filter": [
{
"Name": "ByExcluding",
"Args": {
"expression": "@mt = 'An unhandled exception has occurred while executing the request.'"
}
}
],
"WriteTo": [
{
"Name": "File",
"Args": { "path": "./Logs/log-.txt", "rollingInterval": "Day" }
}
]
}
}

View File

@ -0,0 +1,7 @@
{
"ServerSettings": {
"MuchaUrl": "https://v402-front.mucha-prd.nbgi-amnet.jp:10122",
"GameUrl": "vsapi.taiko-p.jp",
"EnableMoreSongs": false
}
}

View File

@ -0,0 +1,50 @@
using Microsoft.Extensions.Options;
using TaikoLocalServer.Settings;
namespace TaikoLocalServer.Controllers.AmAuth;
[ApiController]
[Route("/sys/servlet/PowerOn")]
public class PowerOnController : BaseController<PowerOnController>
{
private readonly ServerSettings settings;
public PowerOnController(IOptions<ServerSettings> settings)
{
this.settings = settings.Value;
}
[HttpPost]
public ContentResult PowerOn([FromForm] PowerOnRequest request)
{
Logger.LogInformation("Power on request: {Request}",request.Stringify());
var now = DateTime.Now;
var response = new Dictionary<string, string>
{
{"stat", "1"},
{"uri", settings.GameUrl},
{"host", settings.GameUrl},
{"place_id", "JPN0123"},
{"name", "NAMCO"},
{"nickname", "NAMCO"},
{"region0", "1"},
{"region_name0", "NAMCO"},
{"region_name1", "X"},
{"region_name2", "Y"},
{"region_name3", "Z"},
{"country", "JPN"},
{"allnet_id", "456"},
{"timezone", "002,00"},
{"setting", ""},
{"year", now.Year.ToString()},
{"month", now.Month.ToString()},
{"day", now.Day.ToString()},
{"hour", now.Hour.ToString()},
{"minute", now.Minute.ToString()},
{"second", now.Second.ToString()},
{"res_class", "PowerOnResponseVer2"},
{"token", "123"}
};
return Content(FormOutputUtil.ToFormOutput(response) + '\n');
}
}

View File

@ -0,0 +1,87 @@
using Microsoft.Extensions.Options;
using TaikoLocalServer.Settings;
namespace TaikoLocalServer.Controllers.AmUpdater;
public class MuchaController : BaseController<MuchaController>
{
private readonly ServerSettings settings;
public MuchaController(IOptions<ServerSettings> settings)
{
this.settings = settings.Value;
}
[HttpPost("/mucha_front/boardauth.do")]
public ContentResult BoardAuth([FromForm] MuchaUpdateCheckRequest request)
{
Logger.LogInformation("Mucha request: {Request}", request.Stringify());
var serverTime = DateTime.Now.ToString("yyyyMMddHHmm");
var utcServerTime = DateTime.UtcNow.ToString("yyyyMMddHHmm");
var response = new Dictionary<string, string>
{
{ "RESULTS", "001" },
{ "AREA_0", "008" },
{ "AREA_0_EN", "" },
{ "AREA_1", "009" },
{ "AREA_1_EN", "" },
{ "AREA_2", "010" },
{ "AREA_2_EN", "" },
{ "AREA_3", "011" },
{ "AREA_3_EN", "" },
{ "AREA_FULL_0", "" },
{ "AREA_FULL_0_EN", "" },
{ "AREA_FULL_1", "" },
{ "AREA_FULL_1_EN", "" },
{ "AREA_FULL_2", "" },
{ "AREA_FULL_2_EN", "" },
{ "AREA_FULL_3", "" },
{ "AREA_FULL_3_EN", "" },
{ "AUTH_INTERVAL", "86400" },
{ "CHARGE_URL", $"{settings.MuchaUrl}/charge/" },
{ "CONSUME_TOKEN", "0" },
{ "COUNTRY_CD", "JPN" },
{ "DONGLE_FLG", "1" },
{ "EXPIRATION_DATE", "null" },
{ "FILE_URL", $"{settings.MuchaUrl}/file/" },
{ "FORCE_BOOT", "0" },
{ "PLACE_ID", request.PlaceId ?? "" },
{ "PREFECTURE_ID", "14" },
{ "SERVER_TIME", serverTime },
{ "UTC_SERVER_TIME", utcServerTime },
{ "SHOP_NAME", "NAMCO" },
{ "SHOP_NAME_EN", "NAMCO" },
{ "SHOP_NICKNAME", "W" },
{ "SHOP_NICKNAME_EN", "W" },
{ "URL_1", $"{settings.MuchaUrl}/url1/" },
{ "URL_2", $"{settings.MuchaUrl}/url2/" },
{ "URL_3", $"{settings.MuchaUrl}/url3/" },
{ "USE_TOKEN", "0" }
};
var formOutput = FormOutputUtil.ToFormOutput(response);
return Content(formOutput);
}
[HttpPost("/mucha_front/updatacheck.do")]
public ContentResult UpdateCheck(MuchaBoardAuthRequest request)
{
Logger.LogInformation("Request is {Request}", request.Stringify());
var response = new Dictionary<string, string>
{
{ "RESULTS", "001" },
{ "UPDATE_VER_1", request.GameVersion ?? "S1210JPN08.18" },
{ "UPDATE_URL_1", $"{settings.MuchaUrl}/updUrl1/" },
{ "UPDATE_SIZE_1", "0" },
{ "UPDATE_CRC_1", "0000000000000000" },
{ "CHECK_URL_1", $"{settings.MuchaUrl}/checkUrl/" },
{ "EXE_VER_1", request.GameVersion ?? "S1210JPN08.18" },
{ "INFO_SIZE_1", "0" },
{ "COM_SIZE_1", "0" },
{ "COM_TIME_1", "0" },
{ "LAN_INFO_SIZE_1", "0" }
};
var formOutput = FormOutputUtil.ToFormOutput(response);
return Content(formOutput);
}
}

View File

@ -0,0 +1,22 @@
namespace TaikoLocalServer.Controllers.Api;
[ApiController]
[Route("api/[controller]")]
public class CardsController : BaseController<CardsController>
{
private readonly ICardService cardService;
public CardsController(ICardService cardService)
{
this.cardService = cardService;
}
[HttpDelete("{accessCode}")]
public async Task<IActionResult> DeleteUser(string accessCode)
{
var result = await cardService.DeleteCard(accessCode);
return result ? NoContent() : NotFound();
}
}

View File

@ -0,0 +1,35 @@
using SharedProject.Models;
using SharedProject.Models.Responses;
using Swan.Mapping;
namespace TaikoLocalServer.Controllers.Api;
[ApiController]
[Route("api/[controller]")]
public class DanBestDataController : BaseController<DanBestDataController>
{
private readonly IDanScoreDatumService danScoreDatumService;
public DanBestDataController(IDanScoreDatumService danScoreDatumService) {
this.danScoreDatumService = danScoreDatumService;
}
[HttpGet("{baid}")]
public async Task<IActionResult> GetDanBestData(ulong baid)
{
var danScores = await danScoreDatumService.GetDanScoreDatumByBaid(baid);
var danDataList = new List<DanBestData>();
foreach (var danScore in danScores)
{
var danData = danScore.CopyPropertiesToNew<DanBestData>();
danData.DanBestStageDataList = danScore.DanStageScoreData.Select(datum => datum.CopyPropertiesToNew<DanBestStageData>()).ToList();
danDataList.Add(danData);
}
return Ok(new DanBestDataResponse
{
DanBestDataList = danDataList
});
}
}

View File

@ -0,0 +1,26 @@
using SharedProject.Models.Responses;
namespace TaikoLocalServer.Controllers.Api;
[ApiController]
[Route("/api/[controller]")]
public class DashboardController : BaseController<DashboardController>
{
private readonly ICardService cardService;
public DashboardController(ICardService cardService)
{
this.cardService = cardService;
}
[HttpGet]
public async Task<DashboardResponse> GetDashboard()
{
var users = await cardService.GetUsersFromCards();
return new DashboardResponse
{
Users = users
};
}
}

View File

@ -0,0 +1,29 @@
using SharedProject.Models.Requests;
namespace TaikoLocalServer.Controllers.Api;
[ApiController]
[Route("api/[controller]")]
public class FavoriteSongsController : BaseController<FavoriteSongsController>
{
private readonly IUserDatumService userDatumService;
public FavoriteSongsController(IUserDatumService userDatumService)
{
this.userDatumService = userDatumService;
}
[HttpPost]
public async Task<IActionResult> UpdateFavoriteSong(SetFavoriteRequest request)
{
var user = await userDatumService.GetFirstUserDatumOrNull(request.Baid);
if (user is null)
{
return NotFound();
}
await userDatumService.UpdateFavoriteSong(request.Baid, request.SongId, request.IsFavorite);
return NoContent();
}
}

Some files were not shown because too many files have changed in this diff Show More