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

add server management module with set password and slots commands #264

Merged
merged 1 commit into from
Aug 4, 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
15 changes: 15 additions & 0 deletions EvoSC.sln
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TeamSettingsModule.Tests",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ForceTeamModule.Tests", "tests\Modules\ForceTeamModule.Tests\ForceTeamModule.Tests.csproj", "{DE9532E8-F0ED-400B-9592-AF8F74BC83EB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerManagementModule", "src/Modules/ServerManagementModule/ServerManagementModule.csproj", "{AAE1AC39-4C4B-48A9-8B7B-08D2CD461FC1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerManagementModule.Tests", "tests\Modules\ServerManagementModule.Tests\ServerManagementModule.Tests.csproj", "{F8C7FE5E-B389-4BA8-B0DF-6D9D0A9B0949}"
EndProject




Expand Down Expand Up @@ -366,6 +371,14 @@ Global
{DE9532E8-F0ED-400B-9592-AF8F74BC83EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE9532E8-F0ED-400B-9592-AF8F74BC83EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE9532E8-F0ED-400B-9592-AF8F74BC83EB}.Release|Any CPU.Build.0 = Release|Any CPU
{AAE1AC39-4C4B-48A9-8B7B-08D2CD461FC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AAE1AC39-4C4B-48A9-8B7B-08D2CD461FC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AAE1AC39-4C4B-48A9-8B7B-08D2CD461FC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AAE1AC39-4C4B-48A9-8B7B-08D2CD461FC1}.Release|Any CPU.Build.0 = Release|Any CPU
{F8C7FE5E-B389-4BA8-B0DF-6D9D0A9B0949}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F8C7FE5E-B389-4BA8-B0DF-6D9D0A9B0949}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F8C7FE5E-B389-4BA8-B0DF-6D9D0A9B0949}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F8C7FE5E-B389-4BA8-B0DF-6D9D0A9B0949}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -424,5 +437,7 @@ Global
{C10A11E5-4AD8-4229-81F1-57D7DC364E27} = {DC47658A-F421-4BA4-B617-090A7DFB3900}
{B1745099-0081-4443-BF79-26A888765E16} = {6D75D6A2-6ECD-4DE4-96C5-CAD7D134407A}
{DE9532E8-F0ED-400B-9592-AF8F74BC83EB} = {6D75D6A2-6ECD-4DE4-96C5-CAD7D134407A}
{AAE1AC39-4C4B-48A9-8B7B-08D2CD461FC1} = {DC47658A-F421-4BA4-B617-090A7DFB3900}
{F8C7FE5E-B389-4BA8-B0DF-6D9D0A9B0949} = {6D75D6A2-6ECD-4DE4-96C5-CAD7D134407A}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
using EvoSC.Commands.Interfaces;
using EvoSC.Common.Interfaces;
using EvoSC.Common.Interfaces.Controllers;
using EvoSC.Common.Interfaces.Models;
using GbxRemoteNet.Interfaces;
using Moq;

namespace EvoSC.Testing.Controllers;

public class CommandInteractionControllerTestBase<TController> : ControllerMock<TController, ICommandInteractionContext>
where TController : class, IController
{
protected readonly (Mock<IServerClient> Client, Mock<IGbxRemoteClient> Remote) Server =
Mocking.NewServerClientMock();

/// <summary>
/// Initialize this controller mock.
/// </summary>
Expand All @@ -15,7 +21,7 @@ public class CommandInteractionControllerTestBase<TController> : ControllerMock<
protected void InitMock(IOnlinePlayer actor, params object[] services)
{
base.InitMock(services);
this.SetupMock(actor);
this.SetupMock(Server.Client, actor);
}
}

14 changes: 8 additions & 6 deletions src/EvoSC.Testing/Mocking.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ public static ControllerContextMock<TContext> NewControllerContextMock<TContext>
/// <param name="actor">The mocked actor that triggered this action.</param>
/// <returns></returns>
public static ControllerContextMock<IPlayerInteractionContext> SetupMock(
this ControllerContextMock<IPlayerInteractionContext> mock, IOnlinePlayer actor)
this ControllerContextMock<IPlayerInteractionContext> mock, Mock<IServerClient> serverClient, IOnlinePlayer actor)
{
mock.Context.Setup(c => c.Player).Returns(actor);
mock.Context.Setup(c => c.Server).Returns(serverClient.Object);
mock.Context.Object.AuditEvent.CausedBy(actor);

return mock;
Expand All @@ -50,8 +51,8 @@ public static ControllerContextMock<IPlayerInteractionContext> SetupMock(
/// <param name="actor">The mocked actor that triggered this action.</param>
/// <returns></returns>
public static ControllerContextMock<IPlayerInteractionContext>
NewPlayerInteractionContextMock(IOnlinePlayer actor) =>
new ControllerContextMock<IPlayerInteractionContext>().SetupMock(actor);
NewPlayerInteractionContextMock(Mock<IServerClient> serverClient, IOnlinePlayer actor) =>
new ControllerContextMock<IPlayerInteractionContext>().SetupMock(serverClient, actor);

/// <summary>
/// Set up a command interaction context mock.
Expand All @@ -60,9 +61,10 @@ public static ControllerContextMock<IPlayerInteractionContext>
/// <param name="actor">The mocked actor that triggered this command.</param>
/// <returns></returns>
public static ControllerContextMock<ICommandInteractionContext> SetupMock(
this ControllerContextMock<ICommandInteractionContext> mock, IOnlinePlayer actor)
this ControllerContextMock<ICommandInteractionContext> mock, Mock<IServerClient> serverClient, IOnlinePlayer actor)
{
mock.Context.Setup(c => c.Player).Returns(actor);
mock.Context.Setup(c => c.Server).Returns(serverClient.Object);
mock.Context.Object.AuditEvent.CausedBy(actor);

return mock;
Expand All @@ -74,8 +76,8 @@ public static ControllerContextMock<ICommandInteractionContext> SetupMock(
/// <param name="actor">The mocked actor that triggered this command.</param>
/// <returns></returns>
public static ControllerContextMock<ICommandInteractionContext>
NewCommandInteractionContextMock(IOnlinePlayer actor) =>
new ControllerContextMock<ICommandInteractionContext>().SetupMock(actor);
NewCommandInteractionContextMock(Mock<IServerClient> serverClient, IOnlinePlayer actor) =>
new ControllerContextMock<ICommandInteractionContext>().SetupMock(serverClient, actor);

/// <summary>
/// Set up a new Manialink context mock.
Expand Down
1 change: 1 addition & 0 deletions src/EvoSC/EvoSC.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
<ProjectReference Include="..\Modules\MapsModule\MapsModule.csproj" />
<ProjectReference Include="..\Modules\MatchManagerModule\MatchManagerModule.csproj" />
<ProjectReference Include="..\Modules\ASayModule\ASayModule.csproj" />
<ProjectReference Include="..\Modules\ServerManagementModule\ServerManagementModule.csproj" />
<ProjectReference Include="..\Modules\SpectatorTargetInfoModule\SpectatorTargetInfoModule.csproj" />
<ProjectReference Include="..\Modules\TeamSettingsModule\TeamSettingsModule.csproj" />
<ProjectReference Include="..\Modules\WorldRecordModule\WorldRecordModule.csproj" />
Expand Down
4 changes: 3 additions & 1 deletion src/EvoSC/InternalModules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using EvoSC.Modules.Official.Player;
using EvoSC.Modules.Official.PlayerRecords;
using EvoSC.Modules.Official.Scoreboard;
using EvoSC.Modules.Official.ServerManagementModule;
using EvoSC.Modules.Official.SetName;
using EvoSC.Modules.Official.SpectatorTargetInfoModule;
using EvoSC.Modules.Official.TeamSettingsModule;
Expand Down Expand Up @@ -55,7 +56,8 @@ public static class InternalModules
typeof(MapListModule),
typeof(LocalRecordsModule),
typeof(ForceTeamModule),
typeof(TeamSettingsModule)
typeof(TeamSettingsModule),
typeof(ServerManagementModule)
];

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using EvoSC.Commands.Attributes;
using EvoSC.Commands.Interfaces;
using EvoSC.Common.Controllers;
using EvoSC.Common.Controllers.Attributes;
using EvoSC.Modules.Official.ServerManagementModule.Events;
using EvoSC.Modules.Official.ServerManagementModule.Interfaces;
using EvoSC.Modules.Official.ServerManagementModule.Permissions;

namespace EvoSC.Modules.Official.ServerManagementModule.Controllers;

[Controller]
public class ServerCommandsController(IServerManagementService serverManagementService) : EvoScController<ICommandInteractionContext>
{
[ChatCommand("setpassword", "Set the player and spectator password for joining the server.",
ServerManagementPermissions.SetPassword)]
[CommandAlias("/setpw", true)]
public async Task SetServerPasswordAsync(string password)
{
await serverManagementService.SetPasswordAsync(password);

Context.AuditEvent
.WithEventName(ServerManagementAuditEvents.PasswordSet)
.HavingProperties(new { password })
.Success();

await Context.Server.SuccessMessageAsync(Context.Player, "The password was changed.");
}

[ChatCommand("clearpassword", "Clear the server password.",
ServerManagementPermissions.SetPassword)]
[CommandAlias("/clearpw", true)]
public async Task ClearServerPasswordAsync()
{
await serverManagementService.SetPasswordAsync("");

Context.AuditEvent
.WithEventName(ServerManagementAuditEvents.PasswordSet)
.HavingProperties(new { password = "", cleared = true })
.Success();

await Context.Server.SuccessMessageAsync(Context.Player, "The password was cleared and removed.");
}

[ChatCommand("setmaxplayers", "Set maximum number of players that can join the server.",
ServerManagementPermissions.SetMaxSlots)]
[CommandAlias("/maxplayers", true)]
public async Task SetMaxPlayersAsync(int maxPlayers)
{
await serverManagementService.SetMaxPlayersAsync(maxPlayers);

Context.AuditEvent
.WithEventName(ServerManagementAuditEvents.MaxPlayersSet)
.HavingProperties(new { maxPlayers })
.Success();

await Context.Server.SuccessMessageAsync(Context.Player, $"Max players set to {maxPlayers}");
}

[ChatCommand("setmaxspectators", "Set the maximum number of spectators that can join the server.",
ServerManagementPermissions.SetMaxSlots)]
[CommandAlias("/maxspectators", true)]
public async Task SetMaxSpectatorsAsync(int maxSpectators)
{
await serverManagementService.SetMaxSpectatorsAsync(maxSpectators);

Context.AuditEvent
.WithEventName(ServerManagementAuditEvents.MaxSpectatorsSet)
.HavingProperties(new { maxSpectators })
.Success();

await Context.Server.SuccessMessageAsync(Context.Player, $"Max spectators set to {maxSpectators}");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using EvoSC.Common.Events.Arguments;

namespace EvoSC.Modules.Official.ServerManagementModule.Events.Args;

public class PasswordChangedEventArgs : EvoScEventArgs
{
public string NewPassword { get; init; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using EvoSC.Common.Events.Arguments;

namespace EvoSC.Modules.Official.ServerManagementModule.Events.Args;

public class PlayerSlotsChangedEventArgs : EvoScEventArgs
{
public int NewSlots { get; init; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace EvoSC.Modules.Official.ServerManagementModule.Events;

public enum ServerManagementAuditEvents
{
PasswordSet,
MaxPlayersSet,
MaxSpectatorsSet
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace EvoSC.Modules.Official.ServerManagementModule.Events;

public enum ServerManagementEvents
{
PasswordChanged,
MaxPlayersChanged,
MaxSpectatorsChanged
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace EvoSC.Modules.Official.ServerManagementModule.Interfaces;

public interface IServerManagementService
{
public Task SetPasswordAsync(string password);
public Task SetMaxPlayersAsync(int maxPlayers);
public Task SetMaxSpectatorsAsync(int maxSpectators);
}
19 changes: 19 additions & 0 deletions src/Modules/ServerManagementModule/Localization.resx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
<xsd:element name="root" msdata:IsDataSet="true">
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using EvoSC.Common.Permissions.Attributes;

namespace EvoSC.Modules.Official.ServerManagementModule.Permissions;

[PermissionGroup]
public enum ServerManagementPermissions
{
SetPassword,
SetMaxSlots
}
6 changes: 6 additions & 0 deletions src/Modules/ServerManagementModule/ServerManagementModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using EvoSC.Modules.Attributes;

namespace EvoSC.Modules.Official.ServerManagementModule;

[Module(IsInternal = true)]
public class ServerManagementModule : EvoScModule;
25 changes: 25 additions & 0 deletions src/Modules/ServerManagementModule/ServerManagementModule.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>EvoSC.Modules.Official.ServerManagementModule</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyName>ServerManagementModule</AssemblyName>
<Title>Server Management</Title>
<Description>Commands and functions to manage server configuration such as password, player slots etc.</Description>
<Version>1.0.0</Version>
<Authors>Evo</Authors>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Templates\**\*" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Localization.resx" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../../EvoSC.Modules.SourceGeneration/EvoSC.Modules.SourceGeneration.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<ProjectReference Include="../../EvoSC.Modules/EvoSC.Modules.csproj" Private="true" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using EvoSC.Common.Interfaces;
using EvoSC.Common.Services.Attributes;
using EvoSC.Modules.Official.ServerManagementModule.Events;
using EvoSC.Modules.Official.ServerManagementModule.Events.Args;
using EvoSC.Modules.Official.ServerManagementModule.Interfaces;

namespace EvoSC.Modules.Official.ServerManagementModule.Services;

[Service]
public class ServerManagementService(IServerClient serverClient, IEventManager events) : IServerManagementService
{
public async Task SetPasswordAsync(string password)
{
await serverClient.Remote.SetServerPasswordAsync(password);
await serverClient.Remote.SetServerPasswordForSpectatorAsync(password);

await events.RaiseAsync(ServerManagementEvents.PasswordChanged,
new PasswordChangedEventArgs { NewPassword = password });
}

public async Task SetMaxPlayersAsync(int maxPlayers)
{
await serverClient.Remote.SetMaxPlayersAsync(maxPlayers);
await events.RaiseAsync(ServerManagementEvents.MaxPlayersChanged,
new PlayerSlotsChangedEventArgs() { NewSlots = maxPlayers });
}

public async Task SetMaxSpectatorsAsync(int maxSpectators)
{
await serverClient.Remote.SetMaxSpectatorsAsync(maxSpectators);
await events.RaiseAsync(ServerManagementEvents.MaxSpectatorsChanged,
new PlayerSlotsChangedEventArgs() { NewSlots = maxSpectators });
}
}
11 changes: 11 additions & 0 deletions src/Modules/ServerManagementModule/info.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[info]
# A unique name for this module, this is used as a identifier
name = "ServerManagementModule"
# The title of the module
title = "Server Management"
# A short description of what the module is and does
summary = "Commands and functions to manage server configuration such as password, player slots etc."
# The current version of this module, using SEMVER
version = "1.0.0"
# The name of the author that created this module
author = "Evo"
Loading
Loading