using EmbedIO; using EmbedIO.Routing; using EmbedIO.WebApi; using GCLocalServerRewrite.common; using GCLocalServerRewrite.models; using SharedProject.common; using SharedProject.enums; using SharedProject.models; using SQLite.Net2; using Swan.Logging; namespace GCLocalServerRewrite.controllers; public class ApiController : WebApiController { private readonly SQLiteConnection cardSqLiteConnection; private readonly Dictionary musics; private readonly Dictionary musicExtras; public ApiController() { cardSqLiteConnection = DatabaseHelper.ConnectDatabase(Configs.SETTINGS.CardDbName); var musicSqLiteConnection = DatabaseHelper.ConnectDatabase(Configs.SETTINGS.MusicDbName); musics = musicSqLiteConnection.Table().ToDictionary(music => music.MusicId); musicExtras = musicSqLiteConnection.Table().ToDictionary(music => music.MusicId); } [Route(HttpVerbs.Get, "/Users")] // ReSharper disable once UnusedMember.Global public List GetUsers() { var result = cardSqLiteConnection.Table().ToList().ConvertAll(card => new User { CardId = card.CardId, PlayerName = card.PlayerName }); return result; } [Route(HttpVerbs.Post, "/UserDetail/SetMusicFavorite")] // ReSharper disable once UnusedMember.Global public bool SetFavorite([JsonData] MusicFavoriteData data) { var existing = cardSqLiteConnection.Table() .Where(detail => detail.CardId == data.CardId && detail.Pcol1 == Configs.FAVORITE_PCOL1 && detail.Pcol2 == data.MusicId); if (!existing.Any()) { $"Trying to update non existing song's favorite! Card id {data.CardId}, music id {data.MusicId}".Warn(); return false; } var cardDetail = existing.First(); cardDetail.Fcol1 = data.IsFavorite ? 1 : 0; var result = cardSqLiteConnection.Update(cardDetail); return result == 1; } [Route(HttpVerbs.Post, "/UserDetail/SetPlayOption")] // ReSharper disable once UnusedMember.Global public bool SetPlayOption([JsonData] PlayOption data) { var existing = cardSqLiteConnection.Table() .Where(detail => detail.CardId == data.CardId && detail.Pcol1 == Configs.CONFIG_PCOL1 && detail.Pcol2 == Configs.CONFIG_PCOL2 && detail.Pcol3 == Configs.CONFIG_PCOL3); if (!existing.Any()) { $"Trying to update non existing card's config! Card id {data.CardId}".Warn(); return false; } var cardDetail = existing.First(); cardDetail.ScoreUi1 = (long)data.FastSlowIndicator; cardDetail.ScoreUi2 = (long)data.FeverTrance; var result = cardSqLiteConnection.Update(cardDetail); return result == 1; } [Route(HttpVerbs.Get, "/UserDetail/{cardId}")] // ReSharper disable once UnusedMember.Global public UserDetail? GetUserDetail(long cardId) { var cardResult = cardSqLiteConnection.Table().Where(card => card.CardId == cardId); if (!cardResult.Any()) { $"Getting detail for non exisisting card! Card id is {cardId}".Warn(); return null; } var card = cardResult.First(); return ToUserDetail(card); } private UserDetail ToUserDetail(Card card) { var userDetail = new UserDetail { CardId = card.CardId, PlayerName = card.PlayerName }; var songPlayDataDict = new Dictionary(); ProcessCardDetail(userDetail, songPlayDataDict); userDetail.SongPlayDataList = songPlayDataDict.Values.ToList(); userDetail.TotalSongCount = musics.Count; userDetail.TotalStageCount = userDetail.TotalSongCount * 3 + musicExtras.Count; userDetail.AverageScore = (int)(userDetail.TotalScore / userDetail.PlayedStageCount); userDetail.PlayedSongCount = songPlayDataDict.Count; return userDetail; } private void ProcessCardDetail(UserDetail userDetail, IDictionary songPlayDataDict) { var option = cardSqLiteConnection.Table() .FirstOrDefault(detail => detail.CardId == userDetail.CardId && detail.Pcol1 == Configs.CONFIG_PCOL1 && detail.Pcol2 == Configs.CONFIG_PCOL2 && detail.Pcol3 == Configs.CONFIG_PCOL3 , new CardDetail { CardId = userDetail.CardId }); SetOptions(option, userDetail); var songCounts = cardSqLiteConnection.Table() .Where(detail => detail.CardId == userDetail.CardId && detail.Pcol1 == Configs.COUNT_PCOL1); foreach (var detail in songCounts) { SetCounts(detail, songPlayDataDict, userDetail); } var songScores = cardSqLiteConnection.Table() .Where(detail => detail.CardId == userDetail.CardId && detail.Pcol1 == Configs.SCORE_PCOL1); foreach (var detail in songScores) { SetDetails(detail, songPlayDataDict, userDetail); } var favorites = cardSqLiteConnection.Table() .Where(detail => detail.CardId == userDetail.CardId && detail.Pcol1 == Configs.FAVORITE_PCOL1) .ToDictionary(detail => detail.Pcol2); foreach (var (musicId, songPlayData) in songPlayDataDict) { songPlayData.IsFavorite = favorites[musicId].Fcol1 != 0; } } private static void SetOptions(CardDetail cardDetail, UserDetail userDetail) { var fastSlow = (int)cardDetail.ScoreUi1; var feverTrance = (int)cardDetail.ScoreUi2; if (!Enum.IsDefined(typeof(PlayOptions.FastSlowIndicator), fastSlow)) { fastSlow = (int)PlayOptions.FastSlowIndicator.NotUsed; } if (!Enum.IsDefined(typeof(PlayOptions.FeverTranceShow), feverTrance)) { feverTrance = (int)PlayOptions.FeverTranceShow.Show; } userDetail.PlayOption = new PlayOption { CardId = cardDetail.CardId, FastSlowIndicator = (PlayOptions.FastSlowIndicator)fastSlow, FeverTrance = (PlayOptions.FeverTranceShow)feverTrance }; } private void SetDetails(CardDetail cardDetail, IDictionary songPlayDataDict, UserDetail userDetail) { var musicId = cardDetail.Pcol2; AddSongPlayDataIfNotExist(songPlayDataDict, musicId); for (var i = 0; i < SharedConstants.DIFFICULTY_COUNT; i++) { var songPlayDetailData = songPlayDataDict[musicId].SongPlaySubDataList[i]; songPlayDetailData.Difficulty = (Difficulty)i; if (i != cardDetail.Pcol3) { continue; } songPlayDetailData.Score = (int)cardDetail.ScoreUi1; songPlayDetailData.MaxChain = (int)cardDetail.ScoreUi3; userDetail.TotalScore += cardDetail.ScoreUi1; if (cardDetail.ScoreUi1 >= SharedConstants.S_SCORE_THRESHOLD) { userDetail.SAboveStageCount++; } if (cardDetail.ScoreUi1 >= SharedConstants.S_PLUS_SCORE_THRESHOLD) { userDetail.SPlusAboveStageCount++; } if (cardDetail.ScoreUi1 >= SharedConstants.S_PLUS_PLUS_SCORE_THRESHOLD) { userDetail.SPlusPlusAboveStageCount++; } } } private void SetCounts(CardDetail cardDetail, IDictionary songPlayDataDict, UserDetail userDetail) { var musicId = cardDetail.Pcol2; AddSongPlayDataIfNotExist(songPlayDataDict, musicId); for (var i = 0; i < SharedConstants.DIFFICULTY_COUNT; i++) { var songPlayDetailData = songPlayDataDict[musicId].SongPlaySubDataList[i]; songPlayDetailData.Difficulty = (Difficulty)i; if (i != cardDetail.Pcol3) { continue; } songPlayDetailData.PlayCount = (int)cardDetail.ScoreUi1; songPlayDetailData.ClearState = ClearState.Failed; userDetail.PlayedStageCount++; if (cardDetail.ScoreUi2 > 0) { userDetail.ClearedStageCount++; songPlayDetailData.ClearState = ClearState.Clear; } if (cardDetail.ScoreUi3 > 0) { userDetail.NoMissStageCount++; songPlayDetailData.ClearState = ClearState.NoMiss; } if (cardDetail.ScoreUi4 > 0) { userDetail.FullChainStageCount++; songPlayDetailData.ClearState = ClearState.FullChain; } if (cardDetail.ScoreUi6 > 0) { userDetail.PerfectStageCount++; songPlayDetailData.ClearState = ClearState.Perfect; } } } private void AddSongPlayDataIfNotExist(IDictionary songPlayDataDict, int musicId) { if (songPlayDataDict.ContainsKey(musicId)) { return; } var musicData = musics[musicId]; var songPlayData = new SongPlayData { Artist = musicData.Artist ?? string.Empty, Title = musicData.Title ?? string.Empty, MusicId = musicId, SongPlaySubDataList = new SongPlayDetailData[SharedConstants.DIFFICULTY_COUNT] }; for (var i = 0; i < SharedConstants.DIFFICULTY_COUNT; i++) { songPlayData.SongPlaySubDataList[i] = new SongPlayDetailData(); } songPlayDataDict[musicId] = songPlayData; } }