Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

240 map list #242

Merged
merged 58 commits into from
Jun 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
efd6b7c
initial
snixtho Jan 2, 2024
bb7d777
implement async deque
snixtho Jan 3, 2024
a41f9f6
implement queue controller
snixtho Jan 3, 2024
c25dbcf
Add container and panel ML components.
snixtho Jan 5, 2024
0c56550
add border to panel
snixtho Jan 5, 2024
b363a64
convert opacity based on 4-byte color
snixtho Jan 15, 2024
0df0e3b
add chip
snixtho Jan 16, 2024
e799aa5
separator
snixtho Jan 16, 2024
7d1d6e9
add placeholder for textinput
snixtho Jan 24, 2024
0ca5557
smol save
snixtho Jan 27, 2024
e6d67d7
adfg
snixtho Feb 7, 2024
7c6fde9
map list module project file
snixtho Feb 8, 2024
541607c
local save
snixtho Feb 9, 2024
0be57df
changes
snixtho Feb 16, 2024
22b665e
map row tweaks
snixtho Feb 29, 2024
ff584be
basic scrollbar
snixtho Mar 4, 2024
67c5bea
scrollbar can now control the scrolling element
snixtho Mar 5, 2024
2d4302e
fix relative drag position of scrollbar
snixtho Mar 5, 2024
d2735df
begin using map data objects
snixtho Mar 5, 2024
d6a8218
actually show the current map list
snixtho Mar 7, 2024
91ab4f0
save map details to db
snixtho Mar 12, 2024
5f99ddc
Optimize GetCurrentMapListAsync
snixtho Mar 14, 2024
82e6971
Add ability to queue maps from the maplist.
snixtho Mar 14, 2024
10a0cda
add widget prototype with new style
snixtho Apr 12, 2024
13ee3f2
starting new style
snixtho Apr 18, 2024
ec217ba
new button and dropdown
snixtho May 14, 2024
ad22b40
text input
snixtho May 15, 2024
03e85c8
huh
snixtho May 15, 2024
ec85050
alert
snixtho May 15, 2024
af259f7
updated checkbox
snixtho May 15, 2024
8d2cca8
update radiobutton
snixtho May 15, 2024
fe7bcec
some fixes and improvements
snixtho May 15, 2024
8425e08
switch
snixtho May 15, 2024
b40c669
update window
snixtho May 15, 2024
567ce95
fix tags
snixtho May 15, 2024
239e507
fix chip
snixtho May 17, 2024
4777533
fix rating
snixtho May 17, 2024
dcc2b69
fix link button
snixtho May 17, 2024
cd581b7
fix separator
snixtho May 17, 2024
ffef7ab
add utility colors to the ui demo
snixtho May 17, 2024
a07cf0d
add round buttons
snixtho May 17, 2024
1995103
separate namespace for containers
snixtho May 17, 2024
fff2743
add some breathing room for window icon
snixtho May 17, 2024
70e5d0a
make simple maplist ui
snixtho May 17, 2024
21116f7
add close button back to windows
snixtho May 18, 2024
163b634
documentation for components
snixtho May 18, 2024
99b159e
add confirmation dialog
snixtho May 29, 2024
82dafb8
refactoring
snixtho May 29, 2024
a523b03
Some refactoring and dont display delete button if user don't have pe…
snixtho May 30, 2024
8675218
comments and test fixing
snixtho May 30, 2024
2633e53
fix AsyncDeque tests
snixtho May 30, 2024
2ff59ec
add tests for map queue module
snixtho Jun 1, 2024
bbf20e1
map list service tests
snixtho Jun 1, 2024
f0a667b
maplist controller tests
snixtho Jun 1, 2024
2408dcc
remove unused imports
snixtho Jun 1, 2024
bff967d
fix sonarcloud issues
snixtho Jun 1, 2024
db14b66
fix review issues
snixtho Jun 2, 2024
0a33278
more fixes
snixtho Jun 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions EvoSC.sln
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,17 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModuleManagerModule", "src\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatchTrackerModule.Tests", "tests\Modules\MatchTrackerModule.Tests\MatchTrackerModule.Tests.csproj", "{9EF4D340-0C49-4A15-9BCF-6CD9508AA7DE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapQueueModule", "src/Modules/MapQueueModule/MapQueueModule.csproj", "{28C14D85-DD8A-4933-A0A0-B655682B5D02}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapQueueModuleTests", "tests\Modules\MapQueueModuleTests\MapQueueModuleTests.csproj", "{2D2D3AC6-C8BD-4615-BCC7-9A64007DB762}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapListModule", "src\Modules\MapListModule\MapListModule.csproj", "{AB316816-F301-4693-86E8-C31E78F53A59}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapListModule.Tests", "tests\Modules\MapListModule.Tests\MapListModule.Tests.csproj", "{098D1F9B-054D-4158-BB6C-AC908C4595F6}"
EndProject






Expand Down Expand Up @@ -303,6 +314,22 @@ Global
{9EF4D340-0C49-4A15-9BCF-6CD9508AA7DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9EF4D340-0C49-4A15-9BCF-6CD9508AA7DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9EF4D340-0C49-4A15-9BCF-6CD9508AA7DE}.Release|Any CPU.Build.0 = Release|Any CPU
{28C14D85-DD8A-4933-A0A0-B655682B5D02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{28C14D85-DD8A-4933-A0A0-B655682B5D02}.Debug|Any CPU.Build.0 = Debug|Any CPU
{28C14D85-DD8A-4933-A0A0-B655682B5D02}.Release|Any CPU.ActiveCfg = Release|Any CPU
{28C14D85-DD8A-4933-A0A0-B655682B5D02}.Release|Any CPU.Build.0 = Release|Any CPU
{2D2D3AC6-C8BD-4615-BCC7-9A64007DB762}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2D2D3AC6-C8BD-4615-BCC7-9A64007DB762}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2D2D3AC6-C8BD-4615-BCC7-9A64007DB762}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2D2D3AC6-C8BD-4615-BCC7-9A64007DB762}.Release|Any CPU.Build.0 = Release|Any CPU
{AB316816-F301-4693-86E8-C31E78F53A59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AB316816-F301-4693-86E8-C31E78F53A59}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AB316816-F301-4693-86E8-C31E78F53A59}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AB316816-F301-4693-86E8-C31E78F53A59}.Release|Any CPU.Build.0 = Release|Any CPU
{098D1F9B-054D-4158-BB6C-AC908C4595F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{098D1F9B-054D-4158-BB6C-AC908C4595F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{098D1F9B-054D-4158-BB6C-AC908C4595F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{098D1F9B-054D-4158-BB6C-AC908C4595F6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -351,5 +378,9 @@ Global
{42BCE01C-EBEF-4DB6-A61C-35B63C915AD3} = {6D75D6A2-6ECD-4DE4-96C5-CAD7D134407A}
{65F795D5-058D-4F8D-B8E0-BE3F64E14CDF} = {DC47658A-F421-4BA4-B617-090A7DFB3900}
{9EF4D340-0C49-4A15-9BCF-6CD9508AA7DE} = {6D75D6A2-6ECD-4DE4-96C5-CAD7D134407A}
{28C14D85-DD8A-4933-A0A0-B655682B5D02} = {DC47658A-F421-4BA4-B617-090A7DFB3900}
{2D2D3AC6-C8BD-4615-BCC7-9A64007DB762} = {6D75D6A2-6ECD-4DE4-96C5-CAD7D134407A}
{AB316816-F301-4693-86E8-C31E78F53A59} = {DC47658A-F421-4BA4-B617-090A7DFB3900}
{098D1F9B-054D-4158-BB6C-AC908C4595F6} = {6D75D6A2-6ECD-4DE4-96C5-CAD7D134407A}
EndGlobalSection
EndGlobal
8 changes: 4 additions & 4 deletions src/EvoSC.Commands/Middleware/CommandsMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ async Task HandleUserErrorsAsync(IParserResult result, string playerLogin)
}

var message = $"Error: {cmdParserException.Message}";
await serverClient.SendChatMessageAsync($"Error: {message}", playerLogin);
await serverClient.SendChatMessageAsync(playerLogin, $"Error: {message}");
}

if (result.Exception is PlayerNotFoundException playerNotFoundException)
{
await serverClient.SendChatMessageAsync($"Error: {playerNotFoundException.Message}", playerLogin);
await serverClient.SendChatMessageAsync(playerLogin, $"Error: {playerNotFoundException.Message}");
}
else
{
Expand Down Expand Up @@ -66,7 +66,7 @@ private async Task ExecuteCommandAsync(IChatCommand cmd, object[] args, ChatRout
}
finally
{
if (context.AuditEvent.Activated)
if (context.AuditEvent is { IsCanceled: false, Activated: true })
{
// allow actor to be manually set, so avoid overwrite
if (context.AuditEvent.Actor == null)
Expand All @@ -76,7 +76,7 @@ private async Task ExecuteCommandAsync(IChatCommand cmd, object[] args, ChatRout

await context.AuditEvent.LogAsync();
}
else if (cmd.Permission != null)
else if (!context.AuditEvent.IsCanceled && cmd.Permission != null)
{
logger.LogWarning("Command '{Name}' has permissions set but does not activate an audit", cmd.Name);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ await permissions.HasPermissionAsync(cmdContext.Player, cmdContext.CommandExecut
return;
}

await server.SendChatMessageAsync("Insufficient permissions to run this command.", cmdContext.Player);
await server.SendChatMessageAsync(cmdContext.Player, "Insufficient permissions to run this command.");
}
}
1 change: 0 additions & 1 deletion src/EvoSC.Common/Database/DbConnectionFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using EvoSC.Common.Database.Extensions;
using EvoSC.Common.Interfaces.Database;
using LinqToDB;
using LinqToDB.Configuration;
using LinqToDB.Data;
using Microsoft.Extensions.Logging;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using EvoSC.Common.Database.Models.Maps;
using FluentMigrator;

namespace EvoSC.Common.Database.Migrations;

[Tags("Production")]
[Migration(1710232879)]
public class AddMapDetailsTable : Migration
{
public override void Up()
{
Create.Table(DbMapDetails.TableName)
.WithColumn(nameof(DbMapDetails.MapId)).AsInt32().PrimaryKey()
.WithColumn(nameof(DbMapDetails.AuthorTime)).AsInt32()
.WithColumn(nameof(DbMapDetails.GoldTime)).AsInt32()
.WithColumn(nameof(DbMapDetails.SilverTime)).AsInt32()
.WithColumn(nameof(DbMapDetails.BronzeTime)).AsInt32()
.WithColumn(nameof(DbMapDetails.Environment)).AsString()
.WithColumn(nameof(DbMapDetails.Mood)).AsString()
.WithColumn(nameof(DbMapDetails.Cost)).AsInt32()
.WithColumn(nameof(DbMapDetails.MultiLap)).AsBoolean()
.WithColumn(nameof(DbMapDetails.LapCount)).AsInt32()
.WithColumn(nameof(DbMapDetails.MapStyle)).AsString()
.WithColumn(nameof(DbMapDetails.MapType)).AsString()
.WithColumn(nameof(DbMapDetails.CheckpointCount)).AsInt32();
}

public override void Down()
{
Delete.Table(nameof(DbMapDetails.TableName));
}
}
31 changes: 31 additions & 0 deletions src/EvoSC.Common/Database/Models/Maps/DbMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ public class DbMap : IMap

public IPlayer? Author => DbAuthor;

[Association(ThisKey = nameof(Id), OtherKey = nameof(DbMapDetails.MapId))]
public DbMapDetails? DbDetails { get; set; }

public IMapDetails? Details => DbDetails;

public DbMap(){}

public DbMap(IMap? map)
Expand All @@ -69,4 +74,30 @@ public DbMap(IMap? map)
DbAuthor = new DbPlayer(map.Author);
}

public bool Equals(IMap? other) => other != null && Uid.Equals(other.Uid, StringComparison.Ordinal);

public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}

if (ReferenceEquals(this, obj))
{
return true;
}

if (obj.GetType() != this.GetType())
{
return false;
}

return Equals((IMap)obj);
}

public override int GetHashCode()
{
return Uid.GetHashCode();
}
}
80 changes: 80 additions & 0 deletions src/EvoSC.Common/Database/Models/Maps/DbMapDetails.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using EvoSC.Common.Interfaces.Models;
using EvoSC.Common.Interfaces.Util;
using EvoSC.Common.Util;
using LinqToDB.Mapping;

namespace EvoSC.Common.Database.Models.Maps;

[Table(TableName)]
public class DbMapDetails : IMapDetails
{
public const string TableName = "MapDetails";

[Column(nameof(AuthorTime))]
public int DbAuthorTime { get; set; }

[Column(nameof(GoldTime))]
public int DbGoldTime { get; set; }

[Column(nameof(SilverTime))]
public int DbSilverTime { get; set; }

[Column(nameof(BronzeTime))]
public int DbBronzeTime { get; set; }

[Association(ThisKey = nameof(MapId), OtherKey = nameof(Maps.DbMap.Id))]
public DbMap DbMap { get; set; }

public IRaceTime AuthorTime
{
get { return RaceTime.FromMilliseconds(DbAuthorTime); }
set { DbAuthorTime = value.TotalMilliseconds; }
}

public IRaceTime GoldTime
{
get { return RaceTime.FromMilliseconds(DbGoldTime); }
set { DbGoldTime = value.TotalMilliseconds; }
}

public IRaceTime SilverTime
{
get { return RaceTime.FromMilliseconds(DbSilverTime); }
set { DbSilverTime = value.TotalMilliseconds; }
}

public IRaceTime BronzeTime
{
get { return RaceTime.FromMilliseconds(DbBronzeTime); }
set { DbBronzeTime = value.TotalMilliseconds; }
}

[PrimaryKey]
public int MapId { get; set; }

[Column]
public string Environment { get; set; }

[Column]
public string Mood { get; set; }

[Column]
public int Cost { get; set; }

[Column]
public bool MultiLap { get; set; }

[Column]
public int LapCount { get; set; }

[Column]
public string MapStyle { get; set; }

[Column]
public string MapType { get; set; }

[Column]
public int CheckpointCount { get; set; }

public IMap Map => DbMap;
}
3 changes: 1 addition & 2 deletions src/EvoSC.Common/Database/Repository/DbRepository.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

using EvoSC.Common.Interfaces.Database;
using EvoSC.Common.Interfaces.Database;
using LinqToDB;

namespace EvoSC.Common.Database.Repository;
Expand Down
52 changes: 49 additions & 3 deletions src/EvoSC.Common/Database/Repository/Maps/MapRepository.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using EvoSC.Common.Database.Models.Maps;
using System.Globalization;
using EvoSC.Common.Database.Models.Maps;
using EvoSC.Common.Database.Models.Player;
using EvoSC.Common.Exceptions.DatabaseExceptions;
using EvoSC.Common.Interfaces.Database;
Expand All @@ -15,16 +16,25 @@ public class MapRepository(IDbConnectionFactory dbConnFactory, ILogger<MapReposi
{
public async Task<IMap?> GetMapByIdAsync(long id) => await Table<DbMap>()
.LoadWith(t => t.DbAuthor)
.LoadWith(t => t.DbDetails)
.SingleOrDefaultAsync(m => m.Id == id);

public async Task<IMap?> GetMapByUidAsync(string uid) => await Table<DbMap>()
.LoadWith(t => t.DbAuthor)
.LoadWith(t => t.DbDetails)
.SingleOrDefaultAsync(m => m.Uid == uid);

public async Task<IMap?> GetMapByExternalIdAsync(string id) => await Table<DbMap>()
.LoadWith(t => t.DbAuthor)
.LoadWith(t => t.DbDetails)
.SingleOrDefaultAsync(m => m.ExternalId == id);


public async Task<IEnumerable<IMap>> GetMapsByUidAsync(IEnumerable<string> mapUids) => await Table<DbMap>()
.LoadWith(t => t.DbAuthor)
.LoadWith(t => t.DbDetails)
.Where(m => mapUids.Contains(m.Uid))
.ToArrayAsync();

public async Task<IMap> AddMapAsync(MapMetadata map, IPlayer author, string filePath)
{
var dbMap = new DbMap
Expand All @@ -47,7 +57,7 @@ public async Task<IMap> AddMapAsync(MapMetadata map, IPlayer author, string file
{
var id = await Database.InsertWithIdentityAsync(dbMap);
await transaction.CommitTransactionAsync();
dbMap.Id = Convert.ToInt64(id);
dbMap.Id = Convert.ToInt64(id, CultureInfo.InvariantCulture);
}
catch (Exception e)
{
Expand All @@ -59,6 +69,42 @@ public async Task<IMap> AddMapAsync(MapMetadata map, IPlayer author, string file
return dbMap;
}

public async Task<IMapDetails> AddMapDetailsAsync(IMapDetails mapDetails, IMap map)
{
var dbMapDetails = new DbMapDetails
{
AuthorTime = mapDetails.AuthorTime,
GoldTime = mapDetails.GoldTime,
SilverTime = mapDetails.SilverTime,
BronzeTime = mapDetails.BronzeTime,
MapId = (int)map.Id,
Environment = mapDetails.Environment,
Mood = mapDetails.Mood,
Cost = mapDetails.Cost,
MultiLap = mapDetails.MultiLap,
LapCount = mapDetails.LapCount,
MapStyle = mapDetails.MapStyle,
MapType = mapDetails.MapType,
CheckpointCount = mapDetails.CheckpointCount,
DbMap = new DbMap(map)
};

await using var transaction = await Database.BeginTransactionAsync();

try
{
await Database.InsertAsync(dbMapDetails);
}
catch (Exception ex)
{
logger.LogError(ex, "Failed adding map details for map ID {MapId}", map.Id);
await transaction.RollbackTransactionAsync();
throw new EvoScDatabaseException($"Failed adding map details for map ID {map.Id}");
}

return dbMapDetails;
}

public async Task<IMap> UpdateMapAsync(long mapId, MapMetadata map)
{
var updatedMap = new DbMap
Expand Down
3 changes: 2 additions & 1 deletion src/EvoSC.Common/EvoSC.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
<PackageReference Include="Config.Net" Version="5.1.5" />
<PackageReference Include="FluentMigrator" Version="3.3.2" />
<PackageReference Include="FluentMigrator.Runner" Version="3.3.2" />
<PackageReference Include="GBX.NET" Version="1.2.4" />
<PackageReference Include="GBX.NET" Version="1.2.6" />
<PackageReference Include="GBX.NET.LZO" Version="1.0.4" />
<PackageReference Include="GbxRemote.Net" Version="5.0.0" />
<PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="linq2db" Version="5.3.2" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ public interface IMapRepository
/// <param name="filePath">The filepath where the map is stored.</param>
/// <returns></returns>
public Task<IMap> AddMapAsync(MapMetadata map, IPlayer author, string filePath);

/// <summary>
/// Add details about a map to the database.
/// </summary>
/// <param name="mapDetails">Map details.</param>
/// <param name="map">Map associated with these details.</param>
/// <returns></returns>
public Task<IMapDetails> AddMapDetailsAsync(IMapDetails mapDetails, IMap map);

/// <summary>
/// Updates an already existing map.
Expand All @@ -50,5 +58,7 @@ public interface IMapRepository
/// Gets a map from the database based on the external provider ID.
/// </summary>
/// <returns></returns>
Task<IMap?> GetMapByExternalIdAsync(string id);
public Task<IMap?> GetMapByExternalIdAsync(string id);

public Task<IEnumerable<IMap>> GetMapsByUidAsync(IEnumerable<string> mapUids);
}
Loading
Loading