Skip to content

Commit

Permalink
Improve commands structure
Browse files Browse the repository at this point in the history
  • Loading branch information
MSWS committed Sep 1, 2024
1 parent 2c729fb commit 72273ca
Show file tree
Hide file tree
Showing 28 changed files with 288 additions and 75 deletions.
10 changes: 10 additions & 0 deletions Commands/CommandCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Microsoft.Extensions.DependencyInjection;
using GangsAPI.Extensions;

namespace Commands;

public static class CommandCollection {
public static void RegisterCommands(this IServiceCollection provider) {
provider.AddPluginBehavior<GangCommand>();
}
}
18 changes: 18 additions & 0 deletions Commands/Commands.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\GangsAPI\GangsAPI.csproj" />
<ProjectReference Include="..\GangsImpl\Mock\Mock.csproj" />
</ItemGroup>

</Project>
34 changes: 34 additions & 0 deletions Commands/GangCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using GangsAPI.Data;
using GangsAPI.Data.Command;
using GangsAPI.Services.Commands;
using Mock;

namespace Commands;

public class GangCommand : ICommand {
public string Name => "css_gang";
public string? Description => "Master command for gangs";

private Dictionary<string, ICommand> sub = new() {
// ["create"] = new CreateGangCommand(),
// ["delete"] = new DeleteGangCommand(),
// ["invite"] = new InviteGangCommand(),
// ["kick"] = new KickGangCommand(),
// ["leave"] = new LeaveGangCommand(),
// ["list"] = new ListGangCommand(),
// ["promote"] = new PromoteGangCommand(),
// ["demote"] = new DemoteGangCommand(),
// ["info"] = new InfoGangCommand()
};

public CommandResult
Execute(PlayerWrapper? executor, CommandInfoWrapper info) {
if (info.ArgCount == 0) return CommandResult.FAILURE;
if (!sub.TryGetValue(info[0], out var command)) {
// print usage
return CommandResult.INVALID_ARGS;
}

return CommandResult.SUCCESS;
}
}
15 changes: 15 additions & 0 deletions Commands/gang/CreateCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using GangsAPI.Data;
using GangsAPI.Data.Command;
using GangsAPI.Services.Commands;

namespace Commands.gang;

public class CreateCommand : ICommand {
public string Name => "create";
public string? Description => "Creates a new gang";

public CommandResult
Execute(PlayerWrapper? executor, CommandInfoWrapper info) {
throw new NotImplementedException();
}
}
1 change: 1 addition & 0 deletions GangsPlugin/CS2Gangs.cs → Core/CS2Gangs.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Immutable;
using CounterStrikeSharp.API.Core;
using GangsAPI;
using GangsAPI.Services.Commands;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

Expand Down
5 changes: 1 addition & 4 deletions GangsPlugin/GangsPlugin.csproj → Core/Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Commands\Commands.csproj" />
<ProjectReference Include="..\GangsAPI\GangsAPI.csproj"/>
</ItemGroup>

Expand All @@ -16,8 +17,4 @@
<PackageReference Include="xunit" Version="2.9.0"/>
</ItemGroup>

<ItemGroup>
<Folder Include="Commands\" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
using CounterStrikeSharp.API.Core;
using Commands;
using CounterStrikeSharp.API.Core;
using GangsAPI;
using Microsoft.Extensions.DependencyInjection;

namespace GangsImpl;

public class GangServiceCollection : IPluginServiceCollection<IGangPlugin> {
public void ConfigureServices(IServiceCollection serviceCollection) { }
public void ConfigureServices(IServiceCollection serviceCollection) {
serviceCollection.RegisterCommands();
}
}
12 changes: 11 additions & 1 deletion Gangs.sln
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GangsAPI", "GangsAPI\GangsAPI.csproj", "{787D12D8-1310-4042-ADCE-102E517F269E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GangsPlugin", "GangsPlugin\GangsPlugin.csproj", "{3EA38296-9022-4874-8309-872388D884DE}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "Core\Core.csproj", "{3EA38296-9022-4874-8309-872388D884DE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GangsTest", "GangsTest\GangsTest.csproj", "{B1D1E7C7-BDF3-4238-9025-4FEB2B7DAB89}"
EndProject
Expand All @@ -16,6 +16,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GenericDB", "GangsImpl\Gene
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLite", "GangsImpl\SQLite\SQLite.csproj", "{5186EA9C-D2A4-4D70-8F52-0D6C7B6A61B6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CS2", "CS2", "{AC07CD29-5C9D-4AD1-99C7-01DABAB8D0EC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Commands", "Commands\Commands.csproj", "{C7DF1D47-8D2B-4651-98AB-AEEBE5860ECA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -50,11 +54,17 @@ Global
{5186EA9C-D2A4-4D70-8F52-0D6C7B6A61B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5186EA9C-D2A4-4D70-8F52-0D6C7B6A61B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5186EA9C-D2A4-4D70-8F52-0D6C7B6A61B6}.Release|Any CPU.Build.0 = Release|Any CPU
{C7DF1D47-8D2B-4651-98AB-AEEBE5860ECA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C7DF1D47-8D2B-4651-98AB-AEEBE5860ECA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C7DF1D47-8D2B-4651-98AB-AEEBE5860ECA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C7DF1D47-8D2B-4651-98AB-AEEBE5860ECA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{1899055E-62B8-4907-85A2-DFE22531729E} = {3AB7703F-880F-4A41-96EE-B891FA888C65}
{74B15261-4B12-4EF6-859A-E46B315E7DD3} = {3AB7703F-880F-4A41-96EE-B891FA888C65}
{5186EA9C-D2A4-4D70-8F52-0D6C7B6A61B6} = {3AB7703F-880F-4A41-96EE-B891FA888C65}
{140E1706-30E8-4440-AAA0-56E8DD32F054} = {3AB7703F-880F-4A41-96EE-B891FA888C65}
{3EA38296-9022-4874-8309-872388D884DE} = {AC07CD29-5C9D-4AD1-99C7-01DABAB8D0EC}
{C7DF1D47-8D2B-4651-98AB-AEEBE5860ECA} = {AC07CD29-5C9D-4AD1-99C7-01DABAB8D0EC}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,25 @@

namespace GangsAPI.Data;

public class CommandInfoWrapper(CCSPlayerController? executor,
public class CommandInfoWrapper(CCSPlayerController? executor, int offset = 0,
params string[] args) {
public readonly CCSPlayerController? CallingPlayer = executor;

public readonly CommandCallingContext CallingContext =
CommandCallingContext.Console;

public CommandInfoWrapper(CommandInfo info) : this(info.CallingPlayer,
info.ArgString.Split(" ")) {
public CommandInfoWrapper(CommandInfo info, int offset = 0) : this(
info.CallingPlayer, offset, info.ArgString.Split(" ")) {
CallingContext = info.CallingContext;
}

public int ArgCount => args.Length;
public string this[int index] => args[index];
public string ArgString => string.Join(' ', args);
public int ArgCount => args.Length - offset;
public string this[int index] => args[index + offset];

public string ArgString
=> string.Join(' ', GetCommandString.Split(' ').Skip(offset));

public string GetCommandString => string.Join(' ', args.Skip(offset));

public void ReplyToCommand(string message) {
if (CallingPlayer == null) {
Expand Down
5 changes: 5 additions & 0 deletions GangsAPI/Data/Command/CommandResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace GangsAPI.Data.Command;

public enum CommandResult {
SUCCESS, FAILURE, UNKNOWN_COMMAND, INVALID_ARGS, NO_PERMISSION
}
13 changes: 9 additions & 4 deletions GangsAPI/Data/PlayerWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,13 @@ public PlayerWrapper WithFlags(params string[] flags) {
throw new ArgumentException(
$"Expected flag ${flag} to contain a / character");

var domain = flag[..slashIndex];
var domain = flag[1..slashIndex];
var permission = flag[(slashIndex + 1)..];

if (permission.Length == 0)
throw new ArgumentException(
$"Expected flag ${flag} to contain a permission after / character");

if (!flagMap.TryGetValue(domain, out var map)) flagMap[domain] = map = [];

map.Add(permission);
Expand All @@ -69,11 +73,12 @@ public bool HasFlags(params string[] flags) {
throw new ArgumentException(
$"Expected flag ${flag} to contain a / character");

var domain = flag[..slashIndex];
var domain = flag[1..slashIndex];
var permission = flag[(slashIndex + 1)..];

if (!Data.Flags.TryGetValue(domain, out var map)) return false;
if (!map.Contains(permission)) return false;
if (!Data.Flags.TryGetValue(domain, out var perms)) return false;
if (perms.Contains("root")) return true;
if (!perms.Any(p => permission.StartsWith(p))) return false;
}

return true;
Expand Down
6 changes: 6 additions & 0 deletions GangsAPI/Data/Stat/IGangPerk.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace GangsAPI.Data.Stat;

public interface IGangPerk : IPerk {
void ApplyTo(int id);
void RevokedFrom(int id);
}
5 changes: 5 additions & 0 deletions GangsAPI/Data/Stat/IPerk.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace GangsAPI.Data.Stat;

public interface IPerk : IStat, IPluginBehavior {

}
6 changes: 6 additions & 0 deletions GangsAPI/Data/Stat/IPlayerPerk.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace GangsAPI.Data.Stat;

public interface IPlayerPerk : IPerk {
void ApplyTo(ulong steam);
void RevokedFrom(ulong steam);
}
1 change: 1 addition & 0 deletions GangsAPI/Permissions/IPermDictator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
/// </summary>
public interface IPermDictator : IPluginBehavior {
bool CanTarget(IGangRank source, IGangRank target);
IGangRank CreateRank(string name, int rank, IGangRank.Permissions perms = 0);
}
18 changes: 14 additions & 4 deletions GangsAPI/Services/Commands/ICommand.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
using GangsAPI.Data;
using GangsAPI.Data.Command;

namespace GangsAPI.Services.Commands;

public interface ICommand {
public interface ICommand : IPluginBehavior {
string Name { get; }
string? Description { get; }
string[] RequiredFlags { get; }
string[] RequiredGroups { get; }
bool Execute(PlayerWrapper? executor, CommandInfoWrapper info);
string[] RequiredFlags => [];
string[] RequiredGroups => [];

bool CanExecute(PlayerWrapper? executor) {
if (executor == null) return true;
if (RequiredFlags.Any(flag => !executor.HasFlags(flag))) return false;
if (RequiredGroups.Length == 0) return true;
return executor.Data != null
&& RequiredGroups.All(group => executor.Data.Groups.Contains(group));
}

CommandResult Execute(PlayerWrapper? executor, CommandInfoWrapper info);
}
3 changes: 2 additions & 1 deletion GangsAPI/Services/Commands/ICommandManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using GangsAPI.Data;
using GangsAPI.Data.Command;

namespace GangsAPI.Services.Commands;

Expand All @@ -24,5 +25,5 @@ public interface ICommandManager : IPluginBehavior {
/// <param name="executor"></param>
/// <param name="args"></param>
/// <returns>True if the command finished processing successfully.</returns>
bool ProcessCommand(PlayerWrapper? executor, params string[] args);
CommandResult ProcessCommand(PlayerWrapper? executor, params string[] args);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using GangsAPI.Data.Stat;

namespace GangsTest.GangBankTests;
namespace Mock;

public class MockBankStat : IGangStat<int> {
public string StatId => "gang_bank";
Expand Down
22 changes: 7 additions & 15 deletions GangsImpl/Mock/MockCommandManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using GangsAPI.Data;
using GangsAPI.Data.Command;
using GangsAPI.Services.Commands;

namespace Mock;
Expand All @@ -14,23 +15,14 @@ public bool UnregisterCommand(ICommand command) {
return commands.Remove(command.Name);
}

public bool ProcessCommand(PlayerWrapper? executor, string[] args) {
if (args.Length == 0) return false;
if (!commands.TryGetValue(args[0], out var command)) return false;
public CommandResult ProcessCommand(PlayerWrapper? executor, string[] args) {
if (args.Length == 0) return CommandResult.FAILURE;
if (!commands.TryGetValue(args[0], out var command))
return CommandResult.UNKNOWN_COMMAND;

if (executor == null)
return command.Execute(executor,
new CommandInfoWrapper(executor?.Player, args));

if (command.RequiredFlags.Any(flag => !executor.HasFlags(flag)))
return false;

foreach (var group in command.RequiredGroups) {
if (executor.Data == null) return false;
if (!executor.Data.Groups.Contains(group)) return false;
}
if (!command.CanExecute(executor)) return CommandResult.NO_PERMISSION;

return command.Execute(executor,
new CommandInfoWrapper(executor?.Player, args));
new CommandInfoWrapper(executor?.Player, args: args));
}
}
5 changes: 5 additions & 0 deletions GangsTest/API/CommandWrapperTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace GangsTest.API;

public class CommandWrapperTests {

}
Loading

0 comments on commit 72273ca

Please sign in to comment.