1
0
mirror of synced 2024-11-23 22:41:01 +01:00

Add costume setting to user settings and page prototype

This commit is contained in:
asesidaa 2022-09-14 20:14:21 +08:00
parent 95dc84d4b2
commit d6e27fa75c
14 changed files with 165 additions and 51 deletions

View File

@ -20,9 +20,36 @@ public class UserSetting
public int NotesPosition { get; set; }
public string MyDonName { get; set; } = String.Empty;
public string MyDonName { get; set; } = string.Empty;
public string Title { 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; }
}

View File

@ -1,4 +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,52 @@
using System.Text.Json;
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

@ -2,7 +2,7 @@
public static class PathHelper
{
public static string GetDataPath()
public static string GetRootPath()
{
var path = Environment.ProcessPath;
if (path is null)
@ -14,6 +14,11 @@ public static class PathHelper
{
throw new ApplicationException();
}
return Path.Combine(parentPath.ToString(), "wwwroot", "data");
return Path.Combine(parentPath.ToString(), "wwwroot");
}
public static string GetDataPath()
{
return Path.Combine(GetRootPath(), "data");
}
}

View File

@ -22,7 +22,7 @@
{
return;
}
var path = Path.Combine(PathHelper.GetDataPath(), Constants.DEFAULT_DB_NAME);
var path = Path.Combine(PathHelper.GetRootPath(), Constants.DEFAULT_DB_NAME);
optionsBuilder.UseSqlite($"Data Source={path}");
}

View File

@ -1,9 +1,11 @@
using System.Buffers.Binary;
using System.Text.Json;
using SharedProject.Models;
using SharedProject.Models.Responses;
using SharedProject.Utils;
using TaikoLocalServer.Services;
using TaikoLocalServer.Services.Interfaces;
using Throw;
namespace TaikoLocalServer.Controllers.Api;
@ -28,6 +30,10 @@ public class UserSettingsController : BaseController<UserSettingsController>
return NotFound();
}
var costumeData = JsonHelper.GetCostumeDataFromUserData(user, Logger);
var costumeUnlockData = JsonHelper.GetCostumeUnlockDataFromUserData(user, Logger);
var response = new UserSetting
{
AchievementDisplayDifficulty = user.AchievementDisplayDifficulty,
@ -40,7 +46,20 @@ public class UserSettingsController : BaseController<UserSettingsController>
ToneId = user.SelectedToneId,
MyDonName = user.MyDonName,
Title = user.Title,
TitlePlateId = user.TitlePlateId
TitlePlateId = user.TitlePlateId,
Kigurumi = costumeData[0],
Head = costumeData[1],
Body = costumeData[2],
Face = costumeData[3],
Puchi = costumeData[4],
UnlockedKigurumi = costumeUnlockData[0],
UnlockedHead = costumeUnlockData[1],
UnlockedBody = costumeUnlockData[2],
UnlockedFace = costumeUnlockData[3],
UnlockedPuchi = costumeUnlockData[4],
BodyColor = user.ColorBody,
FaceColor = user.ColorFace,
LimbColor = user.ColorLimb
};
return Ok(response);
}
@ -55,6 +74,15 @@ public class UserSettingsController : BaseController<UserSettingsController>
return NotFound();
}
var costumes = new List<uint>
{
userSetting.Kigurumi,
userSetting.Head,
userSetting.Body,
userSetting.Face,
userSetting.Puchi,
};
user.IsSkipOn = userSetting.IsSkipOn;
user.IsVoiceOn = userSetting.IsVoiceOn;
user.DisplayAchievement = userSetting.IsDisplayAchievement;
@ -66,6 +94,11 @@ public class UserSettingsController : BaseController<UserSettingsController>
user.MyDonName = userSetting.MyDonName;
user.Title = userSetting.Title;
user.TitlePlateId = userSetting.TitlePlateId;
user.ColorBody = userSetting.BodyColor;
user.ColorFace = userSetting.FaceColor;
user.ColorLimb = userSetting.LimbColor;
user.CostumeData = JsonSerializer.Serialize(costumes);
await userDatumService.UpdateUserDatum(user);

View File

@ -1,6 +1,4 @@
using System.Text.Json;
using TaikoLocalServer.Services.Interfaces;
using Throw;
using TaikoLocalServer.Services.Interfaces;
namespace TaikoLocalServer.Controllers.Game;
@ -79,34 +77,9 @@ public class BaidController : BaseController<BaidController>
var scoreRankCount = CalculateScoreRankCount(songCountData);
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)
{
Logger.LogWarning("Costume data is null or count less than 5!");
costumeData = new List<uint> { 0, 0, 0, 0, 0 };
}
var costumeData = JsonHelper.GetCostumeDataFromUserData(userData, Logger);
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 costumeArrays = JsonHelper.GetCostumeUnlockDataFromUserData(userData, Logger);
var costumeFlagArrays = Constants.CostumeFlagArraySizes
.Select((size, index) => FlagCalculator.GetBitArrayFromIds(costumeArrays[index], size, Logger))

View File

@ -14,13 +14,8 @@ public class InitialDataCheckController : BaseController<InitialDataCheckControl
var musicAttributeManager = MusicAttributeManager.Instance;
var enabledArray = new byte[Constants.MUSIC_FLAG_ARRAY_SIZE];
var bitSet = new BitArray(Constants.MUSIC_ID_MAX);
foreach (var music in musicAttributeManager.Musics)
{
bitSet.Set((int)music, true);
}
bitSet.CopyTo(enabledArray, 0);
var enabledArray =
FlagCalculator.GetBitArrayFromIds(musicAttributeManager.Musics, Constants.MUSIC_ID_MAX, Logger);
var danData = new List<InitialdatacheckResponse.InformationData>();
for (var danId = Constants.MIN_DAN_ID; danId <= Constants.MAX_DAN_ID; danId++)

View File

@ -6,10 +6,10 @@
public string MyDonName { get; set; } = string.Empty;
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 string FavoriteSongsArray { get; set; } = "[]";
public string ToneFlgArray { get; set; } = "[]";
public string TitleFlgArray { get; set; } = "[]";
public string CostumeFlgArray { get; set; } = "[]";
public short OptionSetting { get; set; }
public int NotesPosition { get; set; }
public bool IsVoiceOn { get; set; }
@ -20,7 +20,7 @@
public uint ColorBody { get; set; }
public uint ColorFace { get; set; }
public uint ColorLimb { get; set; }
public string CostumeData { get; set; } = string.Empty;
public string CostumeData { get; set; } = "[[],[],[],[],[]]";
public bool DisplayDan { get; set; }
public bool DisplayAchievement { get; set; }
public Difficulty AchievementDisplayDifficulty { get; set; }

View File

@ -28,7 +28,7 @@ builder.Services.AddDbContext<TaikoDbContext>(option =>
{
dbName = Constants.DEFAULT_DB_NAME;
}
var path = Path.Combine(PathHelper.GetDataPath(), dbName);
var path = Path.Combine(PathHelper.GetRootPath(), dbName);
option.UseSqlite($"Data Source={path}");
});
builder.Services.AddHttpLogging(options =>

View File

@ -17,4 +17,6 @@ public interface IUserDatumService
public Task<List<uint>> GetFavoriteSongIds(uint baid);
public Task UpdateFavoriteSong(uint baid, uint songId, bool isFavorite);
}

View File

@ -35,10 +35,10 @@
</ItemGroup>
<ItemGroup>
<Content Update="wwwroot\dan_data.json">
<Content Update="wwwroot\data\music_attribute.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\data\music_attribute.json">
<Content Update="wwwroot\data\dan_data.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

View File

@ -90,6 +90,31 @@
</MudGrid>
</MudStack>
</MudPaper>
<MudPaper Class="py-8 px-8 my-8" Outlined="true">
<MudStack Spacing="4">
<MudText Typo="Typo.h2">Costume Options</MudText>
<MudGrid>
<MudItem xs="12" md="4">
<MudStack Spacing="4">
<MudTextField @bind-Value="@response.Kigurumi" Label="Kigurumi"/>
<MudTextField @bind-Value="@response.Head" Label="Head"/>
<MudTextField @bind-Value="@response.Face" Label="Face"/>
<MudTextField @bind-Value="@response.Body" Label="Body"/>
<MudTextField @bind-Value="@response.Puchi" Label="Puchi"/>
</MudStack>
</MudItem>
<MudItem xs="12" md="4">
<MudStack Spacing="4">
<MudTextField @bind-Value="@response.BodyColor" Label="BodyColor"/>
<MudTextField @bind-Value="@response.FaceColor" Label="FaceColor"/>
<MudTextField @bind-Value="@response.LimbColor" Label="LimbColor"/>
</MudStack>
</MudItem>
</MudGrid>
</MudStack>
</MudPaper>
</MudItem>
<MudItem md="4" xs="12" Class="py-8 px-8 my-4 pt-8">
<MudStack Spacing="4" Style="top:100px" Class="sticky">