From fffda53263fe3121f5933c36cdb350a93e21c7ae Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 10 Feb 2024 00:19:19 -0800 Subject: [PATCH] fix: Adds command help, webpage, and fixes issues with other commands (#1669) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Summary - Fixes `[AdvancedSearch` being accessible by players 😱 - Adds `[GenCommands` to generate the same commands html page on https://muo.gg/commands. - Fixes `[helpinfo` so all commands properly show up! > [!WARNING] > ### Developer Warning: > Commands must now be registered in the `Configure` bootup phase. > If a command is not registered early enough, it may not be available to systems like [helpinfo > that cache their information. > [!NOTE] > ### Developer Note: > Various commands related to generating content have been changed to _Developer_ and above access level. ### Screenshots image image --- .github/workflows/update-docs.yml | 12 +- .gitignore | 1 + Distribution/Data/commands.html | 531 ++++++++++++ .../Tests/Utility/IPAddressTests.cs | 1 - Projects/Server/Commands.cs | 17 +- .../Server/Network/NetState/DumpNetStates.cs | 2 +- Projects/Server/Utilities/Html.cs | 11 + .../UOContent/Accounting/AccountHandler.cs | 11 +- Projects/UOContent/Commands/Batch.cs | 4 +- Projects/UOContent/Commands/DragEffects.cs | 2 +- Projects/UOContent/Commands/Dupe.cs | 2 +- Projects/UOContent/Commands/ExportWSC.cs | 2 +- Projects/UOContent/Commands/GenCommands.cs | 72 ++ .../Commands/Generic/Commands/Commands.cs | 6 +- .../Commands/Generic/Commands/DesignInsert.cs | 2 +- .../Implementors/BaseCommandImplementor.cs | 14 +- Projects/UOContent/Commands/Handlers.cs | 4 +- Projects/UOContent/Commands/HelpInfo.cs | 784 +++++++++--------- .../UOContent/Commands/Object Creation/Add.cs | 4 +- .../Commands/Object Creation/AddGump.cs | 2 +- .../Commands/Object Creation/Decorate.cs | 4 +- .../Commands/Object Creation/DecorateMag.cs | 4 +- .../Commands/Object Creation/GenTeleporter.cs | 6 +- Projects/UOContent/Commands/Profiling.cs | 2 +- Projects/UOContent/Commands/Properties.cs | 4 +- Projects/UOContent/Commands/ResetRng.cs | 2 +- .../UOContent/Commands/ResetStaffDress.cs | 2 +- Projects/UOContent/Commands/ShardTime.cs | 2 +- Projects/UOContent/Commands/SignParser.cs | 4 +- Projects/UOContent/Commands/Skills.cs | 2 +- Projects/UOContent/Commands/SkillsMenu.cs | 7 +- Projects/UOContent/Commands/StaffAccess.cs | 4 +- Projects/UOContent/Commands/VisibilityList.cs | 2 +- Projects/UOContent/Commands/Wipe.cs | 2 +- .../Advanced Search/AdvancedSearchCommand.cs | 8 +- .../Engines/CannedEvil/ChampionCommands.cs | 2 +- .../UOContent/Engines/CannedEvil/GenChamps.cs | 4 +- .../UOContent/Engines/ConPVP/DuelContext.cs | 2 +- .../UOContent/Engines/Craft/Core/Recipes.cs | 2 +- .../UOContent/Engines/Doom/GenGauntlet.cs | 6 +- .../Doom/LeverPuzzle/LeverPuzzleController.cs | 2 +- .../Engines/Factions/Core/Faction.cs | 11 +- .../Engines/Factions/Core/Generator.cs | 4 +- .../UOContent/Engines/Factions/Core/Town.cs | 7 +- Projects/UOContent/Engines/Help/PageQueue.cs | 2 +- Projects/UOContent/Engines/Help/SpeechLog.cs | 2 +- .../UOContent/Engines/Khaldun/KhaldunGen.cs | 4 +- .../Engines/ML Quests/MLQuestSystem.cs | 20 +- Projects/UOContent/Engines/Party/Party.cs | 2 +- .../UOContent/Engines/Pathing/MovementPath.cs | 2 +- .../UOContent/Engines/Spawners/BaseSpawner.cs | 2 - .../Commands/ConvertPremiumSpawners.cs | 2 +- .../Spawners/Commands/EditSpawnerCommand.cs | 2 +- .../Commands/ExportSpawnersCommand.cs | 2 +- .../Commands/GenerateSpawnersCommand.cs | 2 +- .../Spawners/Commands/RespawnCommand.cs | 2 +- .../Spawners/Commands/SpawnPropsCommand.cs | 2 +- .../Engines/Spawners/SpawnPropsGump.cs | 1 - .../Engines/Spawners/SpawnerControllerGump.cs | 2 +- .../Engines/Stealables/StealableArtifacts.cs | 9 +- Projects/UOContent/Gumps/AddDoorGump.cs | 2 +- Projects/UOContent/Gumps/AdminGump.cs | 2 +- Projects/UOContent/Gumps/CommentsGump.cs | 2 +- Projects/UOContent/Gumps/Props/PropsGump.cs | 2 - Projects/UOContent/Gumps/ToTAdminGump.cs | 2 +- Projects/UOContent/Gumps/ViewHousesGump.cs | 2 +- Projects/UOContent/Gumps/WhoGump.cs | 2 +- .../UOContent/Items/Addons/SHTeleporter.cs | 4 +- .../Items/Construction/Doors/BaseDoor.cs | 2 +- .../Items/Containers/MarkContainer.cs | 4 +- .../Items/Misc/FlippableAttribute.cs | 2 +- .../UOContent/Items/Misc/PublicMoongate.cs | 4 +- Projects/UOContent/Items/Misc/WayPoint.cs | 2 +- .../Items/Skill Items/Magical/Spellbook.cs | 2 +- Projects/UOContent/Items/Suits/StaffRobe.cs | 2 +- .../UOContent/Items/Talismans/BaseTalisman.cs | 2 +- Projects/UOContent/Misc/AutoRestart.cs | 4 - Projects/UOContent/Misc/DoorGenerator.cs | 4 +- Projects/UOContent/Misc/LanguageStatistics.cs | 2 +- Projects/UOContent/Misc/LightCycle.cs | 9 +- Projects/UOContent/Misc/NameVerification.cs | 2 +- Projects/UOContent/Misc/PacketThrottles.cs | 14 +- Projects/UOContent/Misc/ToggleItem.cs | 2 +- .../UOContent/Mobiles/Townfolk/TownCrier.cs | 2 +- Projects/UOContent/Network/NetworkCommands.cs | 2 +- Projects/UOContent/Regions/GuardedRegion.cs | 2 +- .../UOContent/World Saves/SaveCommands.cs | 2 +- docs/commands/commands.7z | Bin 0 -> 11143 bytes 88 files changed, 1163 insertions(+), 557 deletions(-) create mode 100644 Distribution/Data/commands.html create mode 100644 Projects/UOContent/Commands/GenCommands.cs create mode 100644 docs/commands/commands.7z diff --git a/.github/workflows/update-docs.yml b/.github/workflows/update-docs.yml index b815a3af8..3595a112a 100644 --- a/.github/workflows/update-docs.yml +++ b/.github/workflows/update-docs.yml @@ -10,8 +10,18 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: 3.x - run: pip install mkdocs-material - run: mkdocs gh-deploy --force + - name: Extract commands web file + run: | + 7z x ./docs/commands/commands.7z -o./docs/commands + rm ./docs/commands/commands.7z + - name: Deploy commands file + uses: JamesIves/github-pages-deploy-action@v4 + with: + folder: ./docs/commands + clean: false + force: false diff --git a/.gitignore b/.gitignore index 04da66351..a9b9e57c4 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ /Distribution/runtimes /Distribution/nohup.out /Distribution/ref +/Distribution/web /Projects/*/obj /Projects/*/bin diff --git a/Distribution/Data/commands.html b/Distribution/Data/commands.html new file mode 100644 index 000000000..64c94ffd0 --- /dev/null +++ b/Distribution/Data/commands.html @@ -0,0 +1,531 @@ + + + + + + + + + ModernUO Commands + + + + + + +
+
+
+ +
+ +
+ +

ModernUO Commands

+ +
    + +
+ +
+ +
+
+
+
+ + + + + + + diff --git a/Projects/Server.Tests/Tests/Utility/IPAddressTests.cs b/Projects/Server.Tests/Tests/Utility/IPAddressTests.cs index 8e7501e95..3215b33a3 100644 --- a/Projects/Server.Tests/Tests/Utility/IPAddressTests.cs +++ b/Projects/Server.Tests/Tests/Utility/IPAddressTests.cs @@ -1,5 +1,4 @@ using System; -using System.Buffers.Binary; using System.Net; using Xunit; diff --git a/Projects/Server/Commands.cs b/Projects/Server/Commands.cs index 6808ea716..bf8c4bb9f 100644 --- a/Projects/Server/Commands.cs +++ b/Projects/Server/Commands.cs @@ -1,3 +1,18 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2024 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: Commands.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + using System; using System.Collections.Generic; @@ -91,7 +106,7 @@ public class CommandEntry : IComparable } } -public record CommandInfo(AccessLevel AccessLevel, string Name, string[] Aliases, string Usage, string Description); +public record CommandInfo(AccessLevel AccessLevel, string Name, string[] Aliases, string Usage, string[] Modifiers, string Description); public class CommandInfoSorter : IComparer { diff --git a/Projects/Server/Network/NetState/DumpNetStates.cs b/Projects/Server/Network/NetState/DumpNetStates.cs index 1a7b4705e..24b98b9eb 100644 --- a/Projects/Server/Network/NetState/DumpNetStates.cs +++ b/Projects/Server/Network/NetState/DumpNetStates.cs @@ -19,7 +19,7 @@ namespace Server.Network; public static class DumpNetStates { - public static void Initialize() + public static void Configure() { CommandSystem.Register("DumpNetStates", AccessLevel.Administrator, DumpNetStatesCommand); } diff --git a/Projects/Server/Utilities/Html.cs b/Projects/Server/Utilities/Html.cs index 1ae7017dc..86a1f5e6b 100644 --- a/Projects/Server/Utilities/Html.cs +++ b/Projects/Server/Utilities/Html.cs @@ -14,6 +14,7 @@ *************************************************************************/ using System.Runtime.CompilerServices; +using System.Text; namespace Server.Utilities; @@ -45,4 +46,14 @@ public static class Html [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Center(this string text, string color, int size) => $"
{text}
"; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string EscapeHtml(this string input) => + new StringBuilder(input.Length).Append(input) + .Replace("<", "<") + .Replace(">", ">") + .Replace("&", "&") + .Replace("\"", """) + .Replace("'", "'") + .ToString(); } diff --git a/Projects/UOContent/Accounting/AccountHandler.cs b/Projects/UOContent/Accounting/AccountHandler.cs index 729fd6766..f115fcac0 100644 --- a/Projects/UOContent/Accounting/AccountHandler.cs +++ b/Projects/UOContent/Accounting/AccountHandler.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; using System.Net; using Server.Accounting; using Server.Engines.Help; @@ -56,6 +55,11 @@ public static class AccountHandler "accountHandler.enablePlayerPasswordCommand", false ); + + if (PasswordCommandEnabled) + { + CommandSystem.Register("Password", AccessLevel.Player, Password_OnCommand); + } } public static void Initialize() @@ -63,11 +67,6 @@ public static class AccountHandler EventSink.DeleteRequest += EventSink_DeleteRequest; EventSink.AccountLogin += EventSink_AccountLogin; EventSink.GameLogin += EventSink_GameLogin; - - if (PasswordCommandEnabled) - { - CommandSystem.Register("Password", AccessLevel.Player, Password_OnCommand); - } } [Usage("Password ")] diff --git a/Projects/UOContent/Commands/Batch.cs b/Projects/UOContent/Commands/Batch.cs index f03632878..ae9068bd7 100644 --- a/Projects/UOContent/Commands/Batch.cs +++ b/Projects/UOContent/Commands/Batch.cs @@ -48,7 +48,7 @@ namespace Server.Commands if (command == null) { e.Mobile.SendMessage( - $"That is either an invalid command name or one that does not support this modifier: {commandString}." + $"That is either an invalid command name or one that does not support this modifier: {commandString}." ); return; } @@ -171,7 +171,7 @@ namespace Server.Commands return true; } - public static void Initialize() + public static void Configure() { CommandSystem.Register("Batch", AccessLevel.Counselor, Batch_OnCommand); } diff --git a/Projects/UOContent/Commands/DragEffects.cs b/Projects/UOContent/Commands/DragEffects.cs index 036b064e6..dac60f8d0 100644 --- a/Projects/UOContent/Commands/DragEffects.cs +++ b/Projects/UOContent/Commands/DragEffects.cs @@ -2,7 +2,7 @@ namespace Server.Commands { public static class DragEffects { - public static void Initialize() + public static void Configure() { CommandSystem.Register("DragEffects", AccessLevel.Developer, DragEffects_OnCommand); } diff --git a/Projects/UOContent/Commands/Dupe.cs b/Projects/UOContent/Commands/Dupe.cs index 56b0f46d1..0f43a116b 100644 --- a/Projects/UOContent/Commands/Dupe.cs +++ b/Projects/UOContent/Commands/Dupe.cs @@ -7,7 +7,7 @@ namespace Server.Commands { public static class Dupe { - public static void Initialize() + public static void Configure() { CommandSystem.Register("Dupe", AccessLevel.GameMaster, Dupe_OnCommand); CommandSystem.Register("DupeInBag", AccessLevel.GameMaster, DupeInBag_OnCommand); diff --git a/Projects/UOContent/Commands/ExportWSC.cs b/Projects/UOContent/Commands/ExportWSC.cs index 9310da053..5b870cf92 100644 --- a/Projects/UOContent/Commands/ExportWSC.cs +++ b/Projects/UOContent/Commands/ExportWSC.cs @@ -8,7 +8,7 @@ namespace Server.Commands { private const string ExportFile = @"C:\Uo\WorldForge\items.wsc"; - public static void Initialize() + public static void Configure() { CommandSystem.Register("ExportWSC", AccessLevel.Administrator, Export_OnCommand); } diff --git a/Projects/UOContent/Commands/GenCommands.cs b/Projects/UOContent/Commands/GenCommands.cs new file mode 100644 index 000000000..5268e6322 --- /dev/null +++ b/Projects/UOContent/Commands/GenCommands.cs @@ -0,0 +1,72 @@ +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Text.Json; +using Server.Commands.Generic; +using Server.Json; +using Server.Utilities; + +namespace Server.Commands; + +public static class GenCommands +{ + public static void Configure() + { + CommandSystem.Register("GenCommands", AccessLevel.Developer, GenCommandsWebpage_OnCommand); + } + + [Usage("GenCommands []")] + [Aliases("GenCmdWeb")] + [Description("Generates a webpage to the web folder with a list of all commands.")] + private static void GenCommandsWebpage_OnCommand(CommandEventArgs e) + { + var allCommands = HelpInfo.SortedHelpInfo; + var allModifiers = BaseCommandImplementor.Implementors; + + Dictionary modifiersByAccessor = []; + + foreach (var modifier in allModifiers) + { + modifiersByAccessor[modifier.Accessors[0]] = modifier; + } + + Dictionary> commandsByAccessLevel = []; + + foreach (var command in allCommands) + { + if (!commandsByAccessLevel.TryGetValue(command.AccessLevel, out var list)) + { + commandsByAccessLevel[command.AccessLevel] = list = []; + } + + list.Add(command); + } + + // Serialization options with camel case naming policy + var options = JsonConfig.GetOptions(); + options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; + + // Write modifiers as JSON. All keys must be lowercase. + var modifiersJson = JsonSerializer.Serialize( + modifiersByAccessor, + options + ); + + // Write commands as JSON. All keys must be lowercase. + var commandsJson = JsonSerializer.Serialize( + commandsByAccessLevel, + options + ); + + var template = File.ReadAllText(Path.Combine(Core.BaseDirectory, "Data", "commands.html")) + .Replace("", commandsJson.EscapeHtml()) + .Replace("", modifiersJson.EscapeHtml()); + + // Write the new file to the web folder + var webFolder = Path.Combine(Core.BaseDirectory, "web"); + PathUtility.EnsureDirectory(webFolder); + var webPath = Path.Combine(webFolder, "commands.html"); + File.WriteAllText(webPath, template, Encoding.UTF8); + e.Mobile.SendMessage($"Commands webpage generated at {webPath}."); + } +} diff --git a/Projects/UOContent/Commands/Generic/Commands/Commands.cs b/Projects/UOContent/Commands/Generic/Commands/Commands.cs index e70533aa5..12f5243db 100644 --- a/Projects/UOContent/Commands/Generic/Commands/Commands.cs +++ b/Projects/UOContent/Commands/Generic/Commands/Commands.cs @@ -16,7 +16,7 @@ namespace Server.Commands.Generic { public static List AllCommands { get; } = new(); - public static void Initialize() + public static void Configure() { Register(new KillCommand(true)); Register(new KillCommand(false)); @@ -408,13 +408,13 @@ namespace Server.Commands.Generic if (inGump) { Commands = new[] { "Message", "Msg" }; - Usage = "Message \"text\""; + Usage = "Message "; Description = "Sends a message to a targeted player."; } else { Commands = new[] { "Tell" }; - Usage = "Tell \"text\""; + Usage = "Tell "; Description = "Sends a system message to a targeted player."; } } diff --git a/Projects/UOContent/Commands/Generic/Commands/DesignInsert.cs b/Projects/UOContent/Commands/Generic/Commands/DesignInsert.cs index 0a048ef51..e2e7c3cc8 100644 --- a/Projects/UOContent/Commands/Generic/Commands/DesignInsert.cs +++ b/Projects/UOContent/Commands/Generic/Commands/DesignInsert.cs @@ -26,7 +26,7 @@ namespace Server.Commands.Generic Description = "Inserts multiple targeted items into a customizable house's design."; } - public static void Initialize() + public static void Configure() { TargetCommands.Register(new DesignInsertCommand()); } diff --git a/Projects/UOContent/Commands/Generic/Implementors/BaseCommandImplementor.cs b/Projects/UOContent/Commands/Generic/Implementors/BaseCommandImplementor.cs index eb4a1b968..bce4737a3 100644 --- a/Projects/UOContent/Commands/Generic/Implementors/BaseCommandImplementor.cs +++ b/Projects/UOContent/Commands/Generic/Implementors/BaseCommandImplementor.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Text.Json.Serialization; using Server.Text; namespace Server.Commands.Generic @@ -28,7 +29,7 @@ namespace Server.Commands.Generic public abstract class BaseCommandImplementor { - private static List m_Implementors; + private static List _implementors; public BaseCommandImplementor() => Commands = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -44,19 +45,20 @@ namespace Server.Commands.Generic public CommandSupport SupportRequirement { get; set; } + [JsonIgnore] public Dictionary Commands { get; } public static List Implementors { get { - if (m_Implementors == null) + if (_implementors == null) { - m_Implementors = new List(); + _implementors = []; RegisterImplementors(); } - return m_Implementors; + return _implementors; } } @@ -91,7 +93,7 @@ namespace Server.Commands.Generic } } - public bool CheckObjectTypes(Mobile from, BaseCommand command, Extensions ext, out bool items, out bool mobiles) + public static bool CheckObjectTypes(Mobile from, BaseCommand command, Extensions ext, out bool items, out bool mobiles) { items = mobiles = false; @@ -314,7 +316,7 @@ namespace Server.Commands.Generic public static void Register(BaseCommandImplementor impl) { - m_Implementors.Add(impl); + _implementors.Add(impl); impl.Register(); } } diff --git a/Projects/UOContent/Commands/Handlers.cs b/Projects/UOContent/Commands/Handlers.cs index 53cd5152e..0e20c1830 100644 --- a/Projects/UOContent/Commands/Handlers.cs +++ b/Projects/UOContent/Commands/Handlers.cs @@ -18,7 +18,7 @@ namespace Server.Commands { public static class CommandHandlers { - public static void Initialize() + public static void Configure() { CommandSystem.Prefix = ServerConfiguration.GetOrUpdateSetting("commandsystem.prefix", "["); @@ -28,7 +28,7 @@ namespace Server.Commands Register("GetFollowers", AccessLevel.GameMaster, GetFollowers_OnCommand); - Register("ClearFacet", AccessLevel.Administrator, ClearFacet_OnCommand); + Register("ClearFacet", AccessLevel.Developer, ClearFacet_OnCommand); Register("Where", AccessLevel.Counselor, Where_OnCommand); diff --git a/Projects/UOContent/Commands/HelpInfo.cs b/Projects/UOContent/Commands/HelpInfo.cs index 3056a75cd..2f49d79eb 100644 --- a/Projects/UOContent/Commands/HelpInfo.cs +++ b/Projects/UOContent/Commands/HelpInfo.cs @@ -1,449 +1,427 @@ using System.Collections.Generic; -using System.Text; using Server.Commands.Generic; using Server.Gumps; using Server.Network; +using Server.Text; -namespace Server.Commands +namespace Server.Commands; + +public static class HelpInfo { - public static class HelpInfo + private static List _sortedHelpInfo; + private static Dictionary _helpInfos; + + public static Dictionary HelpInfos { - public static Dictionary HelpInfos { get; } = new(); - - public static List SortedHelpInfo { get; private set; } = new(); - - public static void Initialize() + get { - CommandSystem.Register("HelpInfo", AccessLevel.Player, HelpInfo_OnCommand); + if (_helpInfos == null) + { + FillTable(); + } - FillTable(); + return _helpInfos; + } + } + + public static List SortedHelpInfo + { + get + { + if (_sortedHelpInfo == null) + { + FillTable(); + } + + return _sortedHelpInfo; + } + } + + public static void Configure() + { + CommandSystem.Register("HelpInfo", AccessLevel.Player, HelpInfo_OnCommand); + } + + public static void Initialize() + { + FillTable(); + } + + [Usage("HelpInfo []")] + [Description("Gives information on a specified command, or when no argument specified, displays a gump containing all commands")] + private static void HelpInfo_OnCommand(CommandEventArgs e) + { + if (e.Length > 0) + { + var arg = e.GetString(0).ToLower(); + if (HelpInfos.TryGetValue(arg, out var c)) + { + var m = e.Mobile; + + if (m.AccessLevel >= c.AccessLevel) + { + m.SendGump(new CommandInfoGump(c)); + } + else + { + m.SendMessage("You don't have access to that command."); + } + + return; + } + + e.Mobile.SendMessage($"Command '{arg}' not found!"); } - [Usage("HelpInfo []")] - [Description("Gives information on a specified command, or when no argument specified, displays a gump containing all commands")] - private static void HelpInfo_OnCommand(CommandEventArgs e) - { - if (e.Length > 0) - { - var arg = e.GetString(0).ToLower(); - if (HelpInfos.TryGetValue(arg, out var c)) - { - var m = e.Mobile; + e.Mobile.SendGump(new CommandListGump(0, e.Mobile, null)); + } - if (m.AccessLevel >= c.AccessLevel) + public static void FillTable() + { + var list = new List(); + var commands = CommandEntry.GetList(); + + for (var i = 0; i < commands.Count; ++i) + { + var e = commands[i]; + + var mi = e.Handler.Method; + + var attrs = mi.GetCustomAttributes(typeof(UsageAttribute), false); + + if (attrs.Length == 0) + { + continue; + } + + var usage = attrs[0] as UsageAttribute; + + attrs = mi.GetCustomAttributes(typeof(DescriptionAttribute), false); + + if (attrs.Length == 0) + { + continue; + } + + if (usage == null || attrs[0] is not DescriptionAttribute desc) + { + continue; + } + + attrs = mi.GetCustomAttributes(typeof(AliasesAttribute), false); + + var aliases = attrs.Length == 0 ? null : attrs[0] as AliasesAttribute; + + var descString = desc.Description + .ReplaceOrdinal("<", "(") + .ReplaceOrdinal(">", ")"); + + list.Add(new CommandInfo(e.AccessLevel, e.Command, aliases?.Aliases, usage.Usage, null, descString)); + } + + for (var i = 0; i < TargetCommands.AllCommands.Count; ++i) + { + var command = TargetCommands.AllCommands[i]; + + var usage = command.Usage; + var desc = command.Description; + + if (usage == null || desc == null) + { + continue; + } + + var cmds = command.Commands; + var cmd = cmds[0]; + var aliases = new string[cmds.Length - 1]; + + for (var j = 0; j < aliases.Length; ++j) + { + aliases[j] = cmds[j + 1]; + } + + desc = desc + .ReplaceOrdinal("<", "(") + .ReplaceOrdinal(">", ")"); + + List modsList = []; + + foreach (var baseImpl in BaseCommandImplementor.Implementors) + { + if ((baseImpl.SupportRequirement & command.Supports) != 0) + { + modsList.Add(baseImpl.Accessors[0]); + } + } + + var modifiers = modsList.ToArray(); + + list.Add(new CommandInfo(command.AccessLevel, cmd, aliases, usage, modifiers, desc)); + } + + var commandImpls = BaseCommandImplementor.Implementors; + + for (var i = 0; i < commandImpls.Count; ++i) + { + var command = commandImpls[i]; + + var usage = command.Usage; + var desc = command.Description; + + if (usage == null || desc == null) + { + continue; + } + + var cmds = command.Accessors; + var cmd = cmds[0]; + var aliases = new string[cmds.Length - 1]; + + for (var j = 0; j < aliases.Length; ++j) + { + aliases[j] = cmds[j + 1]; + } + + desc = desc + .ReplaceOrdinal("<", ")") + .ReplaceOrdinal(">", ")"); + + list.Add(new CommandInfo(command.AccessLevel, cmd, aliases, usage, null, desc)); + } + + list.Sort(new CommandInfoSorter()); + + _sortedHelpInfo = list; + _helpInfos = []; + + foreach (var c in _sortedHelpInfo) + { + _helpInfos.TryAdd(c.Name.ToLower(), c); + } + } + + public class CommandListGump : BaseGridGump + { + private const int EntriesPerPage = 15; + private readonly List _list; + + private readonly int _page; + + public CommandListGump(int page, Mobile from, List list) : base(30, 30) + { + _page = page; + + if (list == null) + { + _list = []; + + foreach (var c in SortedHelpInfo) + { + if (from.AccessLevel >= c.AccessLevel) { - m.SendGump(new CommandInfoGump(c)); + _list.Add(c); + } + } + } + else + { + _list = list; + } + + AddNewPage(); + + if (_page > 0) + { + AddEntryButton(20, ArrowLeftID1, ArrowLeftID2, 1, ArrowLeftWidth, ArrowLeftHeight); + } + else + { + AddEntryHeader(20); + } + + AddEntryHtml( + 320, + Center( + $"Page {_page + 1} of {(_list.Count + EntriesPerPage - 1) / EntriesPerPage}" + ) + ); + + if ((_page + 1) * EntriesPerPage < _list.Count) + { + AddEntryButton(20, ArrowRightID1, ArrowRightID2, 2, ArrowRightWidth, ArrowRightHeight); + } + else + { + AddEntryHeader(20); + } + + var last = (int)AccessLevel.Player - 1; + + for (int i = _page * EntriesPerPage, line = 0; line < EntriesPerPage && i < _list.Count; ++i, ++line) + { + var c = _list[i]; + if (from.AccessLevel >= c.AccessLevel) + { + if ((int)c.AccessLevel != last) + { + AddNewLine(); + AddEntryHtml(20 + OffsetSize + 320, Color(c.AccessLevel.ToString(), 0xFF0000)); + AddEntryHeader(20); + line++; + } + + last = (int)c.AccessLevel; + + AddNewLine(); + string name; + if (c.Aliases?.Length > 0) + { + using var sb = ValueStringBuilder.Create(); + sb.Append($"{c.Name} ("); + for (var j = 0; j < c.Aliases.Length; ++j) + { + if (j != 0) + { + sb.Append(", "); + } + + sb.Append(c.Aliases[j]); + } + + sb.Append(")"); + name = sb.ToString(); } else { - m.SendMessage("You don't have access to that command."); + name = c.Name; } - return; + AddEntryHtml(20 + OffsetSize + 320, name); + AddEntryButton(20, ArrowRightID1, ArrowRightID2, 3 + i, ArrowRightWidth, ArrowRightHeight); } - - e.Mobile.SendMessage($"Command '{arg}' not found!"); } - e.Mobile.SendGump(new CommandListGump(0, e.Mobile, null)); + FinishPage(); } - public static void FillTable() + public override void OnResponse(NetState sender, RelayInfo info) { - var list = new List(); - var commands = CommandEntry.GetList(); - - for (var i = 0; i < commands.Count; ++i) + var m = sender.Mobile; + switch (info.ButtonID) { - var e = commands[i]; - - var mi = e.Handler.Method; - - var attrs = mi.GetCustomAttributes(typeof(UsageAttribute), false); - - if (attrs.Length == 0) - { - continue; - } - - var usage = attrs[0] as UsageAttribute; - - attrs = mi.GetCustomAttributes(typeof(DescriptionAttribute), false); - - if (attrs.Length == 0) - { - continue; - } - - if (usage == null || attrs[0] is not DescriptionAttribute desc) - { - continue; - } - - attrs = mi.GetCustomAttributes(typeof(AliasesAttribute), false); - - var aliases = attrs.Length == 0 ? null : attrs[0] as AliasesAttribute; - - var descString = desc.Description - .ReplaceOrdinal("<", "(") - .ReplaceOrdinal(">", ")"); - - if (aliases == null) - { - list.Add(new CommandInfo(e.AccessLevel, e.Command, null, usage.Usage, descString)); - } - else - { - list.Add(new CommandInfo(e.AccessLevel, e.Command, aliases.Aliases, usage.Usage, descString)); - - for (var j = 0; j < aliases.Aliases.Length; j++) + case 0: { - var newAliases = new string[aliases.Aliases.Length]; - - aliases.Aliases.CopyTo(newAliases, 0); - - newAliases[j] = e.Command; - - list.Add(new CommandInfo(e.AccessLevel, aliases.Aliases[j], newAliases, usage.Usage, descString)); + m.CloseGump(); + break; } - } - } - - for (var i = 0; i < TargetCommands.AllCommands.Count; ++i) - { - var command = TargetCommands.AllCommands[i]; - - var usage = command.Usage; - var desc = command.Description; - - if (usage == null || desc == null) - { - continue; - } - - var cmds = command.Commands; - var cmd = cmds[0]; - var aliases = new string[cmds.Length - 1]; - - for (var j = 0; j < aliases.Length; ++j) - { - aliases[j] = cmds[j + 1]; - } - - desc = desc - .ReplaceOrdinal("<", "(") - .ReplaceOrdinal(">", ")"); - - if (command.Supports != CommandSupport.Single) - { - var sb = new StringBuilder(50 + desc.Length); - - sb.Append("Modifiers: "); - - if ((command.Supports & CommandSupport.Global) != 0) + case 1: { - sb.Append("Global, "); - } - - if ((command.Supports & CommandSupport.Online) != 0) - { - sb.Append("Online, "); - } - - if ((command.Supports & CommandSupport.Region) != 0) - { - sb.Append("Region, "); - } - - if ((command.Supports & CommandSupport.Contained) != 0) - { - sb.Append("Contained, "); - } - - if ((command.Supports & CommandSupport.Multi) != 0) - { - sb.Append("Multi, "); - } - - if ((command.Supports & CommandSupport.Area) != 0) - { - sb.Append("Area, "); - } - - if ((command.Supports & CommandSupport.Self) != 0) - { - sb.Append("Self, "); - } - - sb.Remove(sb.Length - 2, 2); - sb.Append("
"); - sb.Append(desc); - - desc = sb.ToString(); - } - - list.Add(new CommandInfo(command.AccessLevel, cmd, aliases, usage, desc)); - - for (var j = 0; j < aliases.Length; j++) - { - var newAliases = new string[aliases.Length]; - - aliases.CopyTo(newAliases, 0); - - newAliases[j] = cmd; - - list.Add(new CommandInfo(command.AccessLevel, aliases[j], newAliases, usage, desc)); - } - } - - var commandImpls = BaseCommandImplementor.Implementors; - - for (var i = 0; i < commandImpls.Count; ++i) - { - var command = commandImpls[i]; - - var usage = command.Usage; - var desc = command.Description; - - if (usage == null || desc == null) - { - continue; - } - - var cmds = command.Accessors; - var cmd = cmds[0]; - var aliases = new string[cmds.Length - 1]; - - for (var j = 0; j < aliases.Length; ++j) - { - aliases[j] = cmds[j + 1]; - } - - desc = desc - .ReplaceOrdinal("<", ")") - .ReplaceOrdinal(">", ")"); - - list.Add(new CommandInfo(command.AccessLevel, cmd, aliases, usage, desc)); - - for (var j = 0; j < aliases.Length; j++) - { - var newAliases = new string[aliases.Length]; - - aliases.CopyTo(newAliases, 0); - - newAliases[j] = cmd; - - list.Add(new CommandInfo(command.AccessLevel, aliases[j], newAliases, usage, desc)); - } - } - - list.Sort(new CommandInfoSorter()); - - SortedHelpInfo = list; - - foreach (var c in SortedHelpInfo) - { - HelpInfos.TryAdd(c.Name.ToLower(), c); - } - } - - public class CommandListGump : BaseGridGump - { - private const int EntriesPerPage = 15; - private readonly List m_List; - - private readonly int m_Page; - - public CommandListGump(int page, Mobile from, List list) - : base(30, 30) - { - m_Page = page; - - if (list == null) - { - m_List = new List(); - - foreach (var c in SortedHelpInfo) - { - if (from.AccessLevel >= c.AccessLevel) + if (_page > 0) { - m_List.Add(c); - } - } - } - else - { - m_List = list; - } - - AddNewPage(); - - if (m_Page > 0) - { - AddEntryButton(20, ArrowLeftID1, ArrowLeftID2, 1, ArrowLeftWidth, ArrowLeftHeight); - } - else - { - AddEntryHeader(20); - } - - AddEntryHtml( - 160, - Center( - $"Page {m_Page + 1} of {(m_List.Count + EntriesPerPage - 1) / EntriesPerPage}" - ) - ); - - if ((m_Page + 1) * EntriesPerPage < m_List.Count) - { - AddEntryButton(20, ArrowRightID1, ArrowRightID2, 2, ArrowRightWidth, ArrowRightHeight); - } - else - { - AddEntryHeader(20); - } - - var last = (int)AccessLevel.Player - 1; - - for (int i = m_Page * EntriesPerPage, line = 0; line < EntriesPerPage && i < m_List.Count; ++i, ++line) - { - var c = m_List[i]; - if (from.AccessLevel >= c.AccessLevel) - { - if ((int)c.AccessLevel != last) - { - AddNewLine(); - AddEntryHtml(20 + OffsetSize + 160, Color(c.AccessLevel.ToString(), 0xFF0000)); - AddEntryHeader(20); - line++; + m.SendGump(new CommandListGump(_page - 1, m, _list)); } - last = (int)c.AccessLevel; - - AddNewLine(); - AddEntryHtml(20 + OffsetSize + 160, c.Name); - AddEntryButton(20, ArrowRightID1, ArrowRightID2, 3 + i, ArrowRightWidth, ArrowRightHeight); + break; } - } - - FinishPage(); - } - - public override void OnResponse(NetState sender, RelayInfo info) - { - var m = sender.Mobile; - switch (info.ButtonID) - { - case 0: + case 2: + { + if ((_page + 1) * EntriesPerPage < SortedHelpInfo.Count) { - m.CloseGump(); - break; + m.SendGump(new CommandListGump(_page + 1, m, _list)); } - case 1: + + break; + } + default: + { + var v = info.ButtonID - 3; + + if (v >= 0 && v < _list.Count) { - if (m_Page > 0) + var c = _list[v]; + + if (m.AccessLevel >= c.AccessLevel) { - m.SendGump(new CommandListGump(m_Page - 1, m, m_List)); + m.SendGump(new CommandInfoGump(c)); + m.SendGump(new CommandListGump(_page, m, _list)); } - - break; - } - case 2: - { - if ((m_Page + 1) * EntriesPerPage < SortedHelpInfo.Count) + else { - m.SendGump(new CommandListGump(m_Page + 1, m, m_List)); + m.SendMessage("You no longer have access to that command."); + m.SendGump(new CommandListGump(_page, m, null)); } - - break; - } - default: - { - var v = info.ButtonID - 3; - - if (v >= 0 && v < m_List.Count) - { - var c = m_List[v]; - - if (m.AccessLevel >= c.AccessLevel) - { - m.SendGump(new CommandInfoGump(c)); - m.SendGump(new CommandListGump(m_Page, m, m_List)); - } - else - { - m.SendMessage("You no longer have access to that command."); - m.SendGump(new CommandListGump(m_Page, m, null)); - } - } - - break; - } - } - } - } - - public class CommandInfoGump : Gump - { - public CommandInfoGump(CommandInfo info, int width = 320, int height = 200) - : base(300, 50) - { - AddPage(0); - - AddBackground(0, 0, width, height, 5054); - - // AddImageTiled( 10, 10, width - 20, 20, 2624 ); - // AddAlphaRegion( 10, 10, width - 20, 20 ); - // AddHtmlLocalized( 10, 10, width - 20, 20, header, headerColor, false, false ); - AddHtml(10, 10, width - 20, 20, Color(Center(info.Name), 0xFF0000)); - - // AddImageTiled( 10, 40, width - 20, height - 80, 2624 ); - // AddAlphaRegion( 10, 40, width - 20, height - 80 ); - - var sb = new StringBuilder(); - - sb.Append("Usage: "); - var usage = info.Usage - .ReplaceOrdinal("<", "(") - .ReplaceOrdinal(">", ")"); - sb.Append(usage); - sb.Append("
"); - - var aliases = info.Aliases; - - if (aliases?.Length > 0) - { - sb.Append($"Alias{(aliases.Length == 1 ? "" : "es")}: "); - - for (var i = 0; i < aliases.Length; ++i) - { - if (i != 0) - { - sb.Append(", "); } - sb.Append(aliases[i]); + break; } - - sb.Append("
"); - } - - sb.Append("AccessLevel: "); - sb.Append(info.AccessLevel.ToString()); - sb.Append("
"); - sb.Append("
"); - - sb.Append(info.Description); - - AddHtml(10, 40, width - 20, height - 80, sb.ToString(), false, true); - - // AddImageTiled( 10, height - 30, width - 20, 20, 2624 ); - // AddAlphaRegion( 10, height - 30, width - 20, 20 ); } - - public string Color(string text, int color) => $"{text}"; - - public string Center(string text) => $"
{text}
"; } } + + public class CommandInfoGump : Gump + { + public CommandInfoGump(CommandInfo info, int width = 320, int height = 200) : base(300, 50) + { + AddPage(0); + + AddBackground(0, 0, width, height, 5054); + + AddHtml(10, 10, width - 20, 20, Color(Center(info.Name), 0xFF0000)); + + using var sb = ValueStringBuilder.Create(); + + sb.Append("Usage: "); + var usage = info.Usage + .ReplaceOrdinal("<", "(") + .ReplaceOrdinal(">", ")"); + sb.Append(usage); + sb.Append("
"); + + var aliases = info.Aliases; + + if (aliases?.Length > 0) + { + sb.Append($"Alias{(aliases.Length == 1 ? "" : "es")}: "); + + for (var i = 0; i < aliases.Length; ++i) + { + if (i != 0) + { + sb.Append(", "); + } + + sb.Append(aliases[i]); + } + + sb.Append("
"); + } + + sb.Append("AccessLevel: "); + sb.Append(info.AccessLevel.ToString()); + sb.Append("
"); + + if (info.Modifiers?.Length > 0) + { + sb.Append("Modifiers: "); + for (var i = 0; i < info.Modifiers.Length; ++i) + { + if (i != 0) + { + sb.Append(", "); + } + + sb.Append(info.Modifiers[i]); + } + sb.Append("
"); + sb.Append("
"); + } + sb.Append(info.Description); + + AddHtml(10, 40, width - 20, height - 80, sb.ToString(), false, true); + } + + public static string Color(string text, int color) => $"{text}"; + + public static string Center(string text) => $"
{text}
"; + } } diff --git a/Projects/UOContent/Commands/Object Creation/Add.cs b/Projects/UOContent/Commands/Object Creation/Add.cs index d203443e1..240d8dbd4 100644 --- a/Projects/UOContent/Commands/Object Creation/Add.cs +++ b/Projects/UOContent/Commands/Object Creation/Add.cs @@ -4,8 +4,6 @@ using System.Diagnostics; using System.Reflection; using System.Text; using Server.Items; -using CPA = Server.CommandPropertyAttribute; - using static Server.Attributes; using static Server.Types; @@ -13,7 +11,7 @@ namespace Server.Commands { public static class Add { - public static void Initialize() + public static void Configure() { CommandSystem.Register("Tile", AccessLevel.GameMaster, Tile_OnCommand); CommandSystem.Register("TileRXYZ", AccessLevel.GameMaster, TileRXYZ_OnCommand); diff --git a/Projects/UOContent/Commands/Object Creation/AddGump.cs b/Projects/UOContent/Commands/Object Creation/AddGump.cs index 2c093052f..0a78f5921 100644 --- a/Projects/UOContent/Commands/Object Creation/AddGump.cs +++ b/Projects/UOContent/Commands/Object Creation/AddGump.cs @@ -87,7 +87,7 @@ namespace Server.Gumps ); } - public static void Initialize() + public static void Configure() { CommandSystem.Register("AddMenu", AccessLevel.GameMaster, AddMenu_OnCommand); } diff --git a/Projects/UOContent/Commands/Object Creation/Decorate.cs b/Projects/UOContent/Commands/Object Creation/Decorate.cs index c15509f59..d9006580d 100644 --- a/Projects/UOContent/Commands/Object Creation/Decorate.cs +++ b/Projects/UOContent/Commands/Object Creation/Decorate.cs @@ -18,9 +18,9 @@ namespace Server.Commands private static Mobile m_Mobile; private static int m_Count; - public static void Initialize() + public static void Configure() { - CommandSystem.Register("Decorate", AccessLevel.Administrator, Decorate_OnCommand); + CommandSystem.Register("Decorate", AccessLevel.Developer, Decorate_OnCommand); } [Usage("Decorate")] diff --git a/Projects/UOContent/Commands/Object Creation/DecorateMag.cs b/Projects/UOContent/Commands/Object Creation/DecorateMag.cs index bc6d12650..66c66ddc6 100644 --- a/Projects/UOContent/Commands/Object Creation/DecorateMag.cs +++ b/Projects/UOContent/Commands/Object Creation/DecorateMag.cs @@ -18,9 +18,9 @@ namespace Server.Commands private static Mobile m_Mobile; private static int m_Count; - public static void Initialize() + public static void Configure() { - CommandSystem.Register("DecorateMag", AccessLevel.Administrator, DecorateMag_OnCommand); + CommandSystem.Register("DecorateMag", AccessLevel.Developer, DecorateMag_OnCommand); } [Usage("DecorateMag")] diff --git a/Projects/UOContent/Commands/Object Creation/GenTeleporter.cs b/Projects/UOContent/Commands/Object Creation/GenTeleporter.cs index 2f99d037a..0c2648fe4 100644 --- a/Projects/UOContent/Commands/Object Creation/GenTeleporter.cs +++ b/Projects/UOContent/Commands/Object Creation/GenTeleporter.cs @@ -28,10 +28,10 @@ namespace Server.Commands private const int SuccessHue = 72, WarningHue = 53, ErrorHue = 33; private static readonly string TeleporterJsonDataPath = Path.Combine(Core.BaseDirectory, "Data/teleporters.json"); - public static void Initialize() + public static void Configure() { - CommandSystem.Register("TelGen", AccessLevel.Administrator, GenTeleporter_OnCommand); - CommandSystem.Register("TelGenDelete", AccessLevel.Administrator, TelGenDelete_OnCommand); + CommandSystem.Register("TelGen", AccessLevel.Developer, GenTeleporter_OnCommand); + CommandSystem.Register("TelGenDelete", AccessLevel.Developer, TelGenDelete_OnCommand); } [Usage("TelGenDelete")] diff --git a/Projects/UOContent/Commands/Profiling.cs b/Projects/UOContent/Commands/Profiling.cs index fd6d0f4a3..c1c362fa8 100644 --- a/Projects/UOContent/Commands/Profiling.cs +++ b/Projects/UOContent/Commands/Profiling.cs @@ -8,7 +8,7 @@ namespace Server.Commands { public static class Profiling { - public static void Initialize() + public static void Configure() { CommandSystem.Register("DumpTimers", AccessLevel.Administrator, DumpTimers_OnCommand); CommandSystem.Register("CountObjects", AccessLevel.Administrator, CountObjects_OnCommand); diff --git a/Projects/UOContent/Commands/Properties.cs b/Projects/UOContent/Commands/Properties.cs index 197b9702b..02363ace0 100644 --- a/Projects/UOContent/Commands/Properties.cs +++ b/Projects/UOContent/Commands/Properties.cs @@ -5,8 +5,6 @@ using Server.Commands.Generic; using Server.Gumps; using Server.Targeting; using Server.Text; -using CPA = Server.CommandPropertyAttribute; - using static Server.Attributes; using static Server.Types; @@ -23,7 +21,7 @@ namespace Server.Commands public static class Properties { - public static void Initialize() + public static void Configure() { CommandSystem.Register("Props", AccessLevel.Counselor, Props_OnCommand); } diff --git a/Projects/UOContent/Commands/ResetRng.cs b/Projects/UOContent/Commands/ResetRng.cs index 4b2329694..97e35b792 100644 --- a/Projects/UOContent/Commands/ResetRng.cs +++ b/Projects/UOContent/Commands/ResetRng.cs @@ -4,7 +4,7 @@ namespace Server.Commands; public class ResetRng { - public static void Initialize() + public static void Configure() { CommandSystem.Register("ResetRng", AccessLevel.Administrator, ResetRng_OnCommand); } diff --git a/Projects/UOContent/Commands/ResetStaffDress.cs b/Projects/UOContent/Commands/ResetStaffDress.cs index 2a42357bd..6ca97f59e 100644 --- a/Projects/UOContent/Commands/ResetStaffDress.cs +++ b/Projects/UOContent/Commands/ResetStaffDress.cs @@ -6,7 +6,7 @@ namespace Server.Commands; public static class StaffDress { - public static void Initialize() + public static void Configure() { CommandSystem.Register("ResetStaffDress", AccessLevel.Counselor, StaffDress_OnCommand); } diff --git a/Projects/UOContent/Commands/ShardTime.cs b/Projects/UOContent/Commands/ShardTime.cs index 17de8d46a..944e2a8d1 100644 --- a/Projects/UOContent/Commands/ShardTime.cs +++ b/Projects/UOContent/Commands/ShardTime.cs @@ -4,7 +4,7 @@ namespace Server.Commands { public static class ShardTime { - public static void Initialize() + public static void Configure() { CommandSystem.Register("Time", AccessLevel.Player, Time_OnCommand); } diff --git a/Projects/UOContent/Commands/SignParser.cs b/Projects/UOContent/Commands/SignParser.cs index c98df5159..3257fcb2f 100644 --- a/Projects/UOContent/Commands/SignParser.cs +++ b/Projects/UOContent/Commands/SignParser.cs @@ -9,9 +9,9 @@ namespace Server.Commands { public static class SignParser { - public static void Initialize() + public static void Configure() { - CommandSystem.Register("SignGen", AccessLevel.Administrator, SignGen_OnCommand); + CommandSystem.Register("SignGen", AccessLevel.Developer, SignGen_OnCommand); } [Usage("SignGen")] diff --git a/Projects/UOContent/Commands/Skills.cs b/Projects/UOContent/Commands/Skills.cs index 1d1d76766..fd6b5c2c8 100644 --- a/Projects/UOContent/Commands/Skills.cs +++ b/Projects/UOContent/Commands/Skills.cs @@ -5,7 +5,7 @@ namespace Server.Commands { public static class SkillsCommand { - public static void Initialize() + public static void Configure() { CommandSystem.Register("SetSkill", AccessLevel.GameMaster, SetSkill_OnCommand); CommandSystem.Register("GetSkill", AccessLevel.GameMaster, GetSkill_OnCommand); diff --git a/Projects/UOContent/Commands/SkillsMenu.cs b/Projects/UOContent/Commands/SkillsMenu.cs index a69e55e1e..d1f3b3834 100644 --- a/Projects/UOContent/Commands/SkillsMenu.cs +++ b/Projects/UOContent/Commands/SkillsMenu.cs @@ -5,12 +5,7 @@ namespace Server.Commands { public static class SkillsMenu { - public static void Initialize() - { - Register(); - } - - public static void Register() + public static void Configure() { CommandSystem.Register("Skills", AccessLevel.Counselor, Skills_OnCommand); } diff --git a/Projects/UOContent/Commands/StaffAccess.cs b/Projects/UOContent/Commands/StaffAccess.cs index b853de0e5..af355866d 100644 --- a/Projects/UOContent/Commands/StaffAccess.cs +++ b/Projects/UOContent/Commands/StaffAccess.cs @@ -13,7 +13,7 @@ public static class StaffAccess [MethodImpl(MethodImplOptions.AggressiveInlining)] private static string AccountTag(Serial serial) => $"OriginalStaffAccess:{serial}"; - public static void Initialize() + public static void Configure() { CommandSystem.Register("StaffAccess", AccessLevel.Player, StaffAccess_OnCommand); @@ -47,7 +47,7 @@ public static class StaffAccess } [Usage("StaffAccess ")] - [Description("Overrides your access level.")] + [Description("Changes your access level. Only access levels at or below your current access level can be set. Use the same access level to reset.")] public static void StaffAccess_OnCommand(CommandEventArgs e) { var m = e.Mobile; diff --git a/Projects/UOContent/Commands/VisibilityList.cs b/Projects/UOContent/Commands/VisibilityList.cs index a18e44224..f2acafb48 100644 --- a/Projects/UOContent/Commands/VisibilityList.cs +++ b/Projects/UOContent/Commands/VisibilityList.cs @@ -8,7 +8,7 @@ namespace Server.Commands { public static class VisibilityList { - public static void Initialize() + public static void Configure() { EventSink.Login += OnLogin; diff --git a/Projects/UOContent/Commands/Wipe.cs b/Projects/UOContent/Commands/Wipe.cs index 4edd6a55c..8fbca1011 100644 --- a/Projects/UOContent/Commands/Wipe.cs +++ b/Projects/UOContent/Commands/Wipe.cs @@ -16,7 +16,7 @@ namespace Server.Commands All = Items | Mobiles | Multis } - public static void Initialize() + public static void Configure() { CommandSystem.Register("Wipe", AccessLevel.GameMaster, WipeAll_OnCommand); CommandSystem.Register("WipeItems", AccessLevel.GameMaster, WipeItems_OnCommand); diff --git a/Projects/UOContent/Engines/Advanced Search/AdvancedSearchCommand.cs b/Projects/UOContent/Engines/Advanced Search/AdvancedSearchCommand.cs index c752a1511..5365ebe51 100644 --- a/Projects/UOContent/Engines/Advanced Search/AdvancedSearchCommand.cs +++ b/Projects/UOContent/Engines/Advanced Search/AdvancedSearchCommand.cs @@ -2,16 +2,14 @@ namespace Server.Engines.AdvancedSearch; public static class AdvancedSearchCommand { - public static void Initialize() + public static void Configure() { - CommandSystem.Register("XmlFind", AccessLevel.Player, OnCommand); // For those old school peeps! - CommandSystem.Register("AdvancedSearch", AccessLevel.Player, OnCommand); - CommandSystem.Register("AdvSrch", AccessLevel.Player, OnCommand); - CommandSystem.Register("AS", AccessLevel.Player, OnCommand); + CommandSystem.Register("AdvancedSearch", AccessLevel.Administrator, OnCommand); // For those old school peeps! } [Usage("AdvancedSearch")] [Description("Opens the advanced search gump.")] + [Aliases("AdvSrch", "AS", "XmlFind")] private static void OnCommand(CommandEventArgs e) { var from = e.Mobile; diff --git a/Projects/UOContent/Engines/CannedEvil/ChampionCommands.cs b/Projects/UOContent/Engines/CannedEvil/ChampionCommands.cs index db6796bea..772e03e34 100644 --- a/Projects/UOContent/Engines/CannedEvil/ChampionCommands.cs +++ b/Projects/UOContent/Engines/CannedEvil/ChampionCommands.cs @@ -19,7 +19,7 @@ namespace Server.Engines.CannedEvil { public static class ChampionCommands { - public static void Initialize() + public static void Configure() { CommandSystem.Register("ClearChampByTarget", AccessLevel.Administrator, KillByTarget_OnCommand); CommandSystem.Register("ClearChampByRegion", AccessLevel.Administrator, KillByRegion_OnCommand); diff --git a/Projects/UOContent/Engines/CannedEvil/GenChamps.cs b/Projects/UOContent/Engines/CannedEvil/GenChamps.cs index 11787b854..0a3b526ea 100644 --- a/Projects/UOContent/Engines/CannedEvil/GenChamps.cs +++ b/Projects/UOContent/Engines/CannedEvil/GenChamps.cs @@ -23,9 +23,9 @@ namespace Server.Engines.CannedEvil { private static readonly ILogger logger = LogFactory.GetLogger(typeof(ChampionGenerator)); - public static void Initialize() + public static void Configure() { - CommandSystem.Register("GenChamps", AccessLevel.Owner, ChampGen_OnCommand); + CommandSystem.Register("GenChamps", AccessLevel.Developer, ChampGen_OnCommand); } private static readonly ChampionEntry[] LLLocations = { diff --git a/Projects/UOContent/Engines/ConPVP/DuelContext.cs b/Projects/UOContent/Engines/ConPVP/DuelContext.cs index 60b8f9e54..2b9402313 100644 --- a/Projects/UOContent/Engines/ConPVP/DuelContext.cs +++ b/Projects/UOContent/Engines/ConPVP/DuelContext.cs @@ -1231,7 +1231,7 @@ namespace Server.Engines.ConPVP Timer.StartTimer(TimeSpan.FromSeconds(10.0), Unregister); } - public static void Initialize() + public static void Configure() { EventSink.Speech += EventSink_Speech; EventSink.Login += EventSink_Login; diff --git a/Projects/UOContent/Engines/Craft/Core/Recipes.cs b/Projects/UOContent/Engines/Craft/Core/Recipes.cs index f2d8e4466..076a4bfef 100644 --- a/Projects/UOContent/Engines/Craft/Core/Recipes.cs +++ b/Projects/UOContent/Engines/Craft/Core/Recipes.cs @@ -35,7 +35,7 @@ public class Recipe public TextDefinition TextDefinition => _td ??= TextDefinition.Of(CraftItem.NameNumber, CraftItem.NameString); - public static void Initialize() + public static void Configure() { CommandSystem.Register("LearnAllRecipes", AccessLevel.GameMaster, LearnAllRecipes_OnCommand); CommandSystem.Register("ForgetAllRecipes", AccessLevel.GameMaster, ForgetAllRecipes_OnCommand); diff --git a/Projects/UOContent/Engines/Doom/GenGauntlet.cs b/Projects/UOContent/Engines/Doom/GenGauntlet.cs index d177c4fc4..ea37ee5f8 100644 --- a/Projects/UOContent/Engines/Doom/GenGauntlet.cs +++ b/Projects/UOContent/Engines/Doom/GenGauntlet.cs @@ -6,10 +6,10 @@ namespace Server.Engines.Doom { public static class GenGauntlet { - public static void Initialize() + public static void Configure() { - CommandSystem.Register("GenGauntlet", AccessLevel.Administrator, GenGauntlet_OnCommand); - CommandSystem.Register("RemGauntlet", AccessLevel.Administrator, RemoveGauntlet); + CommandSystem.Register("GenGauntlet", AccessLevel.Developer, GenGauntlet_OnCommand); + CommandSystem.Register("RemGauntlet", AccessLevel.Developer, RemoveGauntlet); } public static void RemoveGauntlet(CommandEventArgs e) diff --git a/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleController.cs b/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleController.cs index e2a49373b..7e97095b3 100644 --- a/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleController.cs +++ b/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleController.cs @@ -190,7 +190,7 @@ public partial class LeverPuzzleController : Item } } - public static void Initialize() + public static void Configure() { CommandSystem.Register("GenLeverPuzzle", AccessLevel.Administrator, GenLampPuzzle_OnCommand); } diff --git a/Projects/UOContent/Engines/Factions/Core/Faction.cs b/Projects/UOContent/Engines/Factions/Core/Faction.cs index 7e51601a0..15f7a79f4 100644 --- a/Projects/UOContent/Engines/Factions/Core/Faction.cs +++ b/Projects/UOContent/Engines/Factions/Core/Faction.cs @@ -639,14 +639,11 @@ namespace Server.Factions return true; } - public static void Initialize() + public static void Configure() { EventSink.Login += EventSink_Login; EventSink.Logout += EventSink_Logout; - Timer.DelayCall(TimeSpan.FromMinutes(1.0), TimeSpan.FromMinutes(10.0), HandleAtrophy); - Timer.DelayCall(TimeSpan.FromSeconds(30.0), TimeSpan.FromSeconds(30.0), ProcessTick); - CommandSystem.Register("FactionElection", AccessLevel.GameMaster, FactionElection_OnCommand); CommandSystem.Register("FactionCommander", AccessLevel.Administrator, FactionCommander_OnCommand); CommandSystem.Register("FactionItemReset", AccessLevel.Administrator, FactionItemReset_OnCommand); @@ -654,6 +651,12 @@ namespace Server.Factions CommandSystem.Register("FactionTownReset", AccessLevel.Administrator, FactionTownReset_OnCommand); } + public static void Initialize() + { + Timer.DelayCall(TimeSpan.FromMinutes(1.0), TimeSpan.FromMinutes(10.0), HandleAtrophy); + Timer.DelayCall(TimeSpan.FromSeconds(30.0), TimeSpan.FromSeconds(30.0), ProcessTick); + } + public static void FactionTownReset_OnCommand(CommandEventArgs e) { var monoliths = BaseMonolith.Monoliths; diff --git a/Projects/UOContent/Engines/Factions/Core/Generator.cs b/Projects/UOContent/Engines/Factions/Core/Generator.cs index 66e5efba2..6cd6fbe0f 100644 --- a/Projects/UOContent/Engines/Factions/Core/Generator.cs +++ b/Projects/UOContent/Engines/Factions/Core/Generator.cs @@ -4,9 +4,9 @@ namespace Server.Factions { public static class Generator { - public static void Initialize() + public static void Configure() { - CommandSystem.Register("GenerateFactions", AccessLevel.Administrator, GenerateFactions_OnCommand); + CommandSystem.Register("GenerateFactions", AccessLevel.Developer, GenerateFactions_OnCommand); } public static void GenerateFactions_OnCommand(CommandEventArgs e) diff --git a/Projects/UOContent/Engines/Factions/Core/Town.cs b/Projects/UOContent/Engines/Factions/Core/Town.cs index 7f26c67b0..2a13fa11f 100644 --- a/Projects/UOContent/Engines/Factions/Core/Town.cs +++ b/Projects/UOContent/Engines/Factions/Core/Town.cs @@ -420,6 +420,11 @@ namespace Server.Factions return true; } + public static void Configure() + { + CommandSystem.Register("GrantTownSilver", AccessLevel.Administrator, GrantTownSilver_OnCommand); + } + public static void Initialize() { var towns = Towns; @@ -429,8 +434,6 @@ namespace Server.Factions towns[i].Sheriff = towns[i].Sheriff; towns[i].Finance = towns[i].Finance; } - - CommandSystem.Register("GrantTownSilver", AccessLevel.Administrator, GrantTownSilver_OnCommand); } public bool IsSheriff(Mobile mob) => diff --git a/Projects/UOContent/Engines/Help/PageQueue.cs b/Projects/UOContent/Engines/Help/PageQueue.cs index 4c2cc8668..67d6816b7 100644 --- a/Projects/UOContent/Engines/Help/PageQueue.cs +++ b/Projects/UOContent/Engines/Help/PageQueue.cs @@ -121,7 +121,7 @@ namespace Server.Engines.Help public static List List { get; } = new(); - public static void Initialize() + public static void Configure() { CommandSystem.Register("Pages", AccessLevel.Counselor, Pages_OnCommand); } diff --git a/Projects/UOContent/Engines/Help/SpeechLog.cs b/Projects/UOContent/Engines/Help/SpeechLog.cs index a9736679e..aa944bd7a 100644 --- a/Projects/UOContent/Engines/Help/SpeechLog.cs +++ b/Projects/UOContent/Engines/Help/SpeechLog.cs @@ -29,7 +29,7 @@ namespace Server.Engines.Help IEnumerator IEnumerable.GetEnumerator() => m_Queue.GetEnumerator(); - public static void Initialize() + public static void Configure() { CommandSystem.Register("SpeechLog", AccessLevel.Counselor, SpeechLog_OnCommand); } diff --git a/Projects/UOContent/Engines/Khaldun/KhaldunGen.cs b/Projects/UOContent/Engines/Khaldun/KhaldunGen.cs index 4c1ea7639..3057a9c43 100644 --- a/Projects/UOContent/Engines/Khaldun/KhaldunGen.cs +++ b/Projects/UOContent/Engines/Khaldun/KhaldunGen.cs @@ -7,9 +7,9 @@ namespace Server.Commands { private static int m_Count; - public static void Initialize() + public static void Configure() { - CommandSystem.Register("GenKhaldun", AccessLevel.Administrator, GenKhaldun_OnCommand); + CommandSystem.Register("GenKhaldun", AccessLevel.Developer, GenKhaldun_OnCommand); } public static bool FindMorphItem(int x, int y, int z, int inactiveItemID, int activeItemID) diff --git a/Projects/UOContent/Engines/ML Quests/MLQuestSystem.cs b/Projects/UOContent/Engines/ML Quests/MLQuestSystem.cs index bfd5b3124..618569849 100644 --- a/Projects/UOContent/Engines/ML Quests/MLQuestSystem.cs +++ b/Projects/UOContent/Engines/ML Quests/MLQuestSystem.cs @@ -144,6 +144,16 @@ namespace Server.Engines.MLQuests public static void Configure() { Enabled = ServerConfiguration.GetOrUpdateSetting("questSystem.enableMLQuests", Core.ML); + + CommandSystem.Register("MLQuestsInfo", AccessLevel.Administrator, MLQuestsInfo_OnCommand); + CommandSystem.Register("SaveQuest", AccessLevel.Administrator, SaveQuest_OnCommand); + CommandSystem.Register("SaveAllQuests", AccessLevel.Administrator, SaveAllQuests_OnCommand); + CommandSystem.Register("InvalidQuestItems", AccessLevel.Administrator, InvalidQuestItems_OnCommand); + + TargetCommands.Register(new ViewQuestsCommand()); + TargetCommands.Register(new ViewContextCommand()); + + EventSink.QuestGumpRequest += EventSink_QuestGumpRequest; } public static void Initialize() @@ -165,16 +175,6 @@ namespace Server.Engines.MLQuests } MLQuestPersistence.EnsureExistence(); - - CommandSystem.Register("MLQuestsInfo", AccessLevel.Administrator, MLQuestsInfo_OnCommand); - CommandSystem.Register("SaveQuest", AccessLevel.Administrator, SaveQuest_OnCommand); - CommandSystem.Register("SaveAllQuests", AccessLevel.Administrator, SaveAllQuests_OnCommand); - CommandSystem.Register("InvalidQuestItems", AccessLevel.Administrator, InvalidQuestItems_OnCommand); - - TargetCommands.Register(new ViewQuestsCommand()); - TargetCommands.Register(new ViewContextCommand()); - - EventSink.QuestGumpRequest += EventSink_QuestGumpRequest; } [Usage("MLQuestsInfo"), diff --git a/Projects/UOContent/Engines/Party/Party.cs b/Projects/UOContent/Engines/Party/Party.cs index 0634efffb..03c28b130 100644 --- a/Projects/UOContent/Engines/Party/Party.cs +++ b/Projects/UOContent/Engines/Party/Party.cs @@ -96,7 +96,7 @@ namespace Server.Engines.PartySystem } } - public static void Initialize() + public static void Configure() { EventSink.Logout += EventSink_Logout; EventSink.Login += EventSink_Login; diff --git a/Projects/UOContent/Engines/Pathing/MovementPath.cs b/Projects/UOContent/Engines/Pathing/MovementPath.cs index f1ac2d8a6..1652dd053 100644 --- a/Projects/UOContent/Engines/Pathing/MovementPath.cs +++ b/Projects/UOContent/Engines/Pathing/MovementPath.cs @@ -56,7 +56,7 @@ namespace Server public static PathAlgorithm OverrideAlgorithm { get; set; } - public static void Initialize() + public static void Configure() { CommandSystem.Register("Path", AccessLevel.GameMaster, Path_OnCommand); } diff --git a/Projects/UOContent/Engines/Spawners/BaseSpawner.cs b/Projects/UOContent/Engines/Spawners/BaseSpawner.cs index 7f48b19e5..2bfba1957 100644 --- a/Projects/UOContent/Engines/Spawners/BaseSpawner.cs +++ b/Projects/UOContent/Engines/Spawners/BaseSpawner.cs @@ -8,8 +8,6 @@ using Server.Items; using Server.Json; using Server.Mobiles; using Server.Utilities; -using CPA = Server.CommandPropertyAttribute; - using static Server.Attributes; namespace Server.Engines.Spawners; diff --git a/Projects/UOContent/Engines/Spawners/Commands/ConvertPremiumSpawners.cs b/Projects/UOContent/Engines/Spawners/Commands/ConvertPremiumSpawners.cs index 9b95fa1f4..57238a1b3 100644 --- a/Projects/UOContent/Engines/Spawners/Commands/ConvertPremiumSpawners.cs +++ b/Projects/UOContent/Engines/Spawners/Commands/ConvertPremiumSpawners.cs @@ -29,7 +29,7 @@ namespace Server.Engines.Spawners { private static readonly ILogger logger = LogFactory.GetLogger(typeof(ConvertPremiumSpawners)); - public static void Initialize() + public static void Configure() { CommandSystem.Register("ConvertPremiumSpawners", AccessLevel.Developer, ConvertPremiumSpawners_OnCommand); } diff --git a/Projects/UOContent/Engines/Spawners/Commands/EditSpawnerCommand.cs b/Projects/UOContent/Engines/Spawners/Commands/EditSpawnerCommand.cs index e12dd4e9f..4c7f26646 100644 --- a/Projects/UOContent/Engines/Spawners/Commands/EditSpawnerCommand.cs +++ b/Projects/UOContent/Engines/Spawners/Commands/EditSpawnerCommand.cs @@ -23,7 +23,7 @@ namespace Server.Engines.Spawners public class EditSpawnCommand : BaseCommand { - public static void Initialize() + public static void Configure() { TargetCommands.Register(new EditSpawnCommand()); } diff --git a/Projects/UOContent/Engines/Spawners/Commands/ExportSpawnersCommand.cs b/Projects/UOContent/Engines/Spawners/Commands/ExportSpawnersCommand.cs index a1df43980..d9cc910b4 100644 --- a/Projects/UOContent/Engines/Spawners/Commands/ExportSpawnersCommand.cs +++ b/Projects/UOContent/Engines/Spawners/Commands/ExportSpawnersCommand.cs @@ -24,7 +24,7 @@ namespace Server.Engines.Spawners; public class ExportSpawnersCommand : BaseCommand { - public static void Initialize() + public static void Configure() { TargetCommands.Register(new ExportSpawnersCommand()); } diff --git a/Projects/UOContent/Engines/Spawners/Commands/GenerateSpawnersCommand.cs b/Projects/UOContent/Engines/Spawners/Commands/GenerateSpawnersCommand.cs index 74deb41cc..f0743e7de 100644 --- a/Projects/UOContent/Engines/Spawners/Commands/GenerateSpawnersCommand.cs +++ b/Projects/UOContent/Engines/Spawners/Commands/GenerateSpawnersCommand.cs @@ -32,7 +32,7 @@ namespace Server.Engines.Spawners { private static readonly ILogger logger = LogFactory.GetLogger(typeof(GenerateSpawnersCommand)); - public static void Initialize() + public static void Configure() { CommandSystem.Register("GenerateSpawners", AccessLevel.Developer, GenerateSpawners_OnCommand); } diff --git a/Projects/UOContent/Engines/Spawners/Commands/RespawnCommand.cs b/Projects/UOContent/Engines/Spawners/Commands/RespawnCommand.cs index 8dbde7681..b9b386dc5 100644 --- a/Projects/UOContent/Engines/Spawners/Commands/RespawnCommand.cs +++ b/Projects/UOContent/Engines/Spawners/Commands/RespawnCommand.cs @@ -21,7 +21,7 @@ namespace Server.Engines.Spawners { public class RespawnCommand : BaseCommand { - public static void Initialize() + public static void Configure() { TargetCommands.Register(new RespawnCommand()); } diff --git a/Projects/UOContent/Engines/Spawners/Commands/SpawnPropsCommand.cs b/Projects/UOContent/Engines/Spawners/Commands/SpawnPropsCommand.cs index 72f59f64a..0e6ca82ab 100644 --- a/Projects/UOContent/Engines/Spawners/Commands/SpawnPropsCommand.cs +++ b/Projects/UOContent/Engines/Spawners/Commands/SpawnPropsCommand.cs @@ -24,7 +24,7 @@ namespace Server.Engines.Spawners { public class SpawnPropsCommand : BaseCommand { - public static void Initialize() + public static void Configure() { TargetCommands.Register(new SpawnPropsCommand()); } diff --git a/Projects/UOContent/Engines/Spawners/SpawnPropsGump.cs b/Projects/UOContent/Engines/Spawners/SpawnPropsGump.cs index c43fb6e1e..edfb99ec0 100644 --- a/Projects/UOContent/Engines/Spawners/SpawnPropsGump.cs +++ b/Projects/UOContent/Engines/Spawners/SpawnPropsGump.cs @@ -19,7 +19,6 @@ using Server.Engines.Spawners; using Server.Mobiles; using Server.Network; using Server.Text; -using CPA = Server.CommandPropertyAttribute; namespace Server.Gumps { diff --git a/Projects/UOContent/Engines/Spawners/SpawnerControllerGump.cs b/Projects/UOContent/Engines/Spawners/SpawnerControllerGump.cs index 2437c125d..387acc492 100644 --- a/Projects/UOContent/Engines/Spawners/SpawnerControllerGump.cs +++ b/Projects/UOContent/Engines/Spawners/SpawnerControllerGump.cs @@ -32,7 +32,7 @@ public class SpawnerControllerGump : GumpGrid public static int GetButtonID(int type, int index) => 1 + type + index * TypeCount; - public static void Initialize() + public static void Configure() { CommandSystem.Register("Spawn", AccessLevel.GameMaster, OpenSpawnGump_OnCommand); } diff --git a/Projects/UOContent/Engines/Stealables/StealableArtifacts.cs b/Projects/UOContent/Engines/Stealables/StealableArtifacts.cs index 80d4fcdd4..4257a2480 100644 --- a/Projects/UOContent/Engines/Stealables/StealableArtifacts.cs +++ b/Projects/UOContent/Engines/Stealables/StealableArtifacts.cs @@ -21,6 +21,9 @@ public class StealableArtifacts : GenericPersistence public static void Configure() { _stealableArtifactsPersistence = new StealableArtifacts(); + + CommandSystem.Register("GenStealArties", AccessLevel.Developer, GenStealArties_OnCommand); + CommandSystem.Register("RemoveStealArties", AccessLevel.Developer, RemoveStealArties_OnCommand); } public StealableArtifacts() : base("StealableArtifacts", 10) @@ -192,12 +195,6 @@ public class StealableArtifacts : GenericPersistence private static int GetLampPostHue() => Utility.RandomDouble() < 0.9 ? 0 : Utility.RandomList(0x455, 0x47E, 0x482, 0x486, 0x48F, 0x4F2, 0x58C, 0x66C); - public static void Initialize() - { - CommandSystem.Register("GenStealArties", AccessLevel.Administrator, GenStealArties_OnCommand); - CommandSystem.Register("RemoveStealArties", AccessLevel.Administrator, RemoveStealArties_OnCommand); - } - [Usage("GenStealArties"), Description("Generates the stealable artifacts spawner.")] private static void GenStealArties_OnCommand(CommandEventArgs args) { diff --git a/Projects/UOContent/Gumps/AddDoorGump.cs b/Projects/UOContent/Gumps/AddDoorGump.cs index c10879225..7865aef4d 100644 --- a/Projects/UOContent/Gumps/AddDoorGump.cs +++ b/Projects/UOContent/Gumps/AddDoorGump.cs @@ -97,7 +97,7 @@ namespace Server.Gumps } } - public static void Initialize() + public static void Configure() { CommandSystem.Register("AddDoor", AccessLevel.GameMaster, AddDoor_OnCommand); } diff --git a/Projects/UOContent/Gumps/AdminGump.cs b/Projects/UOContent/Gumps/AdminGump.cs index 810dc22e8..607c65281 100644 --- a/Projects/UOContent/Gumps/AdminGump.cs +++ b/Projects/UOContent/Gumps/AdminGump.cs @@ -1421,7 +1421,7 @@ namespace Server.Gumps }; } - public static void Initialize() + public static void Configure() { CommandSystem.Register("Admin", AccessLevel.Administrator, Admin_OnCommand); } diff --git a/Projects/UOContent/Gumps/CommentsGump.cs b/Projects/UOContent/Gumps/CommentsGump.cs index 24504383c..c795d5e38 100644 --- a/Projects/UOContent/Gumps/CommentsGump.cs +++ b/Projects/UOContent/Gumps/CommentsGump.cs @@ -57,7 +57,7 @@ namespace Server.Gumps } } - public static void Initialize() + public static void Configure() { CommandSystem.Register("Comments", AccessLevel.Counselor, Comments_OnCommand); } diff --git a/Projects/UOContent/Gumps/Props/PropsGump.cs b/Projects/UOContent/Gumps/Props/PropsGump.cs index caced7f81..5867f6811 100644 --- a/Projects/UOContent/Gumps/Props/PropsGump.cs +++ b/Projects/UOContent/Gumps/Props/PropsGump.cs @@ -4,8 +4,6 @@ using System.Linq; using System.Reflection; using Server.Commands.Generic; using Server.Network; -using CPA = Server.CommandPropertyAttribute; - using static Server.Types; using static Server.Attributes; using static Server.Gumps.PropsConfig; diff --git a/Projects/UOContent/Gumps/ToTAdminGump.cs b/Projects/UOContent/Gumps/ToTAdminGump.cs index e1d61fcea..3e8cd5972 100644 --- a/Projects/UOContent/Gumps/ToTAdminGump.cs +++ b/Projects/UOContent/Gumps/ToTAdminGump.cs @@ -115,7 +115,7 @@ namespace Server.Gumps } } - public static void Initialize() + public static void Configure() { CommandSystem.Register("ToTAdmin", AccessLevel.Administrator, ToTAdmin_OnCommand); } diff --git a/Projects/UOContent/Gumps/ViewHousesGump.cs b/Projects/UOContent/Gumps/ViewHousesGump.cs index 09078026a..4086386c0 100644 --- a/Projects/UOContent/Gumps/ViewHousesGump.cs +++ b/Projects/UOContent/Gumps/ViewHousesGump.cs @@ -155,7 +155,7 @@ namespace Server.Gumps } } - public static void Initialize() + public static void Configure() { CommandSystem.Register("ViewHouses", AccessLevel.GameMaster, ViewHouses_OnCommand); } diff --git a/Projects/UOContent/Gumps/WhoGump.cs b/Projects/UOContent/Gumps/WhoGump.cs index 0833afe3b..c03672ec2 100644 --- a/Projects/UOContent/Gumps/WhoGump.cs +++ b/Projects/UOContent/Gumps/WhoGump.cs @@ -41,7 +41,7 @@ namespace Server.Gumps Initialize(page); } - public static void Initialize() + public static void Configure() { CommandSystem.Register("Who", AccessLevel.Counselor, WhoList_OnCommand); CommandSystem.Register("WhoList", AccessLevel.Counselor, WhoList_OnCommand); diff --git a/Projects/UOContent/Items/Addons/SHTeleporter.cs b/Projects/UOContent/Items/Addons/SHTeleporter.cs index 9dbd7303d..38102dd4c 100644 --- a/Projects/UOContent/Items/Addons/SHTeleporter.cs +++ b/Projects/UOContent/Items/Addons/SHTeleporter.cs @@ -163,9 +163,9 @@ namespace Server.Items public override bool ShareHue => false; - public static void Initialize() + public static void Configure() { - CommandSystem.Register("SHTelGen", AccessLevel.Administrator, SHTelGen_OnCommand); + CommandSystem.Register("SHTelGen", AccessLevel.Developer, SHTelGen_OnCommand); } [Usage("SHTelGen"), Description("Generates solen hives teleporters.")] diff --git a/Projects/UOContent/Items/Construction/Doors/BaseDoor.cs b/Projects/UOContent/Items/Construction/Doors/BaseDoor.cs index f4933d77c..50cc03059 100644 --- a/Projects/UOContent/Items/Construction/Doors/BaseDoor.cs +++ b/Projects/UOContent/Items/Construction/Doors/BaseDoor.cs @@ -123,7 +123,7 @@ public abstract partial class BaseDoor : Item, ILockable, ITelekinesisable Use(from); } - public static void Initialize() + public static void Configure() { EventSink.OpenDoorMacroUsed += EventSink_OpenDoorMacroUsed; diff --git a/Projects/UOContent/Items/Containers/MarkContainer.cs b/Projects/UOContent/Items/Containers/MarkContainer.cs index c193f967e..fa3f7e440 100644 --- a/Projects/UOContent/Items/Containers/MarkContainer.cs +++ b/Projects/UOContent/Items/Containers/MarkContainer.cs @@ -106,9 +106,9 @@ public partial class MarkContainer : LockableContainer [CommandProperty(AccessLevel.GameMaster)] public DateTime NextRelock => _relockTimer.Next; - public static void Initialize() + public static void Configure() { - CommandSystem.Register("SecretLocGen", AccessLevel.Administrator, SecretLocGen_OnCommand); + CommandSystem.Register("SecretLocGen", AccessLevel.Developer, SecretLocGen_OnCommand); } [Usage("SecretLocGen")] diff --git a/Projects/UOContent/Items/Misc/FlippableAttribute.cs b/Projects/UOContent/Items/Misc/FlippableAttribute.cs index 8ded96613..4a78c9e1e 100644 --- a/Projects/UOContent/Items/Misc/FlippableAttribute.cs +++ b/Projects/UOContent/Items/Misc/FlippableAttribute.cs @@ -5,7 +5,7 @@ namespace Server.Items; public static class FlipCommandHandlers { - public static void Initialize() + public static void Configure() { CommandSystem.Register("Flip", AccessLevel.GameMaster, Flip_OnCommand); } diff --git a/Projects/UOContent/Items/Misc/PublicMoongate.cs b/Projects/UOContent/Items/Misc/PublicMoongate.cs index 459d40d22..9409ed101 100644 --- a/Projects/UOContent/Items/Misc/PublicMoongate.cs +++ b/Projects/UOContent/Items/Misc/PublicMoongate.cs @@ -95,9 +95,9 @@ public partial class PublicMoongate : Item return true; } - public static void Initialize() + public static void Configure() { - CommandSystem.Register("MoonGen", AccessLevel.Administrator, MoonGen_OnCommand); + CommandSystem.Register("MoonGen", AccessLevel.Developer, MoonGen_OnCommand); } [Usage("MoonGen"), Description("Generates public moongates. Removes all old moongates.")] diff --git a/Projects/UOContent/Items/Misc/WayPoint.cs b/Projects/UOContent/Items/Misc/WayPoint.cs index 8da268796..f193b59c8 100644 --- a/Projects/UOContent/Items/Misc/WayPoint.cs +++ b/Projects/UOContent/Items/Misc/WayPoint.cs @@ -26,7 +26,7 @@ public partial class WayPoint : Item public override string DefaultName => "AI Way Point"; - public static void Initialize() + public static void Configure() { CommandSystem.Register("WayPointSeq", AccessLevel.GameMaster, WayPointSeq_OnCommand); } diff --git a/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs b/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs index 94faaf767..d21ab9cbe 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs @@ -213,7 +213,7 @@ public partial class Spellbook : Item, ICraftable, ISlayer, IAosItem return quality; } - public static void Initialize() + public static void Configure() { EventSink.OpenSpellbookRequest += EventSink_OpenSpellbookRequest; EventSink.CastSpellRequest += EventSink_CastSpellRequest; diff --git a/Projects/UOContent/Items/Suits/StaffRobe.cs b/Projects/UOContent/Items/Suits/StaffRobe.cs index 9d98abf7e..90c59ca3c 100644 --- a/Projects/UOContent/Items/Suits/StaffRobe.cs +++ b/Projects/UOContent/Items/Suits/StaffRobe.cs @@ -14,7 +14,7 @@ public partial class StaffRobe : BaseSuit AccessLevel.Seer => 0x1D3, AccessLevel.Administrator => 0x488, AccessLevel.Developer => 11, - AccessLevel.Owner => 0x496, + AccessLevel.Owner => 0x54F, }; } diff --git a/Projects/UOContent/Items/Talismans/BaseTalisman.cs b/Projects/UOContent/Items/Talismans/BaseTalisman.cs index 943de5041..86f56d28d 100644 --- a/Projects/UOContent/Items/Talismans/BaseTalisman.cs +++ b/Projects/UOContent/Items/Talismans/BaseTalisman.cs @@ -301,7 +301,7 @@ public partial class BaseTalisman : Item, IAosItem [SerializableFieldSaveFlag(10)] public bool ShouldSerializeCharges() => _charges != 0; - public static void Initialize() + public static void Configure() { CommandSystem.Register("RandomTalisman", AccessLevel.GameMaster, RandomTalisman_OnCommand); } diff --git a/Projects/UOContent/Misc/AutoRestart.cs b/Projects/UOContent/Misc/AutoRestart.cs index b281b9349..c91605068 100644 --- a/Projects/UOContent/Misc/AutoRestart.cs +++ b/Projects/UOContent/Misc/AutoRestart.cs @@ -54,10 +54,6 @@ namespace Server.Misc public static void Configure() { Enabled = ServerConfiguration.GetOrUpdateSetting("world.enableAutoRestart", false); - } - - public static void Initialize() - { CommandSystem.Register("Restart", AccessLevel.Administrator, Restart_OnCommand); } diff --git a/Projects/UOContent/Misc/DoorGenerator.cs b/Projects/UOContent/Misc/DoorGenerator.cs index 1a3a495d0..0ec27c04f 100644 --- a/Projects/UOContent/Misc/DoorGenerator.cs +++ b/Projects/UOContent/Misc/DoorGenerator.cs @@ -332,9 +332,9 @@ namespace Server private static Map m_Map; private static int m_Count; - public static void Initialize() + public static void Configure() { - CommandSystem.Register("DoorGen", AccessLevel.Administrator, DoorGen_OnCommand); + CommandSystem.Register("DoorGen", AccessLevel.Developer, DoorGen_OnCommand); } [Usage("DoorGen"), Description("Generates doors by analyzing the map. Slow.")] diff --git a/Projects/UOContent/Misc/LanguageStatistics.cs b/Projects/UOContent/Misc/LanguageStatistics.cs index f9c1ace53..677cbd05d 100644 --- a/Projects/UOContent/Misc/LanguageStatistics.cs +++ b/Projects/UOContent/Misc/LanguageStatistics.cs @@ -180,7 +180,7 @@ namespace Server.Misc return $"Unknown code {code}"; } - public static void Initialize() + public static void Configure() { CommandSystem.Register("LanguageStatistics", AccessLevel.Administrator, LanguageStatistics_OnCommand); } diff --git a/Projects/UOContent/Misc/LightCycle.cs b/Projects/UOContent/Misc/LightCycle.cs index 301952f9f..f585a6732 100644 --- a/Projects/UOContent/Misc/LightCycle.cs +++ b/Projects/UOContent/Misc/LightCycle.cs @@ -30,12 +30,15 @@ namespace Server } } + public static void Configure() + { + EventSink.Login += OnLogin; + CommandSystem.Register("GlobalLight", AccessLevel.GameMaster, Light_OnCommand); + } + public static void Initialize() { new LightCycleTimer().Start(); - EventSink.Login += OnLogin; - - CommandSystem.Register("GlobalLight", AccessLevel.GameMaster, Light_OnCommand); } [Usage("GlobalLight "), Description("Sets the current global light level.")] diff --git a/Projects/UOContent/Misc/NameVerification.cs b/Projects/UOContent/Misc/NameVerification.cs index 5c0b7f654..e64c41bf9 100644 --- a/Projects/UOContent/Misc/NameVerification.cs +++ b/Projects/UOContent/Misc/NameVerification.cs @@ -100,7 +100,7 @@ namespace Server.Misc "origin" }; - public static void Initialize() + public static void Configure() { CommandSystem.Register("ValidateName", AccessLevel.Administrator, ValidateName_OnCommand); } diff --git a/Projects/UOContent/Misc/PacketThrottles.cs b/Projects/UOContent/Misc/PacketThrottles.cs index cb695c6e4..b81ade953 100644 --- a/Projects/UOContent/Misc/PacketThrottles.cs +++ b/Projects/UOContent/Misc/PacketThrottles.cs @@ -12,13 +12,15 @@ namespace Server.Network private static readonly int[] Delays = new int[0x100]; private const string ThrottlesConfiguration = "Configuration/throttles.json"; - public static unsafe void Initialize() + public static void Configure() { CommandSystem.Register("GetThrottle", AccessLevel.Administrator, GetThrottle); CommandSystem.Register("SetThrottle", AccessLevel.Administrator, SetThrottle); + } - var configPath = ThrottlesConfiguration; - var path = Path.Join(Core.BaseDirectory, configPath); + public static unsafe void Initialize() + { + var path = Path.Join(Core.BaseDirectory, ThrottlesConfiguration); if (File.Exists(path)) { @@ -28,7 +30,7 @@ namespace Server.Network if (!Utility.ToInt32(k, out var packetId)) { Utility.PushColor(ConsoleColor.DarkYellow); - Console.WriteLine("Packet Throttles: Error deserializing {0} from {1}", k, configPath); + Console.WriteLine("Packet Throttles: Error deserializing {0} from {1}", k, ThrottlesConfiguration); Utility.PopColor(); continue; } @@ -38,8 +40,8 @@ namespace Server.Network } else { - Delays[0x03] = 25; // Speech - Delays[0xAD] = 25; // Speech + Delays[0x03] = 25; // Speech + Delays[0xAD] = 25; // Speech Delays[0x75] = 500; // Rename request } diff --git a/Projects/UOContent/Misc/ToggleItem.cs b/Projects/UOContent/Misc/ToggleItem.cs index 29c98d10c..cf6d475e3 100644 --- a/Projects/UOContent/Misc/ToggleItem.cs +++ b/Projects/UOContent/Misc/ToggleItem.cs @@ -29,7 +29,7 @@ namespace Server.Items [CommandProperty(AccessLevel.GameMaster)] public bool PlayersCanToggle { get; set; } - public static void Initialize() + public static void Configure() { TargetCommands.Register(new ToggleCommand()); } diff --git a/Projects/UOContent/Mobiles/Townfolk/TownCrier.cs b/Projects/UOContent/Mobiles/Townfolk/TownCrier.cs index fbe99d3bc..4bb526439 100644 --- a/Projects/UOContent/Mobiles/Townfolk/TownCrier.cs +++ b/Projects/UOContent/Mobiles/Townfolk/TownCrier.cs @@ -80,7 +80,7 @@ public class GlobalTownCrierEntryList : ITownCrierEntryList } } - public static void Initialize() + public static void Configure() { CommandSystem.Register("TownCriers", AccessLevel.GameMaster, TownCriers_OnCommand); } diff --git a/Projects/UOContent/Network/NetworkCommands.cs b/Projects/UOContent/Network/NetworkCommands.cs index ce35f5af2..3fa9cfa84 100644 --- a/Projects/UOContent/Network/NetworkCommands.cs +++ b/Projects/UOContent/Network/NetworkCommands.cs @@ -6,7 +6,7 @@ namespace Server.Network { public class PacketLoggingCommand : BaseCommand { - public static void Initialize() + public static void Configure() { TargetCommands.Register(new PacketLoggingCommand()); } diff --git a/Projects/UOContent/Regions/GuardedRegion.cs b/Projects/UOContent/Regions/GuardedRegion.cs index 1f1af15c6..7ba2671c8 100644 --- a/Projects/UOContent/Regions/GuardedRegion.cs +++ b/Projects/UOContent/Regions/GuardedRegion.cs @@ -49,7 +49,7 @@ public class GuardedRegion : BaseRegion public virtual bool IsDisabled() => GuardsDisabled; - public static void Initialize() + public static void Configure() { CommandSystem.Register("CheckGuarded", AccessLevel.GameMaster, CheckGuarded_OnCommand); CommandSystem.Register("SetGuarded", AccessLevel.Administrator, SetGuarded_OnCommand); diff --git a/Projects/UOContent/World Saves/SaveCommands.cs b/Projects/UOContent/World Saves/SaveCommands.cs index 7a38576a7..21da36a1f 100644 --- a/Projects/UOContent/World Saves/SaveCommands.cs +++ b/Projects/UOContent/World Saves/SaveCommands.cs @@ -4,7 +4,7 @@ namespace Server.Commands { public static class SaveCommands { - public static void Initialize() + public static void Configure() { CommandSystem.Register("Save", AccessLevel.Administrator, Save_OnCommand); CommandSystem.Register("SetSaves", AccessLevel.Administrator, SetAutoSaves_OnCommand); diff --git a/docs/commands/commands.7z b/docs/commands/commands.7z new file mode 100644 index 0000000000000000000000000000000000000000..eea03578afc6f6c32e9256d0ba036826da867bd4 GIT binary patch literal 11143 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 Z6bb