mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-07-28 07:58:40 +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]
|
[Fact]
|
||||||
public async Task ShouldReturnErrorOnNoPostData()
|
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);
|
Assert.False(response.IsSuccessStatusCode);
|
||||||
#if NET6_0_OR_GREATER
|
#if NET6_0_OR_GREATER
|
||||||
Assert.True(response.StatusCode == HttpStatusCode.BadRequest);
|
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/=PCKS/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Swingy/@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/=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/=UCAS/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=unfavourite/@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>
|
<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.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
|
using LBPUnion.ProjectLighthouse.Serialization;
|
||||||
using LBPUnion.ProjectLighthouse.Types;
|
using LBPUnion.ProjectLighthouse.Types;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
@ -30,10 +35,91 @@ namespace LBPUnion.ProjectLighthouse.Controllers
|
||||||
|
|
||||||
score.SlotId = id;
|
score.SlotId = id;
|
||||||
|
|
||||||
|
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);
|
this.database.Scores.Add(score);
|
||||||
|
}
|
||||||
await this.database.SaveChangesAsync();
|
await this.database.SaveChangesAsync();
|
||||||
|
|
||||||
return this.Ok();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,10 +9,7 @@ namespace LBPUnion.ProjectLighthouse.Helpers.Extensions
|
||||||
char[] invalidPathChars = Path.GetInvalidFileNameChars();
|
char[] invalidPathChars = Path.GetInvalidFileNameChars();
|
||||||
string path = text;
|
string path = text;
|
||||||
|
|
||||||
foreach (char c in invalidPathChars)
|
foreach (char c in invalidPathChars) path = path.Replace(c.ToString(), "");
|
||||||
{
|
|
||||||
path = path.Replace(c.ToString(), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ namespace LBPUnion.ProjectLighthouse.Logging
|
||||||
public class LighthouseFileLogger : LoggerBase
|
public class LighthouseFileLogger : LoggerBase
|
||||||
{
|
{
|
||||||
private static readonly string logsDirectory = Path.Combine(Environment.CurrentDirectory, "logs");
|
private static readonly string logsDirectory = Path.Combine(Environment.CurrentDirectory, "logs");
|
||||||
|
public override bool AllowMultiple => false;
|
||||||
|
|
||||||
public override void Send(LoggerLine line)
|
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, line.LoggerLevel.Name.ToFileName() + ".log"), contentFile);
|
||||||
File.AppendAllText(Path.Combine(logsDirectory, "all.log"), contentAll);
|
File.AppendAllText(Path.Combine(logsDirectory, "all.log"), contentAll);
|
||||||
}
|
}
|
||||||
public override bool AllowMultiple => false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,19 +8,19 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BCrypt.Net-Next" Version="4.0.2" />
|
<PackageReference Include="BCrypt.Net-Next" Version="4.0.2"/>
|
||||||
<PackageReference Include="Kettu" Version="1.2.0" />
|
<PackageReference Include="Kettu" Version="1.2.0"/>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="5.0.11" />
|
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="5.0.11"/>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.11" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.11"/>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.11">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.11">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="5.0.2" />
|
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="5.0.2"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="Types\SlotXsd.cs" />
|
<Compile Remove="Types\SlotXsd.cs"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</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, 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
|
public static string Elements
|
||||||
(params KeyValuePair<string, object>[] pairs)
|
(params KeyValuePair<string, object>[] pairs)
|
||||||
=> pairs.Aggregate(string.Empty, (current, pair) => current + StringElement(pair));
|
=> pairs.Aggregate(string.Empty, (current, pair) => current + StringElement(pair));
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
|
using LBPUnion.ProjectLighthouse.Serialization;
|
||||||
using LBPUnion.ProjectLighthouse.Types.Levels;
|
using LBPUnion.ProjectLighthouse.Types.Levels;
|
||||||
|
|
||||||
namespace LBPUnion.ProjectLighthouse.Types
|
namespace LBPUnion.ProjectLighthouse.Types
|
||||||
|
@ -33,7 +34,29 @@ namespace LBPUnion.ProjectLighthouse.Types
|
||||||
set => this.PlayerIdCollection = string.Join(',', value);
|
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")]
|
[XmlElement("score")]
|
||||||
public int Points { get; set; }
|
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