mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-07-24 14:11:29 +00:00
Merge pull request #37 from LumaLivy/main
Add support for grabbing Top Scores
This commit is contained in:
commit
582d2e2de0
8 changed files with 124 additions and 14 deletions
|
@ -12,7 +12,7 @@ namespace LBPUnion.ProjectLighthouse.Tests
|
|||
[Fact]
|
||||
public async Task ShouldReturnErrorOnNoPostData()
|
||||
{
|
||||
HttpResponseMessage response = await this.Client.PostAsync($"/LITTLEBIGPLANETPS3_XML/login", null!);
|
||||
HttpResponseMessage response = await this.Client.PostAsync("/LITTLEBIGPLANETPS3_XML/login", null!);
|
||||
Assert.False(response.IsSuccessStatusCode);
|
||||
#if NET6_0_OR_GREATER
|
||||
Assert.True(response.StatusCode == HttpStatusCode.BadRequest);
|
||||
|
|
|
@ -103,6 +103,7 @@
|
|||
<s:Boolean x:Key="/Default/UserDictionary/Words/=PCKS/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Swingy/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=thumbsup/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=topscores/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=UCAS/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=unfavourite/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Unpublish/@EntryIndexedValue">True</s:Boolean>
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
using LBPUnion.ProjectLighthouse.Serialization;
|
||||
using LBPUnion.ProjectLighthouse.Types;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
|
@ -30,10 +35,91 @@ namespace LBPUnion.ProjectLighthouse.Controllers
|
|||
|
||||
score.SlotId = id;
|
||||
|
||||
this.database.Scores.Add(score);
|
||||
IQueryable<Score> existingScore = this.database.Scores.Where(s => s.SlotId == score.SlotId && s.PlayerIdCollection == score.PlayerIdCollection);
|
||||
|
||||
if (existingScore.Any())
|
||||
{
|
||||
Score first = existingScore.First(s => s.SlotId == score.SlotId);
|
||||
score.ScoreId = first.ScoreId;
|
||||
score.Points = Math.Max(first.Points, score.Points);
|
||||
this.database.Entry(first).CurrentValues.SetValues(score);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.database.Scores.Add(score);
|
||||
}
|
||||
await this.database.SaveChangesAsync();
|
||||
|
||||
return this.Ok();
|
||||
}
|
||||
|
||||
[HttpGet("topscores/user/{slotId:int}/{type:int}")]
|
||||
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
|
||||
public async Task<IActionResult> TopScores(int slotId, int type, [FromQuery] int pageStart, [FromQuery] int pageSize)
|
||||
{
|
||||
// Get username
|
||||
User user = await this.database.UserFromRequest(this.Request);
|
||||
|
||||
// This is hella ugly but it technically assigns the proper rank to a score
|
||||
// var needed for Anonymous type returned from SELECT
|
||||
var rankedScores = this.database.Scores.Where(s => s.SlotId == slotId && s.Type == type)
|
||||
.OrderByDescending(s => s.Points)
|
||||
.ToList()
|
||||
.Select
|
||||
(
|
||||
(Score s, int rank) => new
|
||||
{
|
||||
Score = s,
|
||||
Rank = rank + 1,
|
||||
}
|
||||
);
|
||||
|
||||
// Find your score, since even if you aren't in the top list your score is pinned
|
||||
var myScore = rankedScores.Where
|
||||
(rs => rs.Score.PlayerIdCollection.Contains(user.Username))
|
||||
.OrderByDescending(rs => rs.Score.Points)
|
||||
.FirstOrDefault();
|
||||
|
||||
// Paginated viewing
|
||||
var pagedScores = rankedScores.Skip(pageStart - 1).Take(Math.Min(pageSize, 30));
|
||||
|
||||
string serializedScores = pagedScores.Aggregate
|
||||
(
|
||||
string.Empty,
|
||||
(current, rs) =>
|
||||
{
|
||||
rs.Score.Rank = rs.Rank;
|
||||
return current + rs.Score.Serialize();
|
||||
}
|
||||
);
|
||||
|
||||
string res;
|
||||
if (myScore == null)
|
||||
{
|
||||
res = LbpSerializer.StringElement("scores", serializedScores);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = LbpSerializer.TaggedStringElement
|
||||
(
|
||||
"scores",
|
||||
serializedScores,
|
||||
new Dictionary<string, object>()
|
||||
{
|
||||
{
|
||||
"yourScore", myScore.Score.Points
|
||||
},
|
||||
{
|
||||
"yourRank", myScore.Rank
|
||||
}, //This is the numerator of your position globally in the side menu.
|
||||
{
|
||||
"totalNumScores", rankedScores.Count()
|
||||
}, // This is the denominator of your position globally in the side menu.
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return this.Ok(res);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,11 +8,8 @@ namespace LBPUnion.ProjectLighthouse.Helpers.Extensions
|
|||
{
|
||||
char[] invalidPathChars = Path.GetInvalidFileNameChars();
|
||||
string path = text;
|
||||
|
||||
foreach (char c in invalidPathChars)
|
||||
{
|
||||
path = path.Replace(c.ToString(), "");
|
||||
}
|
||||
|
||||
foreach (char c in invalidPathChars) path = path.Replace(c.ToString(), "");
|
||||
|
||||
return path;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace LBPUnion.ProjectLighthouse.Logging
|
|||
public class LighthouseFileLogger : LoggerBase
|
||||
{
|
||||
private static readonly string logsDirectory = Path.Combine(Environment.CurrentDirectory, "logs");
|
||||
public override bool AllowMultiple => false;
|
||||
|
||||
public override void Send(LoggerLine line)
|
||||
{
|
||||
|
@ -22,6 +23,5 @@ namespace LBPUnion.ProjectLighthouse.Logging
|
|||
File.AppendAllText(Path.Combine(logsDirectory, line.LoggerLevel.Name.ToFileName() + ".log"), contentFile);
|
||||
File.AppendAllText(Path.Combine(logsDirectory, "all.log"), contentAll);
|
||||
}
|
||||
public override bool AllowMultiple => false;
|
||||
}
|
||||
}
|
|
@ -8,19 +8,19 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BCrypt.Net-Next" Version="4.0.2" />
|
||||
<PackageReference Include="Kettu" Version="1.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="5.0.11" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.11" />
|
||||
<PackageReference Include="BCrypt.Net-Next" Version="4.0.2"/>
|
||||
<PackageReference Include="Kettu" Version="1.2.0"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="5.0.11"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.11"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.11">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="5.0.2" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="5.0.2"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Types\SlotXsd.cs" />
|
||||
<Compile Remove="Types\SlotXsd.cs"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -26,6 +26,9 @@ namespace LBPUnion.ProjectLighthouse.Serialization
|
|||
|
||||
public static string TaggedStringElement(string key, object value, string tagKey, object tagValue) => $"<{key} {tagKey}=\"{tagValue}\">{value}</{key}>";
|
||||
|
||||
public static string TaggedStringElement(string key, object value, Dictionary<string, object> attrKeyValuePairs)
|
||||
=> $"<{key} " + attrKeyValuePairs.Aggregate(string.Empty, (current, kvp) => current + $"{kvp.Key}=\"{kvp.Value}\" ") + $">{value}</{key}>";
|
||||
|
||||
public static string Elements
|
||||
(params KeyValuePair<string, object>[] pairs)
|
||||
=> pairs.Aggregate(string.Empty, (current, pair) => current + StringElement(pair));
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Xml.Serialization;
|
||||
using LBPUnion.ProjectLighthouse.Serialization;
|
||||
using LBPUnion.ProjectLighthouse.Types.Levels;
|
||||
|
||||
namespace LBPUnion.ProjectLighthouse.Types
|
||||
|
@ -33,7 +34,29 @@ namespace LBPUnion.ProjectLighthouse.Types
|
|||
set => this.PlayerIdCollection = string.Join(',', value);
|
||||
}
|
||||
|
||||
[NotMapped]
|
||||
[XmlElement("mainPlayer")]
|
||||
public string MainPlayer {
|
||||
get => this.PlayerIds[0];
|
||||
set => this.PlayerIds[0] = value;
|
||||
}
|
||||
|
||||
[NotMapped]
|
||||
[XmlElement("rank")]
|
||||
public int Rank { get; set; }
|
||||
|
||||
[XmlElement("score")]
|
||||
public int Points { get; set; }
|
||||
|
||||
public string Serialize()
|
||||
{
|
||||
string score = LbpSerializer.StringElement("type", this.Type) +
|
||||
LbpSerializer.StringElement("playerIds", this.PlayerIdCollection) +
|
||||
LbpSerializer.StringElement("mainPlayer", this.MainPlayer) +
|
||||
LbpSerializer.StringElement("rank", this.Rank) +
|
||||
LbpSerializer.StringElement("score", this.Points);
|
||||
|
||||
return LbpSerializer.StringElement("playRecord", score);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue