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

Small qol fixes #254

Merged
merged 9 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions src/EvoSC.CLI/CliManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ private async Task ExecuteHandlerAsync(ICliCommandInfo command, InvocationContex
var startupPipeline = new StartupPipeline(config);
startupPipeline.ServiceContainer.ConfigureServiceContainerForEvoSc();
startupPipeline.SetupBasePipeline(config);
startupPipeline.Services("CliContext", s => s.RegisterInstance<ICliContext>(new CliContext(context)));
startupPipeline.Services("Application", s => s.RegisterInstance<IEvoSCApplication>(this));

await startupPipeline.ExecuteAsync(command.RequiredFeatures
Expand Down
16 changes: 10 additions & 6 deletions src/EvoSC.CLI/CliStartup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ public static class CliStartup
public static void SetupBasePipeline(this IStartupPipeline pipeline, IEvoScBaseConfig config)
{
pipeline
// Set up service container
.Services(AppFeature.Config, s => s.RegisterInstance(config))
// Set up service container
.Services(AppFeature.Config, s =>
s.RegisterInstance(config)
, "CliContext")

.Services(AppFeature.Logging, s => s.AddEvoScLogging(config.Logging))

Expand Down Expand Up @@ -93,11 +95,12 @@ public static void SetupBasePipeline(this IStartupPipeline pipeline, IEvoScBaseC

.Services(AppFeature.Manialinks, s => s
.AddEvoScManialinks()
, "Logging", "Events", "PlayerManager", "ControllerManager", "ActionPipelines", "GbxRemoteClient", "ActionInitializeTemplates")
, "Logging", "Events", "PlayerManager", "ControllerManager", "ActionPipelines", "GbxRemoteClient",
"ActionInitializeTemplates")

.Services(AppFeature.Themes, s => s.AddEvoScThemes())
// initialization of features

// initialization of features
.Action("ActionMigrateDatabase", MigrateDatabase)

.Action("ActionInitializeEventManager", s => s
Expand All @@ -113,7 +116,8 @@ public static void SetupBasePipeline(this IStartupPipeline pipeline, IEvoScBaseC
, "ActionInitializeEventManager", "ActionInitializePlayerCache")

.AsyncAction("InitializeGbxRemoteConnection", SetupGbxRemoteConnectionAsync
, "ActionInitializeEventManager", "ActionInitializePlayerCache", "ActionInitializeManialinkInteractionHandler")
, "ActionInitializeEventManager", "ActionInitializePlayerCache",
"ActionInitializeManialinkInteractionHandler")

.AsyncAction("ActionInitializeTemplates", InitializeTemplatesAsync);
}
Expand Down
8 changes: 8 additions & 0 deletions src/EvoSC.CLI/Interfaces/ICliContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.CommandLine.Invocation;

namespace EvoSC.CLI.Interfaces;

public interface ICliContext
{
public InvocationContext Context { get; }
}
9 changes: 9 additions & 0 deletions src/EvoSC.CLI/Models/CliContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.CommandLine.Invocation;
using EvoSC.CLI.Interfaces;

namespace EvoSC.CLI.Models;

public class CliContext(InvocationContext context) : ICliContext
{
public InvocationContext Context { get; } = context;
}
2 changes: 1 addition & 1 deletion src/EvoSC.Common/Application/AppFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,5 +121,5 @@ public enum AppFeature
/// Add, remove and manage themes using the theme manager.
/// </summary>
[Identifier(NoPrefix = true)]
Themes
Themes,
}
2 changes: 1 addition & 1 deletion src/EvoSC.Common/Config/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static IEvoScBaseConfig GetBaseConfig(string configFile, Dictionary<strin
ConfigMapper.SetupDefaultMappers();

var baseConfig = new ConfigurationBuilder<IEvoScBaseConfig>()
.UseEvoScConfig(MainConfigFile, cliOptions)
.UseEvoScConfig(configFile, cliOptions)
.UseTypeParser(new TextColorTypeParser())
.UseTypeParser(new VersionParser())
.UseTypeParser(new ThemeOptionsParser())
Expand Down
4 changes: 4 additions & 0 deletions src/EvoSC.Common/Database/Models/Player/DbPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public class DbPlayer : IPlayer
public string? Zone { get; set; }

public IPlayerSettings Settings => DbSettings;
public IEnumerable<IGroup> Groups { get; set; }
public IGroup? DisplayGroup { get; set; }

[Association(ThisKey = nameof(Id), OtherKey = nameof(DbPlayerSettings.PlayerId))]
public DbPlayerSettings DbSettings { get; set; }
Expand All @@ -64,6 +66,8 @@ public DbPlayer(IPlayer? player)
NickName = player.NickName;
UbisoftName = player.UbisoftName;
Zone = player.Zone;
Groups = player.Groups;
DisplayGroup = player.DisplayGroup;
}

public bool Equals(IPlayer? other) => other != null && AccountId.Equals(other.AccountId, StringComparison.Ordinal);
Expand Down
35 changes: 29 additions & 6 deletions src/EvoSC.Common/Database/Repository/Players/PlayerRepository.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Globalization;
using EvoSC.Common.Database.Models.Permissions;
using EvoSC.Common.Database.Models.Player;
using EvoSC.Common.Interfaces.Database;
using EvoSC.Common.Interfaces.Database.Repository;
Expand All @@ -8,11 +9,33 @@

namespace EvoSC.Common.Database.Repository.Players;

public class PlayerRepository(IDbConnectionFactory dbConnFactory) : DbRepository(dbConnFactory), IPlayerRepository
public class PlayerRepository(IDbConnectionFactory dbConnFactory, IPermissionRepository permissionRepository) : DbRepository(dbConnFactory), IPlayerRepository
{
public async Task<IPlayer?> GetPlayerByAccountIdAsync(string accountId) => await Table<DbPlayer>()
.LoadWith(p => p.DbSettings)
.SingleOrDefaultAsync(t => t.AccountId == accountId);
public async Task<DbPlayer?> GetPlayerByAccountIdAsync(string accountId)
{
var player = await Table<DbPlayer>()
.LoadWith(p => p.DbSettings)
.SingleOrDefaultAsync(t => t.AccountId == accountId);

if (player == null)
{
return null;
}

var groups = await permissionRepository.GetGroupsAsync(player.Id);
player.Groups = groups;

var displayGroup = await (
from g in Table<DbGroup>()
join ug in Table<DbUserGroup>() on g.Id equals ug.GroupId
where ug.UserId == player.Id && ug.Display
select g
).FirstOrDefaultAsync();

player.DisplayGroup = displayGroup;

return player;
}

public async Task<IPlayer> AddPlayerAsync(string accountId, TmPlayerDetailedInfo playerInfo)
{
Expand All @@ -23,7 +46,8 @@ public async Task<IPlayer> AddPlayerAsync(string accountId, TmPlayerDetailedInfo
AccountId = accountId.ToLower(CultureInfo.InvariantCulture),
NickName = playerInfo.NickName ?? accountId,
UbisoftName = playerInfo.NickName ?? accountId,
Zone = playerInfo.Path ?? "World"
Zone = playerInfo.Path ?? "World",
Groups = Array.Empty<IGroup>()
};

var id = await Database.InsertWithIdentityAsync(player);
Expand All @@ -33,7 +57,6 @@ public async Task<IPlayer> AddPlayerAsync(string accountId, TmPlayerDetailedInfo
{
PlayerId = player.Id,
DisplayLanguage = "en"

};

await Database.InsertAsync(playerSettings);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using EvoSC.Common.Interfaces.Models;
using EvoSC.Common.Database.Models.Player;
using EvoSC.Common.Interfaces.Models;
using GbxRemoteNet.Structs;

namespace EvoSC.Common.Interfaces.Database.Repository;
Expand All @@ -10,7 +11,7 @@ public interface IPlayerRepository
/// </summary>
/// <param name="accountId">The account ID of the player.</param>
/// <returns></returns>
public Task<IPlayer?> GetPlayerByAccountIdAsync(string accountId);
public Task<DbPlayer?> GetPlayerByAccountIdAsync(string accountId);

/// <summary>
/// Add a new player to the database.
Expand Down
3 changes: 3 additions & 0 deletions src/EvoSC.Common/Interfaces/Models/IPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,7 @@ public interface IPlayer : IEquatable<IPlayer>
public string? Zone { get; }

public IPlayerSettings Settings { get; }

public IEnumerable<IGroup> Groups { get; }
public IGroup? DisplayGroup { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ public interface IPlayerCacheService
public Task UpdatePlayerListAsync();

public Task UpdatePlayerAsync(IPlayer player);
public Task InvalidatePlayerStateAsync(IPlayer player);
}
4 changes: 4 additions & 0 deletions src/EvoSC.Common/Models/Players/OnlinePlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public class OnlinePlayer : IOnlinePlayer
public string UbisoftName { get; set; }
public string Zone { get; set; }
public IPlayerSettings Settings { get; set; }
public IEnumerable<IGroup> Groups { get; set; }
public IGroup? DisplayGroup { get; set; }
public required PlayerState State { get; set; }
public IPlayerFlags Flags { get; set; }
public PlayerTeam Team { get; set; }
Expand All @@ -25,6 +27,8 @@ public OnlinePlayer(IPlayer player)
UbisoftName = player.UbisoftName;
Zone = player.Zone;
Settings = player.Settings;
Groups = player.Groups;
DisplayGroup = player.DisplayGroup;
}

public bool Equals(IPlayer? other) => other != null && AccountId.Equals(other.AccountId, StringComparison.Ordinal);
Expand Down
4 changes: 4 additions & 0 deletions src/EvoSC.Common/Models/Players/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public class Player : IPlayer
public string UbisoftName { get; init; }
public string? Zone { get; init; }
public IPlayerSettings Settings { get; set; }
public IEnumerable<IGroup> Groups { get; set; }
public IGroup? DisplayGroup { get; set; }

public Player()
{
Expand All @@ -24,6 +26,8 @@ public Player(DbPlayer dbPlayer) : this()
UbisoftName = dbPlayer.UbisoftName;
Zone = dbPlayer.Zone;
Settings = dbPlayer.Settings;
Groups = dbPlayer.Groups;
DisplayGroup = dbPlayer.DisplayGroup;
}

public bool Equals(IPlayer? other) => other != null && AccountId.Equals(other.AccountId, StringComparison.Ordinal);
Expand Down
12 changes: 9 additions & 3 deletions src/EvoSC.Common/Permissions/PermissionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace EvoSC.Common.Permissions;

public class PermissionManager(IPermissionRepository permissionRepository) : IPermissionManager
public class PermissionManager(IPermissionRepository permissionRepository, IPlayerCacheService playerCache) : IPermissionManager
{
public async Task<bool> HasPermissionAsync(IPlayer player, string permission)
{
Expand Down Expand Up @@ -73,11 +73,17 @@ public async Task RemoveGroupAsync(int id)

public async Task<IGroup?> GetGroupAsync(int id) => await permissionRepository.GetGroupAsync(id);

public async Task AddPlayerToGroupAsync(IPlayer player, IGroup group) =>
public async Task AddPlayerToGroupAsync(IPlayer player, IGroup group)
{
await permissionRepository.AddPlayerToGroupAsync(player.Id, group.Id);
await playerCache.InvalidatePlayerStateAsync(player);
}

public async Task RemovePlayerFromGroupAsync(IPlayer player, IGroup group) =>
public async Task RemovePlayerFromGroupAsync(IPlayer player, IGroup group)
{
await permissionRepository.RemovePlayerFromGroupAsync(player.Id, group.Id);
await playerCache.InvalidatePlayerStateAsync(player);
}

public async Task AddPermissionToGroupAsync(IGroup group, IPermission permission) =>
await permissionRepository.AddPermissionToGroupAsync(group.Id, permission.Id);
Expand Down
2 changes: 1 addition & 1 deletion src/EvoSC.Common/Remote/ChatRouter/RemoteChatRouter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ private async Task HandlePlayerChatRoutingAsync(object sender, PlayerChatGbxEven
{
Task.Run(async () =>
{
var formatted = FormattingUtils.FormatPlayerChatMessage(chatContext.Player.NickName,
var formatted = FormattingUtils.FormatPlayerChatMessage(chatContext.Player,
chatContext.MessageText);
await _server.SendChatMessageAsync(formatted);
});
Expand Down
14 changes: 13 additions & 1 deletion src/EvoSC.Common/Services/PlayerCacheService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public class PlayerCacheService : IPlayerCacheService
private readonly ILogger<PlayerCacheService> _logger;
private readonly IPlayerRepository _playerRepository;


private readonly Dictionary<string, IOnlinePlayer> _onlinePlayers = new();
private readonly object _onlinePlayersMutex = new();

Expand Down Expand Up @@ -259,4 +258,17 @@ public async Task UpdatePlayerListAsync()
}

public Task UpdatePlayerAsync(IPlayer player) => ForceUpdatePlayerInternalAsync(player.AccountId);

public Task InvalidatePlayerStateAsync(IPlayer player)
{
lock (_onlinePlayersMutex)
{
if (_onlinePlayers.ContainsKey(player.AccountId))
{
_onlinePlayers.Remove(player.AccountId);
}
}

return Task.CompletedTask;
}
}
23 changes: 22 additions & 1 deletion src/EvoSC.Common/Themes/ThemeManager.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections;
using System.Reflection;
using EvoSC.Common.Config.Models;
using EvoSC.Common.Interfaces;
Expand Down Expand Up @@ -137,6 +138,26 @@ private dynamic GetCurrentThemeOptions()
themeOptions[option.Key] = option.Value;
}

// override any options set as an envi
foreach (DictionaryEntry enviObject in Environment.GetEnvironmentVariables())
{
var key = enviObject.Key as string;
if (key == null || enviObject.Value == null || !key.StartsWith("EVOSC_THEME_", StringComparison.Ordinal))
{
continue;
}

foreach (var option in themeOptions)
{
var enviKey = $"EVOSC_THEME_{option.Key.Replace('.', '_').ToUpper()}";

if (enviKey == key)
{
themeOptions[option.Key] = enviObject.Value;
}
}
}

_themeOptionsCache = themeOptions;
return themeOptions;
}
Expand All @@ -158,7 +179,7 @@ private Dictionary<string, object> GetConfigOverrideOptions()
var key = defaultOption.Key.StartsWith("Theme.", StringComparison.Ordinal)
? defaultOption.Key[6..]
: defaultOption.Key;

themeOptions[key] = defaultOption.Value;
}

Expand Down
15 changes: 11 additions & 4 deletions src/EvoSC.Common/Util/FormattingUtils.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.RegularExpressions;
using EvoSC.Common.Interfaces.Models;
using EvoSC.Common.Util.TextFormatting;

namespace EvoSC.Common.Util;
Expand Down Expand Up @@ -45,11 +46,17 @@ public static string FormatTimeAsDelta(int milliseconds)
return $"+ {s:0}.{ms:000}";
}

public static TextFormatter FormatPlayerChatMessage(string nickname, string message)
public static TextFormatter FormatPlayerChatMessage(IPlayer player, string message)
{
var formattedMessage = new TextFormatter()
.AddText("[")
.AddText(text => text.AddText(nickname))
var formattedMessage = new TextFormatter();

if (player.DisplayGroup?.Icon != null)
{
formattedMessage.AddText(player.DisplayGroup.Icon, s => s.WithColor(player.DisplayGroup.Color ?? "FFF"));
}

formattedMessage.AddText("[")
.AddText(text => text.AddText(player.NickName))
.AddText("] ")
.AddText(text => text.AddText(message));

Expand Down
7 changes: 5 additions & 2 deletions src/EvoSC.Testing/Database/DbTestHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using EvoSC.Common.Database.Repository.Players;
using EvoSC.Common.Database.Repository.Permissions;
using EvoSC.Common.Database.Repository.Players;
using EvoSC.Common.Interfaces.Database;
using EvoSC.Common.Interfaces.Models;
using GbxRemoteNet.Structs;
Expand All @@ -9,7 +10,9 @@ public static class DbTestHelper
{
public static async Task<IPlayer> AddTestPlayer(IDbConnectionFactory factory, string accountId)
{
var playerRepo = new PlayerRepository(factory);
var logger = TestLoggerSetup.CreateLogger<PermissionRepository>();
var permissionRepo = new PermissionRepository(factory, logger);
var playerRepo = new PlayerRepository(factory, permissionRepo);

return await playerRepo.AddPlayerAsync(accountId, new TmPlayerDetailedInfo
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Microsoft.Extensions.Logging;

namespace EvoSC.Common.Tests;
namespace EvoSC.Testing;

public static class LoggerSetup
public static class TestLoggerSetup
{
/// <summary>
/// Create a new logger.
Expand Down
Loading
Loading