diff --git a/Projects/Server/Commands.cs b/Projects/Server/Commands.cs index 503b24814..6c5de7deb 100644 --- a/Projects/Server/Commands.cs +++ b/Projects/Server/Commands.cs @@ -26,65 +26,20 @@ namespace Server public int Length => Arguments.Length; - public string GetString(int index) - { - if (index < 0 || index >= Arguments.Length) - { - return ""; - } + public string GetString(int index) => index < 0 || index >= Arguments.Length ? "" : Arguments[index]; - return Arguments[index]; - } + public int GetInt32(int index) => index < 0 || index >= Arguments.Length ? 0 : Utility.ToInt32(Arguments[index]); - public int GetInt32(int index) - { - if (index < 0 || index >= Arguments.Length) - { - return 0; - } + public uint GetUInt32(int index) => + index < 0 || index >= Arguments.Length ? 0 : Utility.ToUInt32(Arguments[index]); - return Utility.ToInt32(Arguments[index]); - } + public bool GetBoolean(int index) => index >= 0 && index < Arguments.Length && Utility.ToBoolean(Arguments[index]); - public uint GetUInt32(int index) - { - if (index < 0 || index >= Arguments.Length) - { - return 0; - } + public double GetDouble(int index) => + index < 0 || index >= Arguments.Length ? 0.0 : Utility.ToDouble(Arguments[index]); - return Utility.ToUInt32(Arguments[index]); - } - - public bool GetBoolean(int index) - { - if (index < 0 || index >= Arguments.Length) - { - return false; - } - - return Utility.ToBoolean(Arguments[index]); - } - - public double GetDouble(int index) - { - if (index < 0 || index >= Arguments.Length) - { - return 0.0; - } - - return Utility.ToDouble(Arguments[index]); - } - - public TimeSpan GetTimeSpan(int index) - { - if (index < 0 || index >= Arguments.Length) - { - return TimeSpan.Zero; - } - - return Utility.ToTimeSpan(Arguments[index]); - } + public TimeSpan GetTimeSpan(int index) => + index < 0 || index >= Arguments.Length ? TimeSpan.Zero : Utility.ToTimeSpan(Arguments[index]); } public static partial class EventSink @@ -137,27 +92,7 @@ namespace Server } } - public record CommandInfo - { - public CommandInfo(AccessLevel accessLevel, string name, string[] aliases, string usage, string description) - { - AccessLevel = accessLevel; - Name = name; - Aliases = aliases; - Usage = usage; - Description = description; - } - - public AccessLevel AccessLevel { get; } - - public string Name { get; } - - public string[] Aliases { get; } - - public string Usage { get; } - - public string Description { get; } - } + public record CommandInfo(AccessLevel AccessLevel, string Name, string[] Aliases, string Usage, string Description); public class CommandInfoSorter : IComparer { diff --git a/Projects/UOContent/Commands/Batch.cs b/Projects/UOContent/Commands/Batch.cs index 84aeca315..8e7ce6b73 100644 --- a/Projects/UOContent/Commands/Batch.cs +++ b/Projects/UOContent/Commands/Batch.cs @@ -177,7 +177,8 @@ namespace Server.Commands CommandSystem.Register("Batch", AccessLevel.Counselor, Batch_OnCommand); } - [Usage("Batch"), Description("Allows multiple commands to be run at the same time.")] + [Usage("Batch")] + [Description("Allows multiple commands to be run at the same time.")] public static void Batch_OnCommand(CommandEventArgs e) { e.Mobile.SendGump(new BatchGump(e.Mobile, new Batch())); diff --git a/Projects/UOContent/Commands/DragEffects.cs b/Projects/UOContent/Commands/DragEffects.cs index d9ef33a38..d67d0d393 100644 --- a/Projects/UOContent/Commands/DragEffects.cs +++ b/Projects/UOContent/Commands/DragEffects.cs @@ -7,7 +7,8 @@ namespace Server.Commands CommandSystem.Register("DragEffects", AccessLevel.Developer, DragEffects_OnCommand); } - [Usage("DragEffects [enable=false]"), Description("Enables or disables the item drag and drop effects.")] + [Usage("DragEffects [enable=false]")] + [Description("Enables or disables the item drag and drop effects.")] public static void DragEffects_OnCommand(CommandEventArgs e) { if (e.Length == 0) diff --git a/Projects/UOContent/Commands/Dupe.cs b/Projects/UOContent/Commands/Dupe.cs index db7bfdbde..3cbf9de10 100644 --- a/Projects/UOContent/Commands/Dupe.cs +++ b/Projects/UOContent/Commands/Dupe.cs @@ -13,7 +13,8 @@ namespace Server.Commands CommandSystem.Register("DupeInBag", AccessLevel.GameMaster, DupeInBag_OnCommand); } - [Usage("Dupe [amount]"), Description("Dupes a targeted item.")] + [Usage("Dupe [amount]")] + [Description("Dupes a targeted item.")] private static void Dupe_OnCommand(CommandEventArgs e) { var amount = 1; @@ -26,7 +27,8 @@ namespace Server.Commands e.Mobile.SendMessage("What do you wish to dupe?"); } - [Usage("DupeInBag "), Description("Dupes an item at it's current location (count) number of times.")] + [Usage("DupeInBag ")] + [Description("Dupes an item at it's current location (count) number of times.")] private static void DupeInBag_OnCommand(CommandEventArgs e) { var amount = 1; diff --git a/Projects/UOContent/Commands/Handlers.cs b/Projects/UOContent/Commands/Handlers.cs index 98279f8ed..811bacff9 100644 --- a/Projects/UOContent/Commands/Handlers.cs +++ b/Projects/UOContent/Commands/Handlers.cs @@ -73,7 +73,8 @@ namespace Server.Commands CommandSystem.Register(command, access, handler); } - [Usage("SpeedBoost [true|false]"), Description("Enables a speed boost for the invoker. Disable with parameters.")] + [Usage("SpeedBoost [true|false]")] + [Description("Enables a speed boost for the invoker. Disable with parameters.")] private static void SpeedBoost_OnCommand(CommandEventArgs e) { var from = e.Mobile; @@ -97,7 +98,8 @@ namespace Server.Commands } } - [Usage("Where"), Description("Tells the commanding player his coordinates, region, and facet.")] + [Usage("Where")] + [Description("Tells the commanding player his coordinates, region, and facet.")] public static void Where_OnCommand(CommandEventArgs e) { var from = e.Mobile; @@ -127,9 +129,8 @@ namespace Server.Commands } } - [Usage("DropHolding"), Description( - "Drops the item, if any, that a targeted player is holding. The item is placed into their backpack, or if that's full, at their feet." - )] + [Usage("DropHolding")] + [Description("Drops the item, if any, that a targeted player is holding. The item is placed into their backpack, or if that's full, at their feet.")] public static void DropHolding_OnCommand(CommandEventArgs e) { e.Mobile.BeginTarget(-1, false, TargetFlags.None, DropHolding_OnTarget); @@ -274,7 +275,8 @@ namespace Server.Commands } } - [Usage("GetFollowers"), Description("Teleports all pets of a targeted player to your location.")] + [Usage("GetFollowers")] + [Description("Teleports all pets of a targeted player to your location.")] public static void GetFollowers_OnCommand(CommandEventArgs e) { e.Mobile.BeginTarget(-1, false, TargetFlags.None, GetFollowers_OnTarget); @@ -374,9 +376,8 @@ namespace Server.Commands e.Mobile.Target = new ViewEqTarget(); } - [Usage("Sound [toAll=true]"), Description( - "Plays a sound to players within 12 tiles of you. The (toAll) argument specifies to everyone, or just those who can see you." - )] + [Usage("Sound [toAll=true]")] + [Description("Plays a sound to players within 12 tiles of you. The (toAll) argument specifies to everyone, or just those who can see you.")] public static void Sound_OnCommand(CommandEventArgs e) { if (e.Length == 1) @@ -423,7 +424,8 @@ namespace Server.Commands } } - [Usage("Echo "), Description("Relays (text) as a system message.")] + [Usage("Echo ")] + [Description("Relays (text) as a system message.")] public static void Echo_OnCommand(CommandEventArgs e) { var toEcho = e.ArgString.Trim(); @@ -438,19 +440,22 @@ namespace Server.Commands } } - [Usage("Bank"), Description("Opens the bank box of a given target.")] + [Usage("Bank")] + [Description("Opens the bank box of a given target.")] public static void Bank_OnCommand(CommandEventArgs e) { e.Mobile.Target = new BankTarget(); } - [Usage("Client"), Description("Opens the client gump menu for a given player.")] + [Usage("Client")] + [Description("Opens the client gump menu for a given player.")] private static void Client_OnCommand(CommandEventArgs e) { e.Mobile.Target = new ClientTarget(); } - [Usage("Move"), Description("Repositions a targeted item or mobile.")] + [Usage("Move")] + [Description("Repositions a targeted item or mobile.")] private static void Move_OnCommand(CommandEventArgs e) { e.Mobile.Target = new PickMoveTarget(); @@ -473,9 +478,8 @@ namespace Server.Commands return validMap; } - [Usage("Go [name | serial | (x y [z]) | (deg min (N | S) deg min (E | W))]"), Description( - "With no arguments, this command brings up the go menu. With one argument, (name), you are moved to that regions \"go location.\" Or, if a numerical value is specified for one argument, (serial), you are moved to that object. Two or three arguments, (x y [z]), will move your character to that location. When six arguments are specified, (deg min (N | S) deg min (E | W)), your character will go to an approximate of those sextant coordinates." - )] + [Usage("Go [name | serial | (x y [z]) | (deg min (N | S) deg min (E | W))]")] + [Description("With no arguments, this command brings up the go menu. With one argument, (name), you are moved to that regions \"go location.\" Or, if a numerical value is specified for one argument, (serial), you are moved to that object. Two or three arguments, (x y [z]), will move your character to that location. When six arguments are specified, (deg min (N | S) deg min (E | W)), your character will go to an approximate of those sextant coordinates.")] private static void Go_OnCommand(CommandEventArgs e) { var from = e.Mobile; @@ -685,7 +689,8 @@ namespace Server.Commands } } - [Usage("Help"), Description("Lists all available commands.")] + [Usage("Help")] + [Description("Lists all available commands.")] public static void Help_OnCommand(CommandEventArgs e) { var m = e.Mobile; @@ -732,13 +737,15 @@ namespace Server.Commands } } - [Usage("SMsg "), Aliases("S", "SM"), Description("Broadcasts a message to all online staff.")] + [Usage("SMsg "), Aliases("S", "SM")] + [Description("Broadcasts a message to all online staff.")] public static void StaffMessage_OnCommand(CommandEventArgs e) { BroadcastMessage(AccessLevel.Counselor, e.Mobile.SpeechHue, $"[{e.Mobile.Name}] {e.ArgString}"); } - [Usage("BCast "), Aliases("B", "BC"), Description("Broadcasts a message to everyone online.")] + [Usage("BCast "), Aliases("B", "BC")] + [Description("Broadcasts a message to everyone online.")] public static void BroadcastMessage_OnCommand(CommandEventArgs e) { BroadcastMessage(AccessLevel.Player, 0x482, $"Staff message from {e.Mobile.Name}:"); @@ -758,7 +765,8 @@ namespace Server.Commands } } - [Usage("AutoPageNotify"), Aliases("APN"), Description("Toggles your auto-page-notify status.")] + [Usage("AutoPageNotify"), Aliases("APN")] + [Description("Toggles your auto-page-notify status.")] public static void APN_OnCommand(CommandEventArgs e) { var m = e.Mobile; @@ -789,7 +797,8 @@ namespace Server.Commands } } - [Usage("Cast "), Description("Casts a spell by name.")] + [Usage("Cast ")] + [Description("Casts a spell by name.")] public static void Cast_OnCommand(CommandEventArgs e) { if (e.Length == 1) @@ -816,19 +825,22 @@ namespace Server.Commands } } - [Usage("Stuck"), Description("Opens a menu of towns, used for teleporting stuck mobiles.")] + [Usage("Stuck")] + [Description("Opens a menu of towns, used for teleporting stuck mobiles.")] public static void Stuck_OnCommand(CommandEventArgs e) { e.Mobile.Target = new StuckMenuTarget(); } - [Usage("Light "), Description("Set your local lightlevel.")] + [Usage("Light ")] + [Description("Set your local lightlevel.")] public static void Light_OnCommand(CommandEventArgs e) { e.Mobile.LightLevel = e.GetInt32(0); } - [Usage("Stats"), Description("View some stats about the server.")] + [Usage("Stats")] + [Description("View some stats about the server.")] public static void Stats_OnCommand(CommandEventArgs e) { e.Mobile.SendMessage("Open Connections: {0}", TcpServer.Instances.Count); diff --git a/Projects/UOContent/Commands/HelpInfo.cs b/Projects/UOContent/Commands/HelpInfo.cs index b85ca8b05..3056a75cd 100644 --- a/Projects/UOContent/Commands/HelpInfo.cs +++ b/Projects/UOContent/Commands/HelpInfo.cs @@ -19,9 +19,8 @@ namespace Server.Commands FillTable(); } - [Usage("HelpInfo []"), Description( - "Gives information on a specified command, or when no argument specified, displays a gump containing all commands" - )] + [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) diff --git a/Projects/UOContent/Commands/Object Creation/AddGump.cs b/Projects/UOContent/Commands/Object Creation/AddGump.cs index 84e3523a4..bf7890052 100644 --- a/Projects/UOContent/Commands/Object Creation/AddGump.cs +++ b/Projects/UOContent/Commands/Object Creation/AddGump.cs @@ -92,9 +92,8 @@ namespace Server.Gumps CommandSystem.Register("AddMenu", AccessLevel.GameMaster, AddMenu_OnCommand); } - [Usage("AddMenu [searchString]"), Description( - "Opens an add menu, with an optional initial search string. This menu allows you to search for Items or Mobiles and add them interactively." - )] + [Usage("AddMenu [searchString]")] + [Description("Opens an add menu, with an optional initial search string. This menu allows you to search for Items or Mobiles and add them interactively.")] private static void AddMenu_OnCommand(CommandEventArgs e) { var val = e.ArgString.Trim(); diff --git a/Projects/UOContent/Commands/Object Creation/Decorate.cs b/Projects/UOContent/Commands/Object Creation/Decorate.cs index f8a14b4f2..e36944c44 100644 --- a/Projects/UOContent/Commands/Object Creation/Decorate.cs +++ b/Projects/UOContent/Commands/Object Creation/Decorate.cs @@ -20,7 +20,8 @@ namespace Server.Commands CommandSystem.Register("Decorate", AccessLevel.Administrator, Decorate_OnCommand); } - [Usage("Decorate"), Description("Generates world decoration.")] + [Usage("Decorate")] + [Description("Generates world decoration.")] private static void Decorate_OnCommand(CommandEventArgs e) { m_Mobile = e.Mobile; diff --git a/Projects/UOContent/Commands/Object Creation/DecorateMag.cs b/Projects/UOContent/Commands/Object Creation/DecorateMag.cs index fdea8e992..be9d86629 100644 --- a/Projects/UOContent/Commands/Object Creation/DecorateMag.cs +++ b/Projects/UOContent/Commands/Object Creation/DecorateMag.cs @@ -20,7 +20,8 @@ namespace Server.Commands CommandSystem.Register("DecorateMag", AccessLevel.Administrator, DecorateMag_OnCommand); } - [Usage("DecorateMag"), Description("Generates world decoration.")] + [Usage("DecorateMag")] + [Description("Generates world decoration.")] private static void DecorateMag_OnCommand(CommandEventArgs e) { m_Mobile = e.Mobile; diff --git a/Projects/UOContent/Commands/Object Creation/GenTeleporter.cs b/Projects/UOContent/Commands/Object Creation/GenTeleporter.cs index daa84d9b0..b597611d4 100644 --- a/Projects/UOContent/Commands/Object Creation/GenTeleporter.cs +++ b/Projects/UOContent/Commands/Object Creation/GenTeleporter.cs @@ -33,7 +33,8 @@ namespace Server.Commands CommandSystem.Register("TelGenDelete", AccessLevel.Administrator, TelGenDelete_OnCommand); } - [Usage("TelGenDelete"), Description("Destroys world/dungeon teleporters for all facets.")] + [Usage("TelGenDelete")] + [Description("Destroys world/dungeon teleporters for all facets.")] public static void TelGenDelete_OnCommand(CommandEventArgs e) { var from = e.Mobile; @@ -63,7 +64,8 @@ namespace Server.Commands from.SendMessage(WarningHue, $"{count} Teleporters Removed."); } - [Usage("TelGen"), Description("Generates world/dungeon teleporters for all facets.")] + [Usage("TelGen")] + [Description("Generates world/dungeon teleporters for all facets.")] public static void GenTeleporter_OnCommand(CommandEventArgs e) { var from = e.Mobile; diff --git a/Projects/UOContent/Commands/Profiling.cs b/Projects/UOContent/Commands/Profiling.cs index 79f035202..b23f21523 100644 --- a/Projects/UOContent/Commands/Profiling.cs +++ b/Projects/UOContent/Commands/Profiling.cs @@ -19,7 +19,8 @@ namespace Server.Commands CommandSystem.Register("SetProfiles", AccessLevel.Administrator, SetProfiles_OnCommand); } - [Usage("WriteProfiles"), Description("Generates a log files containing performance diagnostic information.")] + [Usage("WriteProfiles")] + [Description("Generates a log files containing performance diagnostic information.")] public static void WriteProfiles_OnCommand(CommandEventArgs e) { try @@ -86,7 +87,8 @@ namespace Server.Commands } } - [Usage("CountObjects"), Description("Generates a log file detailing all item and mobile types in the world.")] + [Usage("CountObjects")] + [Description("Generates a log file detailing all item and mobile types in the world.")] public static void CountObjects_OnCommand(CommandEventArgs e) { using (var op = new StreamWriter("objects.log")) @@ -140,7 +142,8 @@ namespace Server.Commands e.Mobile.SendMessage("Object table has been generated. See the file : objects.log"); } - [Usage("TraceExpanded"), Description("Generates a log file describing all items using expanded memory.")] + [Usage("TraceExpanded")] + [Description("Generates a log file describing all items using expanded memory.")] public static void TraceExpanded_OnCommand(CommandEventArgs e) { var typeTable = new Dictionary(); @@ -251,7 +254,8 @@ namespace Server.Commands } } - [Usage("TraceInternal"), Description("Generates a log file describing all items in the 'internal' map.")] + [Usage("TraceInternal")] + [Description("Generates a log file describing all items in the 'internal' map.")] public static void TraceInternal_OnCommand(CommandEventArgs e) { var totalCount = 0; diff --git a/Projects/UOContent/Commands/ResetStaffDress.cs b/Projects/UOContent/Commands/ResetStaffDress.cs new file mode 100644 index 000000000..4ca756b84 --- /dev/null +++ b/Projects/UOContent/Commands/ResetStaffDress.cs @@ -0,0 +1,69 @@ +using System; +using Server.Items; +using Server.Mobiles; +using Server.Network; +using Server.Utilities; + +namespace Server.Commands; + +public static class StaffDress +{ + private static readonly Type[] _staffRobeTypes = + { + null, + typeof(CounselorRobe), + typeof(GMRobe), + typeof(SeerRobe), + typeof(AdminRobe), + typeof(AdminRobe), + typeof(AdminRobe) + }; + + public static void Initialize() + { + CommandSystem.Register("ResetStaffDress", AccessLevel.Counselor, StaffDress_OnCommand); + } + + [Usage("ResetStaffDress")] + [Description("Resets staff to proper GM")] + public static void StaffDress_OnCommand(CommandEventArgs e) + { + if (e.Mobile is not PlayerMobile pm) + { + return; + } + + pm.Karma = pm.Fame = pm.Kills = pm.ShortTermMurders = pm.BodyMod = 0; + pm.Body = 987; + pm.SolidHueOverride = pm.HueMod = -1; + pm.Blessed = true; + pm.DisplayGuildTitle = false; + pm.DisplayChampionTitle = false; + if (pm.Mount != null) + { + pm.Mount.Rider = null; + } + + pm.NetState.SendSpeedControl(SpeedControlSetting.Mount); + pm.ResetStaffAccess(); + + for (var i = pm.Items.Count - 1; i >= 0; i--) + { + var item = pm.Items[i]; + + if (item.Layer is not Layer.Backpack + and not Layer.Bank + and not Layer.FacialHair + and not Layer.Hair + and not Layer.Mount + and not Layer.ShopBuy + and not Layer.ShopResale + and not Layer.ShopSell) + { + pm.AddToBackpack(item); + } + } + + pm.AddItem(_staffRobeTypes[(int)pm.AccessLevel].CreateInstance()); + } +} diff --git a/Projects/UOContent/Commands/ShardTime.cs b/Projects/UOContent/Commands/ShardTime.cs index a206d1340..17de8d46a 100644 --- a/Projects/UOContent/Commands/ShardTime.cs +++ b/Projects/UOContent/Commands/ShardTime.cs @@ -9,7 +9,8 @@ namespace Server.Commands CommandSystem.Register("Time", AccessLevel.Player, Time_OnCommand); } - [Usage("Time"), Description("Returns the server's local time.")] + [Usage("Time")] + [Description("Returns the server's local time.")] private static void Time_OnCommand(CommandEventArgs e) { e.Mobile.SendMessage(Core.Now.ToString(CultureInfo.InvariantCulture)); diff --git a/Projects/UOContent/Commands/SignParser.cs b/Projects/UOContent/Commands/SignParser.cs index 0fba2d29a..9f96a4f85 100644 --- a/Projects/UOContent/Commands/SignParser.cs +++ b/Projects/UOContent/Commands/SignParser.cs @@ -15,7 +15,8 @@ namespace Server.Commands CommandSystem.Register("SignGen", AccessLevel.Administrator, SignGen_OnCommand); } - [Usage("SignGen"), Description("Generates world/shop signs on all facets.")] + [Usage("SignGen")] + [Description("Generates world/shop signs on all facets.")] public static void SignGen_OnCommand(CommandEventArgs c) { Parse(c.Mobile); diff --git a/Projects/UOContent/Commands/Skills.cs b/Projects/UOContent/Commands/Skills.cs index 04d525257..900c8a90a 100644 --- a/Projects/UOContent/Commands/Skills.cs +++ b/Projects/UOContent/Commands/Skills.cs @@ -12,7 +12,8 @@ namespace Server.Commands CommandSystem.Register("SetAllSkills", AccessLevel.GameMaster, SetAllSkills_OnCommand); } - [Usage("SetSkill "), Description("Sets a skill value by name of a targeted mobile.")] + [Usage("SetSkill ")] + [Description("Sets a skill value by name of a targeted mobile.")] public static void SetSkill_OnCommand(CommandEventArgs arg) { if (arg.Length != 2) @@ -32,7 +33,8 @@ namespace Server.Commands } } - [Usage("SetAllSkills "), Description("Sets all skill values of a targeted mobile.")] + [Usage("SetAllSkills ")] + [Description("Sets all skill values of a targeted mobile.")] public static void SetAllSkills_OnCommand(CommandEventArgs arg) { if (arg.Length != 1) @@ -45,7 +47,8 @@ namespace Server.Commands } } - [Usage("GetSkill "), Description("Gets a skill value by name of a targeted mobile.")] + [Usage("GetSkill ")] + [Description("Gets a skill value by name of a targeted mobile.")] public static void GetSkill_OnCommand(CommandEventArgs arg) { if (arg.Length != 1) diff --git a/Projects/UOContent/Commands/SkillsMenu.cs b/Projects/UOContent/Commands/SkillsMenu.cs index 956a52c4d..a69e55e1e 100644 --- a/Projects/UOContent/Commands/SkillsMenu.cs +++ b/Projects/UOContent/Commands/SkillsMenu.cs @@ -15,7 +15,8 @@ namespace Server.Commands CommandSystem.Register("Skills", AccessLevel.Counselor, Skills_OnCommand); } - [Usage("Skills"), Description("Opens a menu where you can view or edit skills of a targeted mobile.")] + [Usage("Skills")] + [Description("Opens a menu where you can view or edit skills of a targeted mobile.")] private static void Skills_OnCommand(CommandEventArgs e) { e.Mobile.Target = new SkillsTarget(); diff --git a/Projects/UOContent/Commands/StaffAccess.cs b/Projects/UOContent/Commands/StaffAccess.cs new file mode 100644 index 000000000..47ff71daa --- /dev/null +++ b/Projects/UOContent/Commands/StaffAccess.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using Server.Accounting; +using Server.Mobiles; + +namespace Server.Commands; + +public static class StaffAccess +{ + private static readonly Dictionary _accessLevelByString = new(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static string AccountTag(Serial serial) => $"OriginalStaffAccess:{serial}"; + + public static void Initialize() + { + CommandSystem.Register("StaffAccess", AccessLevel.Player, StaffAccess_OnCommand); + + foreach (var accessLevel in Enum.GetValues()) + { + _accessLevelByString[accessLevel.ToString().ToLower()] = accessLevel; + } + + _accessLevelByString["gm"] = AccessLevel.GameMaster; + _accessLevelByString["dev"] = AccessLevel.Developer; + _accessLevelByString["admin"] = AccessLevel.Administrator; + } + + public static void ResetStaffAccess(this PlayerMobile m) + { + if (m.Account is not Account account) + { + return; + } + + var accountTag = AccountTag(m.Serial); + var originalAccessLevelString = account.GetTag(accountTag); + if (originalAccessLevelString == null) + { + return; + } + + var accessLevel = _accessLevelByString[originalAccessLevelString]; + account.RemoveTag(accountTag); + m.AccessLevel = accessLevel; + } + + [Usage("StaffAccess ")] + [Description("Overrides your access level.")] + public static void StaffAccess_OnCommand(CommandEventArgs e) + { + var m = e.Mobile; + if (m.Account is not Account account) + { + return; + } + + var accountTag = AccountTag(m.Serial); + var originalAccessLevelString = account.GetTag(accountTag); + AccessLevel? originalAccessLevel = originalAccessLevelString != null ? _accessLevelByString[originalAccessLevelString] : null; + if (originalAccessLevel == null && m.AccessLevel == AccessLevel.Player) + { + return; + } + + var accessLevelArgument = e.GetString(0)?.Trim().ToLower(); + AccessLevel newAccessLevel = AccessLevel.Player; + var validAccessLevel = !string.IsNullOrEmpty(accessLevelArgument) && + _accessLevelByString.TryGetValue(accessLevelArgument, out newAccessLevel); + + if (!validAccessLevel && originalAccessLevel == null) + { + m.SendMessage("Invalid access level specified."); + m.SendMessage("Usage: [staffaccess ."); + return; + } + + if (originalAccessLevel != null && (!validAccessLevel || newAccessLevel == originalAccessLevel)) + { + account.RemoveTag(accountTag); + newAccessLevel = originalAccessLevel.Value; + m.SendMessage("Restoring original staff access..."); + } + + if (newAccessLevel > m.AccessLevel) + { + m.SendMessage($"You cannot set your staff access to {newAccessLevel.ToString()}."); + return; + } + + if (originalAccessLevel == null) + { + // Save the original access level + account.AddTag(accountTag, m.AccessLevel.ToString().ToLower()); + } + + m.AccessLevel = newAccessLevel; + m.SendMessage($"Staff access set to {newAccessLevel.ToString()}."); + } +} diff --git a/Projects/UOContent/Commands/Statics.cs b/Projects/UOContent/Commands/Statics.cs index 839bd0ec3..8a64c3021 100644 --- a/Projects/UOContent/Commands/Statics.cs +++ b/Projects/UOContent/Commands/Statics.cs @@ -48,14 +48,16 @@ namespace Server CommandSystem.Register("UnfreezeWorld", AccessLevel.Administrator, UnfreezeWorld_OnCommand); } - [Usage("Freeze"), Description("Makes a targeted area of dynamic items static.")] + [Usage("Freeze")] + [Description("Makes a targeted area of dynamic items static.")] public static void Freeze_OnCommand(CommandEventArgs e) { var from = e.Mobile; BoundingBoxPicker.Begin(from, (map, start, end) => FreezeBox_Callback(from, map, start, end)); } - [Usage("FreezeMap"), Description("Makes every dynamic item in your map static.")] + [Usage("FreezeMap")] + [Description("Makes every dynamic item in your map static.")] public static void FreezeMap_OnCommand(CommandEventArgs e) { var from = e.Mobile; @@ -75,7 +77,8 @@ namespace Server } } - [Usage("FreezeWorld"), Description("Makes every dynamic item on all maps static.")] + [Usage("FreezeWorld")] + [Description("Makes every dynamic item on all maps static.")] public static void FreezeWorld_OnCommand(CommandEventArgs e) { SendWarning( @@ -404,14 +407,16 @@ namespace Server } } - [Usage("Unfreeze"), Description("Makes a targeted area of static items dynamic.")] + [Usage("Unfreeze")] + [Description("Makes a targeted area of static items dynamic.")] public static void Unfreeze_OnCommand(CommandEventArgs e) { var from = e.Mobile; BoundingBoxPicker.Begin(from, (map, start, end) => UnfreezeBox_Callback(from, map, start, end)); } - [Usage("UnfreezeMap"), Description("Makes every static item in your map dynamic.")] + [Usage("UnfreezeMap")] + [Description("Makes every static item in your map dynamic.")] public static void UnfreezeMap_OnCommand(CommandEventArgs e) { var map = e.Mobile.Map; @@ -430,7 +435,8 @@ namespace Server } } - [Usage("UnfreezeWorld"), Description("Makes every static item on all maps dynamic.")] + [Usage("UnfreezeWorld")] + [Description("Makes every static item on all maps dynamic.")] public static void UnfreezeWorld_OnCommand(CommandEventArgs e) { SendWarning( diff --git a/Projects/UOContent/Commands/VisibilityList.cs b/Projects/UOContent/Commands/VisibilityList.cs index cea19640d..ee871d3dc 100644 --- a/Projects/UOContent/Commands/VisibilityList.cs +++ b/Projects/UOContent/Commands/VisibilityList.cs @@ -22,9 +22,8 @@ namespace Server.Commands (m as PlayerMobile)?.VisibilityList.Clear(); } - [Usage("Vis"), Description( - "Adds or removes a targeted player from your visibility list. Anyone on your visibility list will be able to see you at all times, even when you're hidden." - )] + [Usage("Vis")] + [Description("Adds or removes a targeted player from your visibility list. Anyone on your visibility list will be able to see you at all times, even when you're hidden.")] public static void Vis_OnCommand(CommandEventArgs e) { if (e.Mobile is PlayerMobile) @@ -34,7 +33,8 @@ namespace Server.Commands } } - [Usage("VisList"), Description("Shows the names of everyone in your visibility list.")] + [Usage("VisList")] + [Description("Shows the names of everyone in your visibility list.")] public static void VisList_OnCommand(CommandEventArgs e) { if (e.Mobile is PlayerMobile pm) @@ -57,7 +57,8 @@ namespace Server.Commands } } - [Usage("VisClear"), Description("Removes everyone from your visibility list.")] + [Usage("VisClear")] + [Description("Removes everyone from your visibility list.")] public static void VisClear_OnCommand(CommandEventArgs e) { if (e.Mobile is PlayerMobile pm) diff --git a/Projects/UOContent/Commands/Wipe.cs b/Projects/UOContent/Commands/Wipe.cs index bc066fbde..806ad6a61 100644 --- a/Projects/UOContent/Commands/Wipe.cs +++ b/Projects/UOContent/Commands/Wipe.cs @@ -24,25 +24,29 @@ namespace Server.Commands CommandSystem.Register("WipeMultis", AccessLevel.GameMaster, WipeMultis_OnCommand); } - [Usage("Wipe"), Description("Wipes all items and npcs in a targeted bounding box.")] + [Usage("Wipe")] + [Description("Wipes all items and npcs in a targeted bounding box.")] private static void WipeAll_OnCommand(CommandEventArgs e) { BeginWipe(e.Mobile, WipeType.Items | WipeType.Mobiles); } - [Usage("WipeItems"), Description("Wipes all items in a targeted bounding box.")] + [Usage("WipeItems")] + [Description("Wipes all items in a targeted bounding box.")] private static void WipeItems_OnCommand(CommandEventArgs e) { BeginWipe(e.Mobile, WipeType.Items); } - [Usage("WipeNPCs"), Description("Wipes all npcs in a targeted bounding box.")] + [Usage("WipeNPCs")] + [Description("Wipes all npcs in a targeted bounding box.")] private static void WipeNPCs_OnCommand(CommandEventArgs e) { BeginWipe(e.Mobile, WipeType.Mobiles); } - [Usage("WipeMultis"), Description("Wipes all multis in a targeted bounding box.")] + [Usage("WipeMultis")] + [Description("Wipes all multis in a targeted bounding box.")] private static void WipeMultis_OnCommand(CommandEventArgs e) { BeginWipe(e.Mobile, WipeType.Multis);