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

Save rewards

This commit is contained in:
esuo1198 2022-09-14 16:15:23 +09:00
parent 8cdf38f586
commit 5cde9334bf
9 changed files with 548 additions and 19 deletions

View File

@ -27,4 +27,12 @@ public static class Constants
public const int MIN_DAN_ID = 1;
public const int MAX_DAN_ID = 19;
public const int GOT_DAN_BITS = MAX_DAN_ID * 4;
public const int TONE_UID_MAX = 19;
public const int TITLE_UID_MAX = 814;
public const int COSTUME_FLAG_1_ARRAY_SIZE = 154;
public const int COSTUME_FLAG_2_ARRAY_SIZE = 140;
public const int COSTUME_FLAG_3_ARRAY_SIZE = 156;
public const int COSTUME_FLAG_4_ARRAY_SIZE = 58;
public const int COSTUME_FLAG_5_ARRAY_SIZE = 129;
}

View File

@ -1,5 +1,8 @@
using System.Text.Json;
using System.Collections.Generic;
using System.Collections;
using System.Text.Json;
using TaikoLocalServer.Services.Interfaces;
using Throw;
namespace TaikoLocalServer.Controllers.Game;
@ -107,8 +110,59 @@ public class BaidController : BaseController<BaidController>
costumeData = new List<uint> { 0, 0, 0, 0, 0 };
}
var costumeFlag = new byte[10];
Array.Fill(costumeFlag, byte.MaxValue);
var costumeArrays = Array.Empty<uint[]>();
try
{
costumeArrays = JsonSerializer.Deserialize<uint[][]>(userData.CostumeFlgArray);
}
catch (JsonException e)
{
Logger.LogError(e, "Parsing costume flg json data failed");
}
// The only way to get a null is provide string "null" as input,
// which means database content need to be fixed, so better throw
costumeArrays.ThrowIfNull("Costume flg should never be null!");
var costumeFlg1 = new byte[Constants.COSTUME_FLAG_1_ARRAY_SIZE];
var bitSet = new BitArray(Constants.COSTUME_FLAG_1_ARRAY_SIZE);
foreach (var costume in costumeArrays[0])
{
bitSet.Set((int)costume, true);
}
bitSet.CopyTo(costumeFlg1, 0);
var costumeFlg2 = new byte[Constants.COSTUME_FLAG_2_ARRAY_SIZE];
bitSet = new BitArray(Constants.COSTUME_FLAG_2_ARRAY_SIZE);
foreach (var costume in costumeArrays[1])
{
bitSet.Set((int)costume, true);
}
bitSet.CopyTo(costumeFlg2, 0);
var costumeFlg3 = new byte[Constants.COSTUME_FLAG_3_ARRAY_SIZE];
bitSet = new BitArray(Constants.COSTUME_FLAG_3_ARRAY_SIZE);
foreach (var costume in costumeArrays[2])
{
bitSet.Set((int)costume, true);
}
bitSet.CopyTo(costumeFlg3, 0);
var costumeFlg4 = new byte[Constants.COSTUME_FLAG_4_ARRAY_SIZE];
bitSet = new BitArray(Constants.COSTUME_FLAG_4_ARRAY_SIZE);
foreach (var costume in costumeArrays[3])
{
bitSet.Set((int)costume, true);
}
bitSet.CopyTo(costumeFlg4, 0);
var costumeFlg5 = new byte[Constants.COSTUME_FLAG_5_ARRAY_SIZE];
bitSet = new BitArray(Constants.COSTUME_FLAG_5_ARRAY_SIZE);
foreach (var costume in costumeArrays[4])
{
bitSet.Set((int)costume, true);
}
bitSet.CopyTo(costumeFlg5, 0);
var danData = await danScoreDatumService.GetDanScoreDatumByBaid(baid);
@ -145,11 +199,11 @@ public class BaidController : BaseController<BaidController>
Costume4 = costumeData[3],
Costume5 = costumeData[4]
},
CostumeFlg1 = costumeFlag,
CostumeFlg2 = costumeFlag,
CostumeFlg3 = costumeFlag,
CostumeFlg4 = costumeFlag,
CostumeFlg5 = costumeFlag,
CostumeFlg1 = costumeFlg1,
CostumeFlg2 = costumeFlg2,
CostumeFlg3 = costumeFlg3,
CostumeFlg4 = costumeFlg4,
CostumeFlg5 = costumeFlg5,
LastPlayDatetime = userData.LastPlayDatetime.ToString(Constants.DATE_TIME_FORMAT),
IsDispDanOn = userData.DisplayDan,
GotDanMax = maxDan,

View File

@ -40,7 +40,10 @@ public class MyDonEntryController : BaseController<MyDonEntryController>
ColorFace = 0,
ColorBody = 1,
ColorLimb = 3,
FavoriteSongsArray = "[]"
FavoriteSongsArray = "[]",
ToneFlgArray = "[]",
TitleFlgArray = "[]",
CostumeFlgArray = "[[],[],[],[],[]]"
};
await userDatumService.InsertUserDatum(newUser);

View File

@ -1,6 +1,7 @@
using System.Buffers.Binary;
using System.Globalization;
using System.Text.Json;
using TaikoLocalServer.Entities;
using TaikoLocalServer.Services.Interfaces;
using Throw;
@ -191,6 +192,21 @@ public class PlayResultController : BaseController<PlayResultController>
userdata.LastPlayDatetime = lastPlayDatetime;
userdata.LastPlayMode = playResultData.PlayMode;
var toneFlgData = JsonSerializer.Deserialize<List<uint>>(userdata.ToneFlgArray);
toneFlgData?.AddRange(playResultData.GetToneNoes ?? new uint[0]);
userdata.ToneFlgArray = JsonSerializer.Serialize(toneFlgData);
var titleFlgData = JsonSerializer.Deserialize<List<uint>>(userdata.TitleFlgArray);
titleFlgData?.AddRange(playResultData.GetTitleNoes ?? new uint[0]);
userdata.TitleFlgArray = JsonSerializer.Serialize(titleFlgData);
var costumeFlgData = JsonSerializer.Deserialize<List<List<uint>>>(userdata.CostumeFlgArray);
costumeFlgData?[0].AddRange(playResultData.GetCostumeNo1s ?? new uint[0]);
costumeFlgData?[1].AddRange(playResultData.GetCostumeNo2s ?? new uint[0]);
costumeFlgData?[2].AddRange(playResultData.GetCostumeNo3s ?? new uint[0]);
costumeFlgData?[3].AddRange(playResultData.GetCostumeNo4s ?? new uint[0]);
costumeFlgData?[4].AddRange(playResultData.GetCostumeNo5s ?? new uint[0]);
userdata.CostumeFlgArray = JsonSerializer.Serialize(costumeFlgData);
await userDatumService.UpdateUserDatum(userdata);
}

View File

@ -44,8 +44,51 @@ public class UserDataController : BaseController<UserDataController>
}
bitSet.CopyTo(uraSongArray, 0);
var toneArray = new byte[16];
Array.Fill(toneArray, byte.MaxValue);
var userData = await userDatumService.GetFirstUserDatumOrDefault(request.Baid);
var toneFlg = Array.Empty<uint>();
try
{
toneFlg = JsonSerializer.Deserialize<uint[]>(userData.ToneFlgArray);
}
catch (JsonException e)
{
Logger.LogError(e, "Parsing tone flg json data failed");
}
// The only way to get a null is provide string "null" as input,
// which means database content need to be fixed, so better throw
toneFlg.ThrowIfNull("Tone flg should never be null!");
var toneArray = new byte[Constants.TONE_UID_MAX];
bitSet = new BitArray(Constants.TONE_UID_MAX);
foreach (var tone in toneFlg)
{
bitSet.Set((int)tone, true);
}
bitSet.CopyTo(toneArray, 0);
var titleFlg = Array.Empty<uint>();
try
{
titleFlg = JsonSerializer.Deserialize<uint[]>(userData.TitleFlgArray);
}
catch (JsonException e)
{
Logger.LogError(e, "Parsing title flg json data failed");
}
// The only way to get a null is provide string "null" as input,
// which means database content need to be fixed, so better throw
titleFlg.ThrowIfNull("Title flg should never be null!");
var titleArray = new byte[Constants.TITLE_UID_MAX];
bitSet = new BitArray(Constants.TITLE_UID_MAX);
foreach (var title in titleFlg)
{
bitSet.Set((int)title, true);
}
bitSet.CopyTo(titleArray, 0);
var recentSongs = (await songPlayDatumService.GetSongPlayDatumByBaid(request.Baid))
.AsEnumerable()
@ -67,8 +110,6 @@ public class UserDataController : BaseController<UserDataController>
recentSongs = recentSet.ToArray();
var userData = await userDatumService.GetFirstUserDatumOrDefault(request.Baid);
var favoriteSongs = Array.Empty<uint>();
try
{
@ -90,7 +131,7 @@ public class UserDataController : BaseController<UserDataController>
{
Result = 1,
ToneFlg = toneArray,
// TitleFlg = GZipBytesUtil.GetGZipBytes(new byte[100]),
TitleFlg = titleArray,
ReleaseSongFlg = releaseSongArray,
UraReleaseSongFlg = uraSongArray,
DefaultOptionSetting = defaultOptions,

View File

@ -7,6 +7,9 @@
public string Title { get; set; } = string.Empty;
public uint TitlePlateId { get; set; }
public string FavoriteSongsArray { get; set; } = string.Empty;
public string ToneFlgArray { get; set; } = string.Empty;
public string TitleFlgArray { get; set; } = string.Empty;
public string CostumeFlgArray { get; set; } = string.Empty;
public short OptionSetting { get; set; }
public int NotesPosition { get; set; }
public bool IsVoiceOn { get; set; }

View File

@ -0,0 +1,341 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using TaikoLocalServer.Context;
#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

@ -57,7 +57,7 @@ namespace TaikoLocalServer.Migrations
b.HasKey("Baid", "DanId");
b.ToTable("DanScoreData", (string)null);
b.ToTable("DanScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
@ -97,7 +97,7 @@ namespace TaikoLocalServer.Migrations
b.HasKey("Baid", "DanId", "SongNumber");
b.ToTable("DanStageScoreData", (string)null);
b.ToTable("DanStageScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
@ -125,7 +125,7 @@ namespace TaikoLocalServer.Migrations
b.HasKey("Baid", "SongId", "Difficulty");
b.ToTable("SongBestData", (string)null);
b.ToTable("SongBestData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b =>
@ -186,7 +186,7 @@ namespace TaikoLocalServer.Migrations
b.HasIndex("Baid");
b.ToTable("SongPlayData", (string)null);
b.ToTable("SongPlayData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
@ -210,6 +210,10 @@ namespace TaikoLocalServer.Migrations
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("CostumeFlgArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("DisplayAchievement")
.HasColumnType("INTEGER");
@ -249,12 +253,20 @@ namespace TaikoLocalServer.Migrations
.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", (string)null);
b.ToTable("UserData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>