diff --git a/CustomCommands/Commands/Others.example.json b/CustomCommands/Commands/Others.example.json index 07d36c6..7eb2c69 100644 --- a/CustomCommands/Commands/Others.example.json +++ b/CustomCommands/Commands/Others.example.json @@ -17,4 +17,4 @@ }, "PrintTo": 7 } - ] \ No newline at end of file +] \ No newline at end of file diff --git a/CustomCommands/CustomCommands.cs b/CustomCommands/CustomCommands.cs index de6431e..82327f8 100644 --- a/CustomCommands/CustomCommands.cs +++ b/CustomCommands/CustomCommands.cs @@ -9,7 +9,7 @@ namespace CustomCommands; public partial class CustomCommands : BasePlugin, IPluginConfig { public override string ModuleName => "CustomCommands"; - public override string ModuleVersion => "1.0.8"; + public override string ModuleVersion => "1.0.9"; public override string ModuleAuthor => "HerrMagic"; public override string ModuleDescription => "Create your own commands per config"; @@ -43,12 +43,18 @@ public override void Load(bool hotReload) } Logger.LogInformation( - $"CustomCommands has been loaded, and the hot reload flag was {hotReload}, path is {ModulePath}"); + $"{ModuleName} loaded!"); PluginGlobals.Config = Config; - var comms = LoadJson.LoadCommandsFromJson(ModuleDirectory); + var comms = LoadJson.GetCommandsFromJsonFiles(ModuleDirectory); + if (comms == null) + { + Logger.LogError("No commands found please create a config file"); + return; + } + EventManager.RegisterListeners(); if (comms != null) diff --git a/CustomCommands/CustomCommands.csproj b/CustomCommands/CustomCommands.csproj index 4d51773..134187f 100644 --- a/CustomCommands/CustomCommands.csproj +++ b/CustomCommands/CustomCommands.csproj @@ -10,7 +10,11 @@ - + + none + runtime + compile; build; native; contentfiles; analyzers; buildtransitive + @@ -22,6 +26,7 @@ + diff --git a/CustomCommands/Interfaces/ILoadJson.cs b/CustomCommands/Interfaces/ILoadJson.cs index 1fdd577..e564de8 100644 --- a/CustomCommands/Interfaces/ILoadJson.cs +++ b/CustomCommands/Interfaces/ILoadJson.cs @@ -4,5 +4,11 @@ namespace CustomCommands.Interfaces; public interface ILoadJson { - List? LoadCommandsFromJson(string path); + List GetCommandsFromJsonFiles(string path); + void CheckForExampleFile(string path); + bool IsValidJsonSyntax(string jsonString); + bool ValidateObject(List? comms, string path); + void LogCommandDetails(Commands comms); + bool PrintToCheck(Commands comms); + bool ValidateMessage(dynamic message); } \ No newline at end of file diff --git a/CustomCommands/Model/CommandsConfig.cs b/CustomCommands/Model/CommandsConfig.cs index 007de20..18342ad 100644 --- a/CustomCommands/Model/CommandsConfig.cs +++ b/CustomCommands/Model/CommandsConfig.cs @@ -2,12 +2,12 @@ public class Commands { - public required string Title { get; set; } = ""; + public string Title { get; set; } = ""; public string Description { get; set; } = "Description"; - public required string Command { get; set; } = "testtesttest"; + public string Command { get; set; } = ""; public dynamic Message { get; set; } = ""; public CenterElement CenterMessage { get; set; } = new(); - public required Sender PrintTo { get; set; } = Sender.ClientChat; + public Sender PrintTo { get; set; } = Sender.ClientChat; public List ServerCommands { get; set; } = new(); public Permission Permission { get; set; } = new(); } diff --git a/CustomCommands/Services/EventManager.cs b/CustomCommands/Services/EventManager.cs index 69fb593..5fb1605 100644 --- a/CustomCommands/Services/EventManager.cs +++ b/CustomCommands/Services/EventManager.cs @@ -4,7 +4,6 @@ using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Core.Plugin; using CustomCommands.Interfaces; -using Microsoft.Extensions.Logging; namespace CustomCommands.Services; diff --git a/CustomCommands/Services/LoadJson.cs b/CustomCommands/Services/LoadJson.cs index 55166e1..b729811 100644 --- a/CustomCommands/Services/LoadJson.cs +++ b/CustomCommands/Services/LoadJson.cs @@ -14,29 +14,173 @@ public LoadJson(ILogger Logger) this.Logger = Logger; } - /// - /// Load the commands from the JSON file - /// - /// Returns the Commands as a List - public List? LoadCommandsFromJson(string path) + public List GetCommandsFromJsonFiles(string path) { - string jsonPath = Path.Combine(path, "Commands.json"); - if (File.Exists(jsonPath)) + var comms = new List(); + + CheckForExampleFile(path); + + var pathofcommands = Path.Combine(path, "Commands"); + var defaultconfigpath = Path.Combine(path, "Commands.json"); + + var files = new List(); + + if (Directory.Exists(pathofcommands)) + files.AddRange(Directory.GetFiles(pathofcommands, "*.json", SearchOption.AllDirectories)); + + // Check if the default config file exists in plugins/CustomCommands + if (File.Exists(defaultconfigpath)) + { + files.Add(defaultconfigpath); + Logger.LogInformation("Found default config file."); + } + // + else if (!File.Exists(defaultconfigpath) && files.Count == 0) + { + Logger.LogWarning("No Config file found. Please create plugins/CustomCommands/Commands.json or in plugins/CustomCommands/Commands/.json"); + return comms; + } + + foreach (var file in files) + { + var json = File.ReadAllText(file); + + // Validate the JSON file + if (!IsValidJsonSyntax(file)) + continue; + + var commands = JsonSerializer.Deserialize>(json); + if (ValidateObject(commands, file)) + comms.AddRange(commands!); + } + return comms; + } + // Check if the Command.json file exists. If not replace it with the example file + public void CheckForExampleFile(string path) + { + var defaultconfigpath = Path.Combine(path, "Commands.json"); + var exampleconfigpath = Path.Combine(path, "Commands.example.json"); + if (!File.Exists(defaultconfigpath)) + { + File.Copy(exampleconfigpath, defaultconfigpath); + Logger.LogInformation("Created default config file."); + } + + } + public bool IsValidJsonSyntax(string path) + { + try + { + var json = File.ReadAllText(path); + var document = JsonDocument.Parse(json); + return true; + } + catch (JsonException ex) { - var json = File.ReadAllText(jsonPath); - return JsonSerializer.Deserialize>(json); + Logger.LogError($"Invalid JSON syntax in {path}. Please check the docs on how to create a valid JSON file"); + Logger.LogError(ex.Message); + return false; } - else if (File.Exists(Path.Combine(path, "Commands.example.json"))) + } + public bool ValidateObject(List? comms, string path) + { + if (comms == null) + { + Logger.LogError($"Invalid JSON format in {path}. Please check the docs on how to create a valid JSON file"); + return false; + } + bool commandstatus = true; + for (int i = 0; i < comms.Count; i++) + { + commandstatus = true; + // Title + if (string.IsNullOrEmpty(comms[i].Title)) + { + Logger.LogWarning($"Title not set in {path}. Title is not required but recommended"); + commandstatus = false; + } + // Description + if (string.IsNullOrEmpty(comms[i].Description)) + { + Logger.LogWarning($"Description not set in {path}. Description is not required but recommended. This will be shown in the help command"); + commandstatus = false; + } + // Command + if (string.IsNullOrEmpty(comms[i].Command)) + { + Logger.LogError($"Command not set in {path}"); + commandstatus = false; + } + if (!PrintToCheck(comms[i])) + commandstatus = false; + + if (!commandstatus) + { + Logger.LogError($"Command {comms[i].Command} will not be loaded. Index: {i}"); + LogCommandDetails(comms[i]); + } + } + if (!commandstatus) + return false; + return true; + } + + public void LogCommandDetails(Commands comms) + { + Logger.LogInformation($"-- Title: {comms.Title}"); + Logger.LogInformation($"-- Description: {comms.Description}"); + Logger.LogInformation($"-- Command: {comms.Command}"); + Logger.LogInformation($"-- Message: {comms.Message}"); + Logger.LogInformation($"-- CenterMessage: {comms.CenterMessage.Message}"); + Logger.LogInformation($"-- CenterMessageTime: {comms.CenterMessage.Time}"); + Logger.LogInformation($"-- PrintTo: {comms.PrintTo}"); + Logger.LogInformation($"-- ServerCommands: {JsonSerializer.Serialize(comms.ServerCommands)}"); + Logger.LogInformation($"-- PermissionList: {JsonSerializer.Serialize(comms.Permission)}"); + Logger.LogInformation("--------------------------------------------------"); + } + + public bool PrintToCheck(Commands comms) + { + if (comms.PrintTo == Sender.ClientChat || comms.PrintTo == Sender.AllChat) { - Logger.LogWarning("No Config file found. Please rename Commands.example.json to Commands.json"); - return null; + + if (!ValidateMessage(comms.Message)) + { + Logger.LogError($"Message not set but needs to be set because PrintTo is set to {comms.PrintTo}"); + return false; + } } + else if (comms.PrintTo == Sender.ClientCenter || comms.PrintTo == Sender.AllCenter) + { + if (string.IsNullOrEmpty(comms.CenterMessage.Message)) + { + Logger.LogError($"CenterMessage is not set but needs to be set because PrintTo is set to {comms.PrintTo}"); + return false; + } + } else { - Logger.LogWarning("No Config file found. Please create one"); - return null; + if (!ValidateMessage(comms.Message) && string.IsNullOrEmpty(comms.CenterMessage.Message)) + { + Logger.LogError($"Message and CenterMessage are not set but needs to be set because PrintTo is set to {comms.PrintTo}"); + return false; + } } + return true; } - + public bool ValidateMessage(dynamic message) + { + if (message is JsonElement jsonElement) + { + if (jsonElement.ValueKind == JsonValueKind.String) + return true; + + if (jsonElement.ValueKind == JsonValueKind.Array) + return true; + + return false; + } + return false; + } } diff --git a/CustomCommands/Services/MessageManager.cs b/CustomCommands/Services/MessageManager.cs index 248b568..bf54ff9 100644 --- a/CustomCommands/Services/MessageManager.cs +++ b/CustomCommands/Services/MessageManager.cs @@ -3,7 +3,6 @@ using CounterStrikeSharp.API.Core.Plugin; using CustomCommands.Interfaces; using CustomCommands.Model; -using Microsoft.Extensions.Logging; namespace CustomCommands.Services; public class MessageManager : IMessageManager diff --git a/CustomCommands/Services/PermissionsManager.cs b/CustomCommands/Services/PermissionsManager.cs index dbc6389..b0ab555 100644 --- a/CustomCommands/Services/PermissionsManager.cs +++ b/CustomCommands/Services/PermissionsManager.cs @@ -2,8 +2,6 @@ using CounterStrikeSharp.API.Modules.Admin; using CustomCommands.Interfaces; using CustomCommands.Model; -using Microsoft.Extensions.Logging; -using Serilog; namespace CustomCommands.Services; diff --git a/CustomCommands/Services/ReplaceTagsFunction.cs b/CustomCommands/Services/ReplaceTagsFunction.cs index 2e7eaa8..81f2a6b 100644 --- a/CustomCommands/Services/ReplaceTagsFunction.cs +++ b/CustomCommands/Services/ReplaceTagsFunction.cs @@ -6,7 +6,6 @@ using CounterStrikeSharp.API.Modules.Entities; using CounterStrikeSharp.API.Modules.Utils; using CustomCommands.Interfaces; -using CounterStrikeSharp.API.Core.Translations; using Microsoft.Extensions.Logging; using CounterStrikeSharp.API.Core.Plugin; diff --git a/Examples/LanguageSupport.json b/Examples/LanguageSupport.json index 6cca537..5bff262 100644 --- a/Examples/LanguageSupport.json +++ b/Examples/LanguageSupport.json @@ -3,7 +3,12 @@ "Title": "Sentance", "Description": "Send a sentance", "Command": "sentance", + // Note that you also need to add the test tag in the language files in CustomCommands/lang "Message": "{LANG=test} test", - "PrintTo": 0 + "PrintTo": 2, + "CenterMessage": { + "Message": "{LANG=test}", + "Time": 10 + } } ] \ No newline at end of file diff --git a/README.md b/README.md index a0a7ed7..c5eb8df 100644 --- a/README.md +++ b/README.md @@ -111,4 +111,13 @@ Defines if the command requires specific permissions to execute: ### Colorlist -![CS2Colors](.github\img\ColorsCS2.png) +![CS2Colors](.github/img/ColorsCS2.png) + +### Multiple Files + +If you want to have multiple files instead of one big one create a folder in plugins/CustomCommands named Commands there you can create json files and folders as many as you want and with any name. + + +## Contributing + +You are welcome to contribute to this project! Simply create a pull request, and it will be promptly reviewed.