Skip to content

Commit

Permalink
Local Records (#244)
Browse files Browse the repository at this point in the history
  • Loading branch information
snixtho authored Jun 30, 2024
1 parent a01520e commit 7c04e8c
Show file tree
Hide file tree
Showing 82 changed files with 2,267 additions and 208 deletions.
15 changes: 15 additions & 0 deletions EvoSC.sln
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapListModule", "src\Module
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapListModule.Tests", "tests\Modules\MapListModule.Tests\MapListModule.Tests.csproj", "{098D1F9B-054D-4158-BB6C-AC908C4595F6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalRecordsModule", "src/Modules/LocalRecordsModule/LocalRecordsModule.csproj", "{1D8DBFC8-EC21-4DDA-9D88-DE7CA04C8449}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalRecordsModule.Tests", "tests\Modules\LocalRecordsModule.Tests\LocalRecordsModule.Tests.csproj", "{7401429B-B842-4316-B7A2-B77E9AD966CB}"
EndProject




Expand Down Expand Up @@ -330,6 +335,14 @@ Global
{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
{1D8DBFC8-EC21-4DDA-9D88-DE7CA04C8449}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1D8DBFC8-EC21-4DDA-9D88-DE7CA04C8449}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1D8DBFC8-EC21-4DDA-9D88-DE7CA04C8449}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1D8DBFC8-EC21-4DDA-9D88-DE7CA04C8449}.Release|Any CPU.Build.0 = Release|Any CPU
{7401429B-B842-4316-B7A2-B77E9AD966CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7401429B-B842-4316-B7A2-B77E9AD966CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7401429B-B842-4316-B7A2-B77E9AD966CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7401429B-B842-4316-B7A2-B77E9AD966CB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -382,5 +395,7 @@ Global
{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}
{1D8DBFC8-EC21-4DDA-9D88-DE7CA04C8449} = {DC47658A-F421-4BA4-B617-090A7DFB3900}
{7401429B-B842-4316-B7A2-B77E9AD966CB} = {6D75D6A2-6ECD-4DE4-96C5-CAD7D134407A}
EndGlobalSection
EndGlobal
5 changes: 5 additions & 0 deletions src/EvoSC.Common/Database/Repository/Maps/MapRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public class MapRepository(IDbConnectionFactory dbConnFactory, ILogger<MapReposi
.LoadWith(t => t.DbDetails)
.SingleOrDefaultAsync(m => m.Id == id);

public async Task<IMap[]> GetMapsAsync() => await Table<DbMap>()
.LoadWith(m => m.DbAuthor)
.LoadWith(m => m.DbDetails)
.ToArrayAsync();

public async Task<IMap?> GetMapByUidAsync(string uid) => await Table<DbMap>()
.LoadWith(t => t.DbAuthor)
.LoadWith(t => t.DbDetails)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ public interface IMapRepository
/// <param name="id">The maps database ID.</param>
/// <returns>a map if it exists in the database.</returns>
public Task<IMap?> GetMapByIdAsync(long id);

/// <summary>
/// Get all maps in the database.
/// </summary>
/// <returns></returns>
public Task<IMap[]> GetMapsAsync();

/// <summary>
/// Gets a map from the database based on the provided UID.
Expand Down
6 changes: 6 additions & 0 deletions src/EvoSC.Common/Interfaces/Services/IMapService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,10 @@ public interface IMapService
/// <param name="map">Map to get details of.</param>
/// <returns></returns>
public Task<IMapDetails> FetchMapDetailsAsync(IMap map);

/// <summary>
/// Get all maps in the database.
/// </summary>
/// <returns></returns>
public Task<IMap[]> GetCurrentMapListAsync();
}
2 changes: 2 additions & 0 deletions src/EvoSC.Common/Services/MapService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ public async Task<IMapDetails> FetchMapDetailsAsync(IMap map)
}
}

public Task<IMap[]> GetCurrentMapListAsync() => mapRepository.GetMapsAsync();

private static bool MapVersionExistsInDb(IMap map, MapMetadata mapMetadata)
{
return map.ExternalVersion == mapMetadata.ExternalVersion;
Expand Down
4 changes: 2 additions & 2 deletions src/EvoSC.Common/Util/FormattingUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ public static TextFormatter FormatPlayerChatMessage(string nickname, string mess
{
var formattedMessage = new TextFormatter()
.AddText("[")
.AddText(text => text.AsIsolated().AddText(nickname))
.AddText(text => text.AddText(nickname))
.AddText("] ")
.AddText(text => text.AsIsolated().AddText(message));
.AddText(text => text.AddText(message));

return formattedMessage;
}
Expand Down
6 changes: 3 additions & 3 deletions src/EvoSC.Common/Util/TextFormatting/FormattedText.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace EvoSC.Common.Util.TextFormatting;
public class FormattedText
{
public TextStyling? Style { get; set; }
public bool IsIsolated { get; set; }
public bool IsIsolated { get; set; } = true;
public StringBuilder Text { get; set; } = new StringBuilder();

public FormattedText(){}
Expand Down Expand Up @@ -127,9 +127,9 @@ public FormattedText WithStyle(Action<TextStyling> styleAction)
/// interfere with later text.
/// </summary>
/// <returns></returns>
public FormattedText AsIsolated()
public FormattedText AsNotIsolated()
{
IsIsolated = true;
IsIsolated = false;
return this;
}

Expand Down
23 changes: 20 additions & 3 deletions src/EvoSC.Common/Util/TextFormatting/TextColor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,26 @@ public TextColor(Color color)

public TextColor(string hex)
{
this._r = byte.Parse(hex[0].ToString(), System.Globalization.NumberStyles.HexNumber);
this._g = byte.Parse(hex[1].ToString(), System.Globalization.NumberStyles.HexNumber);
this._b = byte.Parse(hex[2].ToString(), System.Globalization.NumberStyles.HexNumber);
if (hex.Length == 3)
{
this._r = byte.Parse(hex[0].ToString(), System.Globalization.NumberStyles.HexNumber);
this._g = byte.Parse(hex[1].ToString(), System.Globalization.NumberStyles.HexNumber);
this._b = byte.Parse(hex[2].ToString(), System.Globalization.NumberStyles.HexNumber);
}
else if (hex.Length >= 6)
{
var r = Math.Floor(byte.Parse(hex[0..2], NumberStyles.HexNumber) / 255.0 * 0xF);
var g = Math.Floor(byte.Parse(hex[2..4], NumberStyles.HexNumber) / 255.0 * 0xF);
var b = Math.Floor(byte.Parse(hex[4..6], NumberStyles.HexNumber) / 255.0 * 0xF);

this._r = (byte)r;
this._g = (byte)g;
this._b = (byte)b;
}
else
{
throw new FormatException("Invalid color code");
}
}

/// <summary>
Expand Down
11 changes: 11 additions & 0 deletions src/EvoSC.Common/Util/TextFormatting/TextStyling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ public TextStyling WithColor(TextColor color)
return this;
}

/// <summary>
/// Set the color of this style.
/// </summary>
/// <param name="color">The color to use.</param>
/// <returns></returns>
public TextStyling WithColor(string color)
{
_color = new TextColor(color);
return this;
}

/// <summary>
/// Set the color of this style.
/// </summary>
Expand Down
139 changes: 49 additions & 90 deletions src/EvoSC.Manialinks/Interfaces/IManialinkManager.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
using EvoSC.Common.Interfaces.Models;
using EvoSC.Manialinks.Interfaces.Models;
using EvoSC.Manialinks.Interfaces.Models;

namespace EvoSC.Manialinks.Interfaces;

/// <summary>
/// Manialink template & ManiaScript registry, and can render, display and hide Manialink to players.
/// </summary>
public interface IManialinkManager
public interface IManialinkManager : IManialinkOperations
{
/// <summary>
/// Add all the default templates from EvoSC.
Expand Down Expand Up @@ -54,27 +53,10 @@ public interface IManialinkManager
public void RemoveManiaScript(string name);

/// <summary>
/// Render a template and send it to all players.
/// </summary>
/// <param name="name">The name of the template.</param>
/// <param name="data">Any kind of data the template uses.</param>
/// <returns></returns>
public Task SendManialinkAsync(string name, IDictionary<string, object?> data);

/// <summary>
/// Render a template and send it to all players.
/// </summary>
/// <param name="name">The name of the template.</param>
/// <param name="data">Any kind of data the template uses.</param>
/// <returns></returns>
public Task SendManialinkAsync(string name, dynamic data);

/// <summary>
/// Render a template and send it to all players without data.
/// Pre-process all current templates registered.
/// </summary>
/// <param name="name">The name of the template.</param>
/// <returns></returns>
public Task SendManialinkAsync(string name);
public Task PreprocessAllAsync();

/// <summary>
/// Send a manialink to all players which persists even if a player re-connects.
Expand Down Expand Up @@ -103,105 +85,82 @@ public interface IManialinkManager
public Task SendPersistentManialinkAsync(string name);

/// <summary>
/// Render a template and send it to a specific player.
/// </summary>
/// <param name="player">The player to send to.</param>
/// <param name="name">The name of the template.</param>
/// <param name="data">Data which the template uses.</param>
/// <returns></returns>
public Task SendManialinkAsync(IPlayer player, string name, IDictionary<string, object?> data);

/// <summary>
/// Render a template and send it to a specific player.
/// Send a manialink to all players which persists even if a player re-connects.
/// It will also automatically show for new players.
///
/// This method allows for dynamic data updates by a callback method.
/// </summary>
/// <param name="player">The player to send to.</param>
/// <param name="name">The name of the template.</param>
/// <param name="data">Data which the template uses</param>
/// <param name="name">Name of the template to show.</param>
/// <param name="setupData">Method that returns data to be sent.</param>
/// <returns></returns>
public Task SendManialinkAsync(IPlayer player, string name, dynamic data);

public Task SendPersistentManialinkAsync(string name, Func<Task<dynamic>> setupData);
/// <summary>
/// Render a template and send it to a specific player.
/// Send a manialink to all players which persists even if a player re-connects.
/// It will also automatically show for new players.
///
/// This method allows for dynamic data updates by a callback method.
/// </summary>
/// <param name="playerLogin">The login to send to.</param>
/// <param name="name">The name of the template.</param>
/// <param name="data">Data which the template uses</param>
/// <param name="name">Name of the template to show.</param>
/// <param name="setupData">Method that returns data to be sent.</param>
/// <returns></returns>
public Task SendManialinkAsync(string playerLogin, string name, dynamic data);
public Task SendPersistentManialinkAsync(string name, Func<Task<IDictionary<string, object?>>> setupData);

/// <summary>
/// Render a template and send it to a specific player without data.
/// Hides and removes a persistent mainalink.
/// </summary>
/// <param name="player">The player to send to.</param>
/// <param name="name">The name of the template.</param>
/// <param name="name">Name of the template to hide.</param>
/// <returns></returns>
public Task SendManialinkAsync(IPlayer player, string name) => SendManialinkAsync(player, name, new { });
public Task RemovePersistentManialinkAsync(string name);

/// <summary>
/// Render a template and send it to a set of players.
/// Add a global variable that is accessible from all templates.
/// </summary>
/// <param name="players">The players to send to</param>
/// <param name="name">The name of the template.</param>
/// <param name="data">Data which the template uses</param>
/// <returns></returns>
public Task SendManialinkAsync(IEnumerable<IPlayer> players, string name, IDictionary<string, object?> data);
/// <param name="name">Name of the variable.</param>
/// <param name="value">Value of the variable.</param>
/// <typeparam name="T">Variable type.</typeparam>
public void AddGlobalVariable<T>(string name, T value);

/// <summary>
/// Render a template and send it to a set of players.
/// Remove a global variable.
/// </summary>
/// <param name="players">The players to send to</param>
/// <param name="name">The name of the template.</param>
/// <param name="data">Data which the template uses</param>
/// <returns></returns>
public Task SendManialinkAsync(IEnumerable<IPlayer> players, string name, dynamic data);
/// <param name="name">Name of the variable to remove.</param>
public void RemoveGlobalVariable(string name);

/// <summary>
/// Render a template and send it to a set of players without data.
/// Remove all global variables.
/// </summary>
/// <param name="players">The players to send to</param>
/// <param name="name">The name of the template.</param>
/// <returns></returns>
public Task SendManialinkAsync(IEnumerable<IPlayer> players, string name) =>
SendManialinkAsync(players, name, new { });
public void ClearGlobalVariables();

/// <summary>
/// Hide a manialink from all players.
/// Get the rendered contents of a template.
/// </summary>
/// <param name="name">Name of the manialink to hide.</param>
/// <param name="name">Name of the template.</param>
/// <param name="data">Data to send to the template.</param>
/// <returns></returns>
public Task HideManialinkAsync(string name);
public Task<string> PrepareAndRenderAsync(string name, IDictionary<string, object?> data);

/// <summary>
/// Hide a manialink from a player.
/// Get the rendered contents of a template.
/// </summary>
/// <param name="player">The player to hide the manialink from.</param>
/// <param name="name">Name of the manialink to hide.</param>
/// <param name="name">Name of the template.</param>
/// <param name="data">Data to send to the template.</param>
/// <returns></returns>
public Task HideManialinkAsync(IPlayer player, string name);
public Task<string> PrepareAndRenderAsync(string name, dynamic data);

/// <summary>
/// Hide a manialink from a player.
/// Get the effective name of a template's name. This may change
/// depending on the theme.
/// </summary>
/// <param name="playerLogin">The player to hide the manialink from.</param>
/// <param name="name">Name of the manialink to hide.</param>
/// <param name="name">Original name of the template.</param>
/// <returns></returns>
public Task HideManialinkAsync(string playerLogin, string name);

/// <summary>
/// Hide a manialink from a set of players.
/// </summary>
/// <param name="players">The players to hide the manialink from.</param>
/// <param name="name">Name of the manialink to hide.</param>
/// <returns></returns>
public Task HideManialinkAsync(IEnumerable<IPlayer> players, string name);

public string GetEffectiveName(string name);

/// <summary>
/// Pre-process all current templates registered.
/// Create a new transaction for manialink operations.
/// Nothing is done until the transaction is committed,
/// and all operations are sent at once for speed.
/// </summary>
/// <returns></returns>
public Task PreprocessAllAsync();

public void AddGlobalVariable<T>(string name, T value);
public void RemoveGlobalVariable(string name);
public void ClearGlobalVariables();
public IManialinkTransaction CreateTransaction();
}
Loading

0 comments on commit 7c04e8c

Please sign in to comment.