Skip to content

Commit

Permalink
[Exiled::Events] Added new commands for installing plugins, changin…
Browse files Browse the repository at this point in the history
…g or printing config values (#2389)

* new commands

* hgh

* fixes

* displaying verified plugins

* fixes

* final fix

---------

Co-authored-by: Yamato <[email protected]>
Co-authored-by: Vladislav Popovič <[email protected]>
  • Loading branch information
3 people authored Jun 23, 2024
1 parent 5f90618 commit 7ebbd79
Show file tree
Hide file tree
Showing 9 changed files with 601 additions and 2 deletions.
25 changes: 25 additions & 0 deletions Exiled.API/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,31 @@ public static string ToSnakeCase(this string str, bool shouldReplaceSpecialChars
return shouldReplaceSpecialChars ? Regex.Replace(snakeCaseString, @"[^0-9a-zA-Z_]+", string.Empty) : snakeCaseString;
}

/// <summary>
/// Converts a <see cref="string"/> from snake_case convention.
/// </summary>
/// <param name="str">The string to be converted.</param>
/// <returns>Returns the new NotSnakeCase string.</returns>
public static string FromSnakeCase(this string str)
{
string result = string.Empty;

for (int i = 0; i < str.Length; i++)
{
if (str[i] == '_')
{
result += str[i + 1].ToString().ToUpper();
i++;
}
else
{
result += str[i];
}
}

return result;
}

/// <summary>
/// Converts an <see cref="IEnumerable{T}"/> into a string.
/// </summary>
Expand Down
52 changes: 52 additions & 0 deletions Exiled.Events/Commands/ConfigValue/ConfigValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// -----------------------------------------------------------------------
// <copyright file="ConfigValue.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

namespace Exiled.Events.Commands.ConfigValue
{
using System;

using CommandSystem;

/// <summary>
/// The config value command.
/// </summary>
[CommandHandler(typeof(RemoteAdminCommandHandler))]
[CommandHandler(typeof(GameConsoleCommandHandler))]
public class ConfigValue : ParentCommand
{
/// <summary>
/// Initializes a new instance of the <see cref="ConfigValue"/> class.
/// </summary>
public ConfigValue()
{
LoadGeneratedCommands();
}

/// <inheritdoc/>
public override string Command { get; } = "config_value";

/// <inheritdoc/>
public override string[] Aliases { get; } = { "value", "cv", "cfgval" };

/// <inheritdoc/>
public override string Description { get; } = "Gets or sets a config value";

/// <inheritdoc/>
public override void LoadGeneratedCommands()
{
RegisterCommand(Get.Instance);
RegisterCommand(Set.Instance);
}

/// <inheritdoc/>
protected override bool ExecuteParent(ArraySegment<string> arguments, ICommandSender sender, out string response)
{
response = "Please, specify a valid subcommand! Available ones: get, set";
return false;
}
}
}
88 changes: 88 additions & 0 deletions Exiled.Events/Commands/ConfigValue/Get.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// -----------------------------------------------------------------------
// <copyright file="Get.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

namespace Exiled.Events.Commands.ConfigValue
{
using System;
using System.Linq;
using System.Reflection;

using CommandSystem;
using Exiled.API.Extensions;
using Exiled.API.Interfaces;
using Exiled.Permissions.Extensions;
using RemoteAdmin;

/// <summary>
/// The command to get config value.
/// </summary>
public class Get : ICommand
{
/// <summary>
/// Gets a static instance of <see cref="Get"/> class.
/// </summary>
public static Get Instance { get; } = new();

/// <inheritdoc/>
public string Command { get; } = "get";

/// <inheritdoc/>
public string[] Aliases { get; } = { "print" };

/// <inheritdoc/>
public string Description { get; } = "Gets a config value";

/// <inheritdoc/>
public bool SanitizeResponse { get; }

/// <inheritdoc/>
public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response)
{
const string perm = "cv.get";

if (!sender.CheckPermission(perm) && sender is PlayerCommandSender playerSender && !playerSender.FullPermissions)
{
response = $"You can't get a config value, you don't have \"{perm}\" permissions.";
return false;
}

if (arguments.Count != 1)
{
response = "Please, use: cv get PluginName.ValueName";
return false;
}

string[] args = arguments.At(0).Split('.');

string pluginName = args[0];
string propertyName = args[1].FromSnakeCase();

if (Loader.Loader.Plugins.All(x => x.Name != pluginName))
{
response = $"Plugin not found: {pluginName}";
return false;
}

IPlugin<IConfig> plugin = Loader.Loader.Plugins.First(x => x.Name == pluginName);

if (plugin.Config == null)
{
response = "Plugin config is null!";
return false;
}

if (plugin.Config.GetType().GetProperty(propertyName) is not PropertyInfo property)
{
response = $"Config value not found: {propertyName} ({propertyName.ToSnakeCase()})";
return false;
}

response = $"Value: {property.GetValue(plugin.Config)}";
return true;
}
}
}
115 changes: 115 additions & 0 deletions Exiled.Events/Commands/ConfigValue/Set.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// -----------------------------------------------------------------------
// <copyright file="Set.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

namespace Exiled.Events.Commands.ConfigValue
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

using CommandSystem;
using Exiled.API.Extensions;
using Exiled.API.Features;
using Exiled.API.Interfaces;
using Exiled.Loader;
using Exiled.Permissions.Extensions;
using RemoteAdmin;

/// <summary>
/// The command to set config value.
/// </summary>
public class Set : ICommand
{
/// <summary>
/// Gets a static instance of <see cref="Set"/> class.
/// </summary>
public static Set Instance { get; } = new();

/// <inheritdoc/>
public string Command { get; } = "set";

/// <inheritdoc/>
public string[] Aliases { get; } = { "edit" };

/// <inheritdoc/>
public string Description { get; } = "Sets a config value";

/// <inheritdoc/>
public bool SanitizeResponse { get; }

/// <inheritdoc/>
public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response)
{
const string perm = "cv.set";

if (!sender.CheckPermission(perm) && sender is PlayerCommandSender playerSender && !playerSender.FullPermissions)
{
response = $"You can't set a config value, you don't have \"{perm}\" permissions.";
return false;
}

if (arguments.Count != 2)
{
response = "Please, use: cv set PluginName.ValueName NewValue";
return false;
}

string[] args = arguments.At(0).Split('.');

string pluginName = args[0];
string propertyName = args[1].FromSnakeCase();

if (Loader.Plugins.All(x => x.Name != pluginName))
{
response = $"Plugin not found: {pluginName}";
return false;
}

IPlugin<IConfig> plugin = Loader.GetPlugin(pluginName);

if (plugin.Config == null)
{
response = "Plugin config is null!";
return false;
}

if (plugin.Config.GetType().GetProperty(propertyName) is not PropertyInfo property)
{
response = $"Config value not found: {propertyName} ({propertyName.ToSnakeCase()})";
return false;
}

object newValue;

try
{
newValue = Convert.ChangeType(arguments.At(1), property.PropertyType);
}
catch (Exception exception)
{
Log.Error(exception);

response = $"Provided value is not a type of {property.PropertyType.Name}";
return false;
}

if (newValue == null)
{
response = $"Provided value is not a type of {property.PropertyType.Name}";
return false;
}

SortedDictionary<string, IConfig> configs = ConfigManager.LoadSorted(ConfigManager.Read());
property.SetValue(configs[pluginName], newValue);
bool success = ConfigManager.Save(configs);

response = success ? "Value has been successfully changed and added in config" : "Value has been successfully changed but not added in config";
return true;
}
}
}
Loading

0 comments on commit 7ebbd79

Please sign in to comment.