using Oxide.Core; using System; using System.Collections; using Newtonsoft.Json; using System.Collections.Generic; using System.Linq; using UnityEngine; /* * This is a partial rewrite 2.0.0 * Now Supports Skins + Ammo Types + Reset Command * * Updated API hook * * This update 2.0.2 fixes issues with commands * Updated reset lang msg * * This update 2.0.3 * Added ability for multiple loadouts per player assuming they have the permission loadoutless.save * Added Select command * Added Remove command * Added Clear command * Updated Save command * updated lang files * Added Item limits defaults to server stacksize limits * Added Auto Limit adjuster based on StackSizeChanges on the server. * * Warning Delete Lang file! * This update 2.0.4 * Updated lang files * Fixed command issues * Updated permissions to be cleaner * * Updated Lang * Added overwrite command * * Update 2.0.7 * Updated Commands / Code Cleanup * Imported WhiteThunders Memory leak patch * * Update 2.0.8 * Fixed Item Limits set to 0/enabled not allowing admins to set default loadout. * * Update 2.0.9 * Fixed error after creating a ban file and attempting to reset players data files * * Update 2.1.0 * Fixed Clearing Data Files * Fixed Duplication issues * Fixed performance hits on high pop servers now runs coroutines on reset/clear * * Update 2.1.1 * Fixes extended mag issue ( now you don't have to re-load to get the 38 limit ) * Fixes 3 msg responses not being sent properly. * Fixed Syntax msg missing /overwrite name command option. * Delete lang file */ namespace Oxide.Plugins { [Info("Loadoutless", "Khan(main)/russeldelrosario(update fix)", "2.1.3")] [Description("Players can respawn with a loadout")] public class Loadoutless : RustPlugin { #region Variables private const string Default = "loadoutless.spawn"; private const string Use = "loadoutless.use"; private const string Admin = "loadoutless.admin"; private const string FileBanlist = "Loadoutless_itembanlist"; private const string FileMain = "Loadoutless_folder/"; private static Loadoutless _instance; private Dictionary _playerLoadouts = new Dictionary(); private PluginConfig _config; #endregion #region Localization private string Lang(string key, string id = null, params object[] args) => string.Format(lang.GetMessage(key, this, id), args); protected override void LoadDefaultMessages() { lang.RegisterMessages(new Dictionary { ["Error_Insuffarg"] = "Insufficient arguments! player options are \n /loadout save name, overwrite name, remove name, select name", ["Error_Insuffarg2"] = "Insufficient arguments! options are \n setdefault : sets server loadout, \n banitem, baninv, removebanitem, \n reset : resets players loadouts to server defaults \n clear : will delete all players saved loadouts", ["Error_Noitem"] = "No item selected!", ["Error_Itemnotfound"] = "Item not found!", ["Error_Filenotexist"] = "Playerfile doesn't exist.", ["Error_Creatingnewfile"] = "Creating a new playerfile...", ["Cmd_Removebanitem"] = "Item is removed from the banfile.", ["Cmd_Removebanitem_notinfile"] = "Item was not banned!", ["Cmd_Banitem_already"] = "Item is already banned!", ["Cmd_Banitem"] = "Item sucessfully added to the banfile!", ["Cmd_Setdefault"] = "Default Server loadout has succesfully been set!", ["Cmd_Processing"] = "coroutine has begun processing data files for update. will take a min or two.", ["Cmd_Wait"] = "Coroutine is still running please wait a min or two and try again.", ["Cmd_Noperm"] = "You don't have the permsission to do that!", ["Cmd_Saved"] = "Loadout {0} was sucessfully saved!", ["Cmd_inv_added"] = "All inventory Items are saved in the ban file", ["Cmd_Reset"] = "All players loadouts have been reset to default \n By user {0}", ["Cmd_MaxLoadOut"] = "Maximum number of loadouts is {0} please remove 1 to add another", ["Cmd_MaxLimit"] = "{0} stack amount is greater than item stack limit set {1}", ["Cmd_Select"] = "Available loadouts are {0} ", ["Cmd_Remove"] = "Available loadouts to remove are {0} ", ["Cmd_SelectMia"] = "Loadout {0} doesn't exist, your current loadouts are {1} ", ["Cmd_Selected"] = "Loadout {0} is now set", ["Cmd_Cleared"] = "Player {0} has cleared everyone's loadouts, only default loadout remains", ["Cmd_Savedalready"] = "Loadout {0} already exists", ["Cmd_NotEnough"] = "You must save a loadout with a name! \n /loadout save primary", ["Cmd_NotEnough2"] = "Available loadouts to remove are {0} ", ["Cmd_Overwritten"] = "Loadout {0} was successfully overwritten!", ["Cmd_Overwrite"] = "Available loadouts to overwite are {0} ", }, this); } #endregion #region Config protected override void LoadDefaultConfig() => _config = new PluginConfig(); protected override void LoadConfig() { base.LoadConfig(); try { _config = Config.ReadObject(); if (_config == null) { throw new JsonException(); } if (_config.ToDictionary().Keys.SequenceEqual(Config.ToDictionary(x => x.Key, x => x.Value).Keys)) return; PrintWarning("Loaded updated config."); SaveConfig(); } catch { PrintWarning("You have messed up your config please run it through Json Validation @ https://jsonlint.com/"); //LoadDefaultConfig(); } } protected override void SaveConfig() => Config.WriteObject(_config, true); private void CheckConfig() { foreach (ItemDefinition item in ItemManager.itemList) { if (!(item.isHoldable || item.isUsable || item.isWearable)) continue; if (!_config.Limits.ContainsKey(item.shortname)) { _config.Limits.Add(item.shortname, new Limit { DisplayName = item.displayName.english, Amount = item.stackable }); } if (!_config.EnableAutoLimits) continue; _config.Limits[item.shortname].DisplayName = item.displayName.english; _config.Limits[item.shortname].Amount = item.stackable; } if (_config.DefaultLoadout == null) { _config.DefaultLoadout = new List { new LoadoutItem { Itemid = 20489901, Amount = 1, Slot = 0, Container = "wear", Bp = false, Weapon = false }, new LoadoutItem { Itemid = -1754948969, Amount = 1, Slot = 0, Container = "main", Bp = false, Weapon = false }, new LoadoutItem { Itemid = 963906841, Amount = 1, Slot = 0, Container = "belt", Bp = false, Weapon = false }, new LoadoutItem { Itemid = 795236088, Amount = 1, Slot = 1, Container = "belt", Bp = false, Weapon = false }, new LoadoutItem { Itemid = -1583967946, Amount = 1, Slot = 2, Container = "belt", Bp = false, Weapon = false }, new LoadoutItem { Itemid = 171931394, Amount = 1, Slot = 3, Container = "belt", Bp = false, Weapon = false }, }; } SaveConfig(); } public class Limit { public string DisplayName; public double Amount; } private class PluginConfig { [JsonProperty("Set Max Player Loadouts", Order = 1)] public int MaxLoadouts = 3; [JsonProperty("Enable Item Limits", Order = 2)] public bool EnableLimits = true; [JsonProperty("Enable Auto Update Limits", Order = 3)] public bool EnableAutoLimits = false; [JsonProperty(Order = 4)] public List DefaultLoadout; [JsonProperty("Item Loadout Limits Defaults to your Servers Stack Size", Order = 5)] public Dictionary Limits = new Dictionary(); public string ToJson() => JsonConvert.SerializeObject(this); public Dictionary ToDictionary() => JsonConvert.DeserializeObject>(ToJson()); } #endregion #region Hooks private void Init() { permission.RegisterPermission(Use, this); permission.RegisterPermission(Default, this); permission.RegisterPermission(Admin, this); _instance = this; } private void OnServerInitialized() { CheckConfig(); foreach (BasePlayer player in BasePlayer.activePlayerList) { PlayerLoadout.TryLoad(player); } } private void Unload() { if (_coroutine != null) ServerMgr.Instance.StopCoroutine(_coroutine); _instance = null; } private void OnPlayerConnected(BasePlayer player) { PlayerLoadout.TryLoad(player); } private void OnPlayerRespawned(BasePlayer player) { if (permission.UserHasPermission(player.UserIDString, Default)) { GiveLoadout(player); } } private void OnPlayerDisconnected(BasePlayer player, string reason) { _playerLoadouts.Remove(player.UserIDString); } #endregion #region Methodes private Coroutine _coroutine; private IEnumerator ResetPlayersLoadout() { string[] files = Interface.Oxide.DataFileSystem.GetFiles(FileMain); if (files == null) { _coroutine = null; yield return null; } int count = 0; foreach (string filePath in files) { if (filePath.Contains(FileBanlist)) continue; string fileName = RemoveFilePath(filePath).Replace(".json", ""); if (_playerLoadouts.ContainsKey(fileName)) { _playerLoadouts[fileName].AvailableLoadouts["default"] = _config.DefaultLoadout; _playerLoadouts[fileName].Loadout = "default"; Interface.Oxide.DataFileSystem.WriteObject($"{FileMain}/{fileName}", _playerLoadouts[fileName]); } else { PlayerLoadout playerLoadout = Interface.Oxide.DataFileSystem.ReadObject($"{FileMain}/{fileName}"); playerLoadout.AvailableLoadouts["default"] = _config.DefaultLoadout; playerLoadout.Loadout = "default"; playerLoadout.Save(); } count++; Puts($"Setting Defaults Loadouts processing file {count} {files.Length - 1}"); yield return CoroutineEx.waitForSeconds(0.5f); } _coroutine = null; yield return null; } private IEnumerator ClearPlayersLoadouts() { string[] files = Interface.Oxide.DataFileSystem.GetFiles(FileMain); if (files == null) { _coroutine = null; yield break; } int count = 0; foreach (string filePath in files) { if (filePath.Contains(FileBanlist)) continue; string fileName = RemoveFilePath(filePath).Replace(".json", ""); if (_playerLoadouts.ContainsKey(fileName)) { _playerLoadouts[fileName].AvailableLoadouts.Clear(); _playerLoadouts[fileName].AvailableLoadouts["default"] = _config.DefaultLoadout; _playerLoadouts[fileName].Loadout = "default"; Interface.Oxide.DataFileSystem.WriteObject($"{FileMain}/{fileName}", _playerLoadouts[fileName]); } else { PlayerLoadout playerLoadout = Interface.Oxide.DataFileSystem.ReadObject($"{FileMain}/{fileName}"); playerLoadout.AvailableLoadouts.Clear(); playerLoadout.AvailableLoadouts["default"] = _config.DefaultLoadout; playerLoadout.Loadout = "default"; playerLoadout.Save(); } count++; Puts($"Clearing All Loadouts processing file {count} {files.Length - 1}"); yield return CoroutineEx.waitForSeconds(0.5f); } _coroutine = null; yield return null; } public string RemoveFilePath(string value) { value = value.Substring(value.LastIndexOf('/') + 1); return value; } public void AddInvBan(Item[] invItems) { List banFile = LoadBanFile(); foreach (var item in invItems) { if (CheckBanFile(item.info.itemid.ToString()) == false) { banFile.Add(item.info.itemid.ToString()); } else { PrintToConsole(item.info.shortname + "already in banfile"); } UpdateBanFile(banFile); } } void UpdateBanFile(List ban_list) { Interface.Oxide.DataFileSystem.WriteObject(FileMain + FileBanlist, JsonConvert.SerializeObject(ban_list)); } bool CheckBanFile(string itemid) { List banFile = LoadBanFile(); return banFile.Contains(itemid); } List RemoveItemBanlist(List banfile, string itemid) { List newBanfile = new List(); foreach (string item in banfile) { if (item != itemid) { newBanfile.Add(item); } } return newBanfile; } List LoadBanFile() { List banFile; //When ban file is needed checks if it exists if not, it will create one. if (!Interface.Oxide.DataFileSystem.ExistsDatafile(FileMain + FileBanlist)) { banFile = new List(); } else { string rawBanfile = Interface.Oxide.DataFileSystem.ReadObject(FileMain + FileBanlist); banFile = JsonConvert.DeserializeObject>(rawBanfile); } return banFile; } private static List GetPlayerLoadout(BasePlayer player, bool admin = false) { List loadoutItems = new List(); foreach (Item item in player.inventory.containerWear.itemList) { if (item == null) continue; if (admin == false) { if (_instance._config.EnableLimits && _instance._config.Limits.ContainsKey(item.info.shortname) && item.amount > _instance._config.Limits[item.info.shortname].Amount) { _instance.SendMessage(player,_instance.Lang("Cmd_MaxLimit", player.UserIDString, item.info.displayName.english, _instance._config.Limits[item.info.shortname].Amount)); return null; } } LoadoutItem loadoutItem = ProcessItem(item, "wear"); loadoutItems.Add(loadoutItem); } foreach (Item item in player.inventory.containerMain.itemList) { if (item == null) continue; if (admin == false) { if (_instance._config.EnableLimits && _instance._config.Limits.ContainsKey(item.info.shortname) && item.amount > _instance._config.Limits[item.info.shortname].Amount) { _instance.SendMessage(player,_instance.Lang("Cmd_MaxLimit", player.UserIDString, item.info.displayName.english, _instance._config.Limits[item.info.shortname].Amount)); return null; } } LoadoutItem loadoutItem = ProcessItem(item, "main"); loadoutItems.Add(loadoutItem); } foreach (Item item in player.inventory.containerBelt.itemList) { if (item == null) continue; if (admin == false) { if (_instance._config.EnableLimits && _instance._config.Limits.ContainsKey(item.info.shortname) && item.amount > _instance._config.Limits[item.info.shortname].Amount) { _instance.SendMessage(player,_instance.Lang("Cmd_MaxLimit", player.UserIDString, item.info.displayName.english, _instance._config.Limits[item.info.shortname].Amount)); return null; } } LoadoutItem loadoutItem = ProcessItem(item, "belt"); loadoutItems.Add(loadoutItem); } return loadoutItems; } private static LoadoutItem ProcessItem(Item item, string container) { LoadoutItem iItem = new LoadoutItem(); iItem.Amount = item.amount; iItem.Mods = new List(); iItem.Container = container; iItem.Skinid = item.skin; iItem.Itemid = item.info.itemid; iItem.Weapon = false; iItem.Slot = item.position; iItem.Ammotype = 0; iItem.AmmoAmount = 0; if (item.info.category.ToString() != "Weapon") { return iItem; } BaseProjectile weapon = item.GetHeldEntity() as BaseProjectile; if (weapon == null || weapon.primaryMagazine == null) { return iItem; } iItem.Weapon = true; iItem.Ammotype = weapon.primaryMagazine.ammoType.itemid; iItem.AmmoAmount = weapon.primaryMagazine.contents; if (item.contents == null) { return iItem; } foreach (var mod in item.contents.itemList) { if (mod.info.itemid != 0) { iItem.Mods.Add(mod.info.itemid); } } return iItem; } private static Item BuildWeapon(int id, ulong skin, int Ammotype, int ammoAmount, List mods) { Item item = CreateByItemID(id, 1, skin); var weapon = item.GetHeldEntity() as BaseProjectile; if (weapon != null) { weapon.primaryMagazine.contents = ammoAmount; weapon.primaryMagazine.ammoType = ItemManager.FindItemDefinition(Ammotype); } if (mods == null) { return item; } bool mag = false; foreach (var mod in mods) { item.contents.AddItem(ItemManager.FindItemDefinition(mod), 1); if (mod == 2005491391) //extended mag { mag = true; } } if (mag) { int num = Mathf.CeilToInt(ProjectileWeaponMod.Mult(weapon, (x => x.magazineCapacity), (y => y.scalar), 1f) * weapon.primaryMagazine.definition.builtInSize); weapon.primaryMagazine.contents = ammoAmount; weapon.primaryMagazine.capacity = num; } return item; } private static Item BuildItem(int itemid, int amount, ulong skin) { if (amount < 1) amount = 1; Item item = CreateByItemID(itemid, amount, skin); return item; } private static Item CreateByItemID(int itemID, int amount = 1, ulong skin = 0) { return ItemManager.CreateByItemID(itemID, amount, skin); } private static bool GiveItem(PlayerInventory inv, Item item, ItemContainer container = null, int position = 0) { if (item == null) { return false; } return container != null && item.MoveToContainer(container, position, true) || item.MoveToContainer(inv.containerMain, position, true) || item.MoveToContainer(inv.containerBelt, position, true); } List CheckBannedList(List list) { List newList = new List(); List banFile = LoadBanFile(); foreach (LoadoutItem item in list) { if (!banFile.Contains(item.Itemid.ToString())) { newList.Add(item); } } return newList; } public object GiveLoadout(BasePlayer player) { return PlayerLoadout.Find(player)?.GiveLoadout(player); } public void SendMessage(BasePlayer player, string message) { PrintToChat(player, lang.GetMessage(message, this, player.UserIDString)); } #endregion #region Classes public class PlayerLoadout { public ulong ID; public string Name; //public List Items = new List(); public string Loadout; public Dictionary> AvailableLoadouts = new Dictionary>(); internal static void TryLoad(BasePlayer player) { if (Find(player) != null) { return; } PlayerLoadout data = Interface.Oxide.DataFileSystem.ReadObject($"{FileMain}/{player.userID}"); if (data == null || data.ID == 0) { data = new PlayerLoadout{ID = player.userID, Name = player.displayName, Loadout = "default", AvailableLoadouts = new Dictionary>{{"default", _instance._config.DefaultLoadout}}}; } else { data.Update(player); } data.Save(); if (!_instance._playerLoadouts.ContainsKey(player.UserIDString)) { _instance._playerLoadouts.Add(player.UserIDString, data); } } internal void Update(BasePlayer player) { ID = player.userID; Name = player.displayName; Save(); } internal void Save() { Interface.Oxide.DataFileSystem.WriteObject($"{FileMain}/{ID}", this); } internal static PlayerLoadout Find(BasePlayer player) { PlayerLoadout playerLoadout; return _instance._playerLoadouts.TryGetValue(player.UserIDString, out playerLoadout) ? playerLoadout : null; } internal object GiveLoadout(BasePlayer player) { if (!AvailableLoadouts.ContainsKey(Loadout)) { return null; } player.inventory.Strip(); foreach (var kitem in AvailableLoadouts[Loadout]) { GiveItem(player.inventory, kitem.Weapon ? BuildWeapon(kitem.Itemid, kitem.Skinid, kitem.Ammotype, kitem.AmmoAmount, kitem.Mods) : BuildItem(kitem.Itemid, kitem.Amount, kitem.Skinid), kitem.Container == "belt" ? player.inventory.containerBelt : kitem.Container == "wear" ? player.inventory.containerWear : player.inventory.containerMain, kitem.Slot); } return true; } } public class LoadoutItem { public int Itemid; public bool Bp; public ulong Skinid; public string Container; public int Slot; public int Amount; public bool Weapon; public int Ammotype; public int AmmoAmount; public List Mods = new List(); } #endregion #region Commands [ChatCommand("loadout")] private void LoadoutLessCommand(BasePlayer player, string command, string[] args) { if (_coroutine != null) { SendMessage(player, "Cmd_Wait"); return; } if (args.Length == 0) { if (permission.UserHasPermission(player.UserIDString, Admin)) { SendMessage(player,"Error_Insuffarg2"); } if (permission.UserHasPermission(player.UserIDString, Use)) { SendMessage(player, "Error_Insuffarg"); } } else { PlayerLoadout user = PlayerLoadout.Find(player); switch (args[0].ToLower()) { case "overwrite": if (permission.UserHasPermission(player.UserIDString, Use)) { if (args.Length < 2) { SendMessage(player, Lang("Cmd_NotEnough", player.UserIDString)); return; } if (!user.AvailableLoadouts.ContainsKey(args[1])) { SendMessage(player, Lang("Cmd_Overwrite", player.UserIDString, string.Join("\n", user.AvailableLoadouts.Keys.ToArray()))); return; } user.Loadout = args[1]; List loadout = GetPlayerLoadout(player); if (loadout == null) return; user.AvailableLoadouts[args[1]] = CheckBannedList(loadout); SendMessage(player, Lang("Cmd_Overwritten", player.UserIDString, user.Loadout)); user.Save(); } else { SendMessage(player, "Cmd_Noperm"); } break; case "save": if (permission.UserHasPermission(player.UserIDString, Use)) { if (args.Length < 2) { SendMessage(player, Lang("Cmd_NotEnough", player.UserIDString)); return; } if (user.AvailableLoadouts.Count >= _config.MaxLoadouts) { SendMessage(player, Lang("Cmd_MaxLoadOut", player.UserIDString, _config.MaxLoadouts)); return; } if (user.AvailableLoadouts.ContainsKey(args[1])) { SendMessage(player, Lang("Cmd_Savedalready", player.UserIDString, args[1])); return; } user.Loadout = args[1]; List loadout = GetPlayerLoadout(player); if (loadout == null) return; user.AvailableLoadouts.Add(args[1], CheckBannedList(loadout)); SendMessage(player, Lang("Cmd_Saved", player.UserIDString, user.Loadout)); user.Save(); } else { SendMessage(player, "Cmd_Noperm"); } break; case "remove": if (permission.UserHasPermission(player.UserIDString, Use)) { if (args.Length < 2) { SendMessage(player, _instance.Lang("Cmd_Remove", player.UserIDString, string.Join("\n", user.AvailableLoadouts.Keys.ToArray()))); return; } if (!user.AvailableLoadouts.ContainsKey(args[1])) { SendMessage(player, _instance.Lang("Cmd_Remove", player.UserIDString, string.Join("\n", user.AvailableLoadouts.Keys.ToArray()))); return; } user.AvailableLoadouts.Remove(args[1]); user.Save(); SendMessage(player, $"Loadout {args[1]} was removed"); } else { SendMessage(player, "Cmd_Noperm"); } break; case "select": if (permission.UserHasPermission(player.UserIDString, Use)) { if (args.Length == 1) { SendMessage(player, _instance.Lang("Cmd_Select", player.UserIDString, string.Join("\n", user.AvailableLoadouts.Keys.ToArray()))); return; } if (!user.AvailableLoadouts.ContainsKey(args[1])) { SendMessage(player, _instance.Lang("Cmd_SelectMia", player.UserIDString, args[1], string.Join("\n", user.AvailableLoadouts.Keys.ToArray()))); return; } user.Loadout = args[1]; user.Save(); SendMessage(player, _instance.Lang("Cmd_Selected", player.UserIDString, args[1])); } else { SendMessage(player, "Cmd_Noperm"); } break; case "setdefault": if (permission.UserHasPermission(player.UserIDString, Admin)) { List loadout = GetPlayerLoadout(player, true); if (loadout == null) return; _config.DefaultLoadout = loadout; SaveConfig(); _coroutine = ServerMgr.Instance.StartCoroutine(ResetPlayersLoadout()); SendMessage(player, "Cmd_Setdefault"); SendMessage(player, "Cmd_Processing"); } else { SendMessage(player, "Cmd_Noperm"); } break; case "banitem": if (permission.UserHasPermission(player.UserIDString, Admin)) { try { List ban_list = LoadBanFile(); string itemid = player.GetActiveItem().info.itemid.ToString(); if (CheckBanFile(itemid) == false) { ban_list.Add(itemid); UpdateBanFile(ban_list); SendMessage(player, "Cmd_Banitem"); } else { SendMessage(player, "Cmd_Banitem_already"); } } catch (NullReferenceException) { SendMessage(player, "Error_Noitem"); } } else { SendMessage(player, "Cmd_Noperm"); } break; case "removebanitem": if (permission.UserHasPermission(player.UserIDString, Admin)) { try { string itemid = player.GetActiveItem().info.itemid.ToString(); if (CheckBanFile(itemid) == true) { UpdateBanFile(RemoveItemBanlist(LoadBanFile(), itemid)); SendMessage(player, "Cmd_Removebanitem"); } else { SendMessage(player, "Cmd_Removebanitem_notinfile"); } } catch (NullReferenceException) { SendMessage(player, "Cmd_Error_Noitem"); } } else { SendMessage(player, "Cmd_Noperm"); } break; case "baninv": if (permission.UserHasPermission(player.UserIDString, Admin)) { //--Start Original Code by Russel del Rosario. https://russeldelrosario.com var tempItems = new List{}; tempItems.AddRange(player.inventory.containerMain.itemList); tempItems.AddRange(player.inventory.containerWear.itemList); tempItems.AddRange(player.inventory.containerBelt.itemList); AddInvBan(tempItems.ToArray()); SendMessage(player, "Cmd_inv_added"); //--END } else { SendMessage(player, "Cmd_Noperm"); } break; case "reset": if (permission.UserHasPermission(player.UserIDString, Admin)) { _coroutine = ServerMgr.Instance.StartCoroutine(ResetPlayersLoadout()); SendMessage(player, Lang("Cmd_Reset", player.UserIDString, player.displayName)); SendMessage(player, "Cmd_Processing"); } else { SendMessage(player, "Cmd_Noperm"); } break; case "clear" : if (permission.UserHasPermission(player.UserIDString, Admin)) { _coroutine = ServerMgr.Instance.StartCoroutine(ClearPlayersLoadouts()); SendMessage(player, _instance.Lang("Cmd_Cleared", player.UserIDString, player.displayName)); SendMessage(player, "Cmd_Processing"); } else { SendMessage(player, "Cmd_Noperm"); } break; default: SendMessage(player, "Error_Insuffarg"); break; } } } #endregion } }