RustServer/plugins/StackSizeController.cs

537 lines
20 KiB
C#

using System.Collections.Generic;
using System.Linq;
using System;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("Stack Size Controller", "Canopy Sheep", "2.0.4", ResourceId = 2320)]
[Description("Allows you to set the max stack size of every item.")]
public class StackSizeController : RustPlugin
{
#region Data
private bool pluginLoaded = false;
Items items;
class Items
{
public Dictionary<string, int> itemlist = new Dictionary<string, int>();
}
private bool LoadData()
{
var itemsdatafile = Interface.Oxide.DataFileSystem.GetFile("StackSizeController");
try
{
items = itemsdatafile.ReadObject<Items>();
return true;
}
catch (Exception ex)
{
PrintWarning("Error: Data file is corrupt. Debug info: " + ex.Message);
return false;
}
}
private void UpdateItems()
{
var gameitemList = ItemManager.itemList;
List<string> itemCategories = new List<string>();
int stacksize;
foreach (var item in gameitemList)
{
if (!itemCategories.Contains(item.category.ToString()))
{
if (!(configData.Settings.CategoryDefaultStack.ContainsKey(item.category.ToString())))
{
configData.Settings.CategoryDefaultStack[item.category.ToString()] = configData.Settings.NewCategoryDefaultSetting;
Puts("Added item category: '" + item.category.ToString() + "' to the config.");
}
itemCategories.Add(item.category.ToString());
}
if (!(items.itemlist.ContainsKey(item.displayName.english)))
{
stacksize = DetermineStack(item);
items.itemlist.Add(item.displayName.english, stacksize);
}
}
List<string> KeysToRemove = new List<string>();
foreach (KeyValuePair<string ,int> category in configData.Settings.CategoryDefaultStack)
{
if (!itemCategories.Contains(category.Key)) { KeysToRemove.Add(category.Key); }
}
if (KeysToRemove.Count > 0)
{
Puts("Cleaning config categories...");
foreach (string Key in KeysToRemove)
{
configData.Settings.CategoryDefaultStack.Remove(Key);
}
}
SaveConfig();
KeysToRemove = new List<string>();
bool foundItem = false;
foreach (KeyValuePair<string, int> item in items.itemlist)
{
foreach (var itemingamelist in gameitemList)
{
if (itemingamelist.displayName.english == item.Key)
{
foundItem = true;
break;
}
}
if (!(foundItem)) { KeysToRemove.Add(item.Key); }
foundItem = false;
}
if (KeysToRemove.Count > 0)
{
Puts("Cleaning data file...");
foreach (string key in KeysToRemove)
{
items.itemlist.Remove(key);
}
}
SaveData();
LoadStackSizes();
}
private int DetermineStack(ItemDefinition item)
{
if (item.condition.enabled && item.condition.max > 0 && (!configData.Settings.StackHealthItems))
{
return 1;
}
else
{
if (configData.Settings.DefaultStack != 0 && (!configData.Settings.CategoryDefaultStack.ContainsKey(item.category.ToString())))
{
return configData.Settings.DefaultStack;
}
else if (configData.Settings.CategoryDefaultStack.ContainsKey(item.category.ToString()) && configData.Settings.CategoryDefaultStack[item.category.ToString()] != 0)
{
return configData.Settings.CategoryDefaultStack[item.category.ToString()];
}
else if (configData.Settings.DefaultStack != 0 && configData.Settings.CategoryDefaultStack[item.category.ToString()] == 0)
{
return configData.Settings.DefaultStack;
}
else
{
return item.stackable;
}
}
}
private void LoadStackSizes()
{
var gameitemList = ItemManager.itemList;
foreach (var item in gameitemList)
{
item.stackable = items.itemlist[item.displayName.english];
}
}
private void SaveData()
{
Interface.Oxide.DataFileSystem.WriteObject("StackSizeController", items);
}
#endregion
#region Config
ConfigData configData;
class ConfigData
{
public SettingsData Settings { get; set; }
}
class SettingsData
{
public int DefaultStack { get; set; }
public int NewCategoryDefaultSetting { get; set; }
public bool StackHealthItems { get; set; }
public Dictionary<string, int> CategoryDefaultStack { get; set; }
}
private void TryConfig()
{
try
{
configData = Config.ReadObject<ConfigData>();
}
catch (Exception ex)
{
PrintWarning("Corrupt config detected, debug: " + ex.Message);
LoadDefaultConfig();
}
}
protected override void LoadDefaultConfig()
{
Puts("Generating a new config file...");
Config.WriteObject(new ConfigData
{
Settings = new SettingsData
{
DefaultStack = 0,
NewCategoryDefaultSetting = 0,
StackHealthItems = true,
CategoryDefaultStack = new Dictionary<string, int>()
{
{ "Ammunition", 0 },
{ "Weapon", 0 },
},
},
}, true);
}
private void SaveConfig()
{
Config.WriteObject(configData);
}
#endregion
#region Hooks
private void OnServerInitialized()
{
TryConfig();
pluginLoaded = LoadData();
if (pluginLoaded)
{
if (!configData.Settings.StackHealthItems) { Unsubscribe(); }
UpdateItems();
}
else { Puts("Stack Sizes could not be changed due to a corrupt data file."); }
permission.RegisterPermission("stacksizecontroller.canChangeStackSize", this);
}
private bool hasPermission(BasePlayer player, string perm)
{
if (player.net.connection.authLevel > 1)
{
return true;
}
return permission.UserHasPermission(player.userID.ToString(), perm);
}
private object CanStackItem(Item item, Item targetItem)
{
if (item.info.shortname != targetItem.info.shortname) { return null; }
if (item.contents != targetItem.contents) { return false; }
FlameThrower flamethrower = item.GetHeldEntity() as FlameThrower;
if (flamethrower != null)
{
if (flamethrower.ammo != (targetItem.GetHeldEntity() as FlameThrower).ammo) { return false; }
}
return null;
}
private void Unsubscribe()
{
Unsubscribe(nameof(CanStackItem));
}
#endregion
#region Commands
[ChatCommand("stack")]
private void StackCommand(BasePlayer player, string command, string[] args)
{
if (!hasPermission(player, "stacksizecontroller.canChangeStackSize"))
{
SendReply(player, "You don't have permission to use this command.");
return;
}
if (!pluginLoaded)
{
SendReply(player, "StackSizeController has encountered an error while trying to read the data file. Please contact your server administrator to fix the issue.");
return;
}
if (args.Length < 2)
{
SendReply(player, "Syntax Error: Requires 2 arguments. Syntax Example: /stack ammo.rocket.hv 64 (Use shortname)");
return;
}
int stackAmount = 0;
List<ItemDefinition> gameitems = ItemManager.itemList.FindAll(x => x.shortname.Equals(args[0]));
if (gameitems.Count == 0)
{
SendReply(player, "Syntax Error: That is an incorrect item name. Please use a valid shortname.");
return;
}
string replymessage = "";
switch (args[1].ToLower())
{
case "default":
{
stackAmount = DetermineStack(gameitems[0]);
replymessage = "Updated Stack Size for " + gameitems[0].displayName.english + " (" + gameitems[0].shortname + ") to " + stackAmount + " (Default value based on config).";
break;
}
default:
{
if (int.TryParse(args[1], out stackAmount) == false)
{
SendReply(player, "Syntax Error: Stack Amount is not a number. Syntax Example: /stack ammo.rocket.hv 64 (Use shortname)");
return;
}
replymessage = "Updated Stack Size for " + gameitems[0].displayName.english + " (" + gameitems[0].shortname + ") to " + stackAmount + ".";
break;
}
}
if (gameitems[0].condition.enabled && gameitems[0].condition.max > 0)
{
if (!(configData.Settings.StackHealthItems))
{
SendReply(player, "Error: Stacking health items is disabled in the config.");
return;
}
}
items.itemlist[gameitems[0].displayName.english] = Convert.ToInt32(stackAmount);
gameitems[0].stackable = Convert.ToInt32(stackAmount);
SaveData();
SendReply(player, replymessage);
}
[ChatCommand("stackall")]
private void StackAllCommand(BasePlayer player, string command, string[] args)
{
if (!hasPermission(player, "stacksizecontroller.canChangeStackSize"))
{
SendReply(player, "You don't have permission to use this command.");
return;
}
if (!pluginLoaded)
{
SendReply(player, "StackSizeController has encountered an error while trying to read the data file. Please contact your server administrator to fix the issue.");
return;
}
if (args.Length < 1)
{
SendReply(player, "Syntax Error: Requires 1 argument. Syntax Example: /stackall 65000");
return;
}
int stackAmount = 0;
string replymessage = "";
var itemList = ItemManager.itemList;
foreach (var gameitem in itemList)
{
switch (args[0].ToLower())
{
case "default":
{
stackAmount = DetermineStack(gameitem);
replymessage = "The Stack Size of all stackable items has been set to their default values (specified in config).";
break;
}
default:
{
if (int.TryParse(args[0], out stackAmount) == false)
{
SendReply(player, "Syntax Error: Stack Amount is not a number. Syntax Example: /stackall 65000");
return;
}
replymessage = "The Stack Size of all stackable items has been set to " + stackAmount.ToString() + ".";
break;
}
}
if (gameitem.condition.enabled && gameitem.condition.max > 0 && !(configData.Settings.StackHealthItems)) { continue; }
if (gameitem.displayName.english.ToString() == "Salt Water" || gameitem.displayName.english.ToString() == "Water") { continue; }
items.itemlist[gameitem.displayName.english] = Convert.ToInt32(stackAmount);
gameitem.stackable = Convert.ToInt32(stackAmount);
}
SaveData();
SendReply(player, replymessage);
}
[ConsoleCommand("stack")]
private void StackConsoleCommand(ConsoleSystem.Arg arg)
{
if (arg.IsAdmin != true)
{
if ((arg.Connection.userid.ToString() != null) && !(permission.UserHasPermission(arg.Connection.userid.ToString(), "stacksizecontroller.canChangeStackSize")))
{
arg.ReplyWith("[StackSizeController] You don't have permission to use this command.");
return;
}
}
if (!pluginLoaded)
{
arg.ReplyWith("[StackSizeController] StackSizeController has encountered an error while trying to read the data file. Please contact your server administrator to fix the issue.");
return;
}
if (arg.Args != null)
{
if (arg.Args.Length < 2)
{
arg.ReplyWith("[StackSizeController] Syntax Error: Requires 2 arguments. Syntax Example: stack ammo.rocket.hv 64 (Use shortname)");
return;
}
}
else
{
arg.ReplyWith("[StackSizeController] Syntax Error: Requires 2 arguments. Syntax Example: stack ammo.rocket.hv 64 (Use shortname)");
return;
}
int stackAmount = 0;
List<ItemDefinition> gameitems = ItemManager.itemList.FindAll(x => x.shortname.Equals(arg.Args[0]));
if (gameitems.Count == 0)
{
arg.ReplyWith("[StackSizeController] Syntax Error: That is an incorrect item name. Please use a valid shortname.");
return;
}
string replymessage = "";
switch (arg.Args[1].ToLower())
{
case "default":
{
stackAmount = DetermineStack(gameitems[0]);
replymessage = "[StackSizeController] Updated Stack Size for " + gameitems[0].displayName.english + " (" + gameitems[0].shortname + ") to " + stackAmount + " (Default value based on config).";
break;
}
default:
{
if (int.TryParse(arg.Args[1], out stackAmount) == false)
{
arg.ReplyWith("[StackSizeController] Syntax Error: Stack Amount is not a number. Syntax Example: /stack ammo.rocket.hv 64 (Use shortname)");
return;
}
replymessage = "[StackSizeController] Updated Stack Size for " + gameitems[0].displayName.english + " (" + gameitems[0].shortname + ") to " + stackAmount + ".";
break;
}
}
if (gameitems[0].condition.enabled && gameitems[0].condition.max > 0)
{
if (!(configData.Settings.StackHealthItems))
{
arg.ReplyWith("[StackSizeController] Error: Stacking health items is disabled in the config.");
return;
}
}
items.itemlist[gameitems[0].displayName.english] = Convert.ToInt32(stackAmount);
gameitems[0].stackable = Convert.ToInt32(stackAmount);
SaveData();
arg.ReplyWith(replymessage);
}
[ConsoleCommand("stackall")]
private void StackAllConsoleCommand(ConsoleSystem.Arg arg)
{
if (arg.IsAdmin != true)
{
if ((arg.Connection.userid.ToString() != null) && !(permission.UserHasPermission(arg.Connection.userid.ToString(), "stacksizecontroller.canChangeStackSize")))
{
arg.ReplyWith("[StackSizeController] You don't have permission to use this command.");
return;
}
}
if (!pluginLoaded)
{
arg.ReplyWith("[StackSizeController] StackSizeController has encountered an error while trying to read the data file. Please contact your server administrator to fix the issue.");
return;
}
if (arg.Args != null)
{
if (arg.Args.Length < 1)
{
arg.ReplyWith("[StackSizeController] Syntax Error: Requires 1 argument. Syntax Example: stackall 65000");
return;
}
}
else
{
arg.ReplyWith("[StackSizeController] Syntax Error: Requires 1 argument. Syntax Example: stackall 65000");
return;
}
int stackAmount = 0;
string replymessage = "";
var itemList = ItemManager.itemList;
foreach (var gameitem in itemList)
{
if (gameitem.condition.enabled && gameitem.condition.max > 0 && (!(configData.Settings.StackHealthItems))) { continue; }
if (gameitem.displayName.english.ToString() == "Salt Water" ||
gameitem.displayName.english.ToString() == "Water") { continue; }
switch (arg.Args[0].ToLower())
{
case "default":
{
stackAmount = DetermineStack(gameitem);
replymessage = "[StackSizeController] The Stack Size of all stackable items has been set to their default values (specified in config).";
break;
}
default:
{
if (int.TryParse(arg.Args[0], out stackAmount) == false)
{
arg.ReplyWith("[StackSizeController] Syntax Error: Stack Amount is not a number. Syntax Example: /stackall 65000");
return;
}
replymessage = "[StackSizeController] The Stack Size of all stackable items has been set to " + stackAmount.ToString() + ".";
break;
}
}
items.itemlist[gameitem.displayName.english] = Convert.ToInt32(stackAmount);
gameitem.stackable = Convert.ToInt32(stackAmount);
}
SaveData();
arg.ReplyWith(replymessage);
}
#endregion
}
}