Иконка ресурса

FREE SmeltingController : 1.5.15 1.5.15

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
// Reference: 0Harmony

/**
 * OxidationSmelting - Smelting controller
 * Copyright (C) 2021-2023 kasvoton [kasvoton@stinkfist.org]
 *
 * All Rights Reserved.* DO NOT DISTRIBUTE THIS SOFTWARE.*
 * You should have received a copy of the EULA along with this software.* If not, see <https://oxidation.stinkfist.org/license/eula.txt>.*
 *
 *                #################################
 *               ###  I AM AVAILABLE FOR HIRING  ###
 *                #################################
 *
 * IF YOU WANT A CUSTOM PLUGIN FOR YOUR SERVER GET INTO CONTACT WITH ME SO
 * WE CAN DISCUSS YOUR NEED IN DETAIL.I CAN BUILD PLUGINS FROM SCRATCH OR
 * MODIFY EXISTING ONES DEPENDING ON THE COMPLEXITY.*
 */

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using Facepunch.Extend;
using HarmonyLib;
using Newtonsoft.Json;
using Oxide.Core;

#pragma warning disable IDE0058

namespace Oxide.Plugins
{

	[Info("SmeltingController", "codefling.com/kasvoton", "1.5.15")]

	public class SmeltingController : RustPlugin
	{
		private Harmony _harmony;

		// --- EVENTS ------------------------------------------------------------------------------------------------------------
		internal void Loaded()
		{
			Harmony.DEBUG = ConVar.Global.developer > 0;
			_harmony = new Harmony($"{Name}_{Version.Major}_{Version.Minor}_{Version.Patch}");
		}

		internal void OnServerInitialized()
		{
			try
			{
				SaveConfig();
				ApplySettings();

				_ = _harmony.Patch(
					AccessTools.Method(typeof(ItemModCookable), "CycleCooking"),
					transpiler: new HarmonyMethod(typeof(CycleCookingPatch), "Transpiler"));

				_ = _harmony.Patch(
					AccessTools.Method(typeof(BaseOven), "ConsumeFuel"),
					transpiler: new HarmonyMethod(typeof(ConsumeFuelPatch), "Transpiler"));
			}
			catch
			{
				NextFrame(() =>
				{
					WriteError($"Issues were detected while parsing the config file, exiting..");
					Interface.Oxide.UnloadPlugin(Name);
				});
			}
		}

		internal void Unload()
		{
			Harmony.DEBUG = false;
			_harmony.UnpatchAll($"{Name}_{Version.Major}_{Version.Minor}_{Version.Patch}");
			RevertSettings();
		}

		// --- HARMONY -----------------------------------------------------------------------------------------------------------
		public class CycleCookingPatch
		{
			public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				List<CodeInstruction> il = new(instructions);

				int index = il.FindIndex(i => i.opcode == OpCodes.Stloc_2);

				if (index > 0)
				{
					il.InsertRange(index + 1, new List<CodeInstruction>()
					{
						new(OpCodes.Ldloc_2),
						new (OpCodes.Call, AccessTools.Method(typeof(SmeltingController), nameof(GetMultiplication))),
						new (OpCodes.Ldloc_1),
						new (OpCodes.Mul),
						new (OpCodes.Stloc_1)
					});
				}

				return il;
			}
		}

		public class ConsumeFuelPatch
		{
			public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				List<CodeInstruction> il = new(instructions);

				MethodInfo getFuelRate = AccessTools.Method(typeof(BaseOven), nameof(BaseOven.GetFuelRate));
				MethodInfo getCharcoalRate = AccessTools.Method(typeof(BaseOven), nameof(BaseOven.GetCharcoalRate));

				foreach (CodeInstruction instruction in il)
				{
					MethodInfo methodInfo = instruction.operand as MethodInfo;

					if (methodInfo == getFuelRate)
					{
						yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(SmeltingController), nameof(GetMultiplication)));
					}
					else if (methodInfo == getCharcoalRate)
					{
						yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(SmeltingController), nameof(GetCharcoalRate)));
					}
					else
					{
						yield return instruction;
					}
				}
			}
		}

		// --- UTILITY -----------------------------------------------------------------------------------------------------------
		protected static int GetMultiplication(BaseOven instance)
		{
			try
			{
				if (!Settings.Ovens.TryGetValue(instance.ShortPrefabName, out PluginSettings.OvenSettings oven))
				{
					return 1;
				}
				return oven.Multiplier;
			}
			catch (Exception)
			{
				return 1;
			}
		}

		protected static int GetCharcoalRate(BaseOven instance)
		{
			try
			{
				if (!Settings.Ovens.TryGetValue(instance.ShortPrefabName, out PluginSettings.OvenSettings oven))
				{
					return 1;
				}
				return oven.Charcoal;
			}
			catch (Exception)
			{
				return 1;
			}
		}

		// --- CONFIGURATION -----------------------------------------------------------------------------------------------------
		private static PluginSettings Settings;

		protected override void LoadConfig()
		{
			try
			{
				base.LoadConfig();
				Settings = Config.ReadObject<PluginSettings>();
			}
			catch (JsonReaderException)
			{
				// do nothing
			}
			catch (Exception)
			{
				LoadDefaultConfig();
				SaveConfig();
			}
		}

		protected override void SaveConfig()
		{
			Config.WriteObject(Settings, true);
		}

		protected override void LoadDefaultConfig()
		{
			WriteWarning($"Created a new default config file");

			Settings = new PluginSettings
			{
				NoBurntMeat = false
			};

			foreach (string Oven in Ovens)
			{
				Settings.Ovens.Add(Oven, new PluginSettings.OvenSettings());
			}

			foreach (ItemDefinition Item in ItemManager.itemList)
			{
				foreach (ItemMod mod in Item.itemMods)
				{
					if (Item.shortname.Contains(".burned") || Item.shortname.Contains(".cooked"))
					{
						continue;
					}

					ItemModCookable Cookable = mod as ItemModCookable;

					if (Cookable != null)
					{
						Settings.Products.Add(Item.shortname, value: new PluginSettings.ProductSettings
						{
							Amount = Cookable.amountOfBecome,
							CookTime = Cookable.cookTime
						});
					}

					ItemModBurnable Burnable = mod as ItemModBurnable;

					if (Burnable != null && Burnable.byproductItem != null)
					{
						Settings.Fuel.Add(Item.shortname, value: new PluginSettings.FuelSettings
						{
							FuelAmount = Burnable.fuelAmount,
							ByProduct = Burnable.byproductItem.shortname,
							ByProductAmount = Burnable.byproductAmount,
							ByProductChance = 1 - Burnable.byproductChance,
						});
					}
				}
			}
		}

		protected void ApplySettings()
		{
			foreach (ItemDefinition Item in ItemManager.itemList)
			{
				foreach (ItemMod mod in Item.itemMods)
				{
					ItemModCookable cookable = mod as ItemModCookable;
					if (cookable != null)
					{
						PluginSettings.ProductSettings info;
						if (Settings.Products.TryGetValue(Item.shortname, out info))
						{
							if (!Backup.Products.ContainsKey(Item.shortname))
							{
								Backup.Products.Add(Item.shortname, value: new PluginSettings.ProductSettings
								{
									Amount = cookable.amountOfBecome,
									CookTime = cookable.cookTime,
									LowTemp = cookable.lowTemp,
									HighTemp = cookable.highTemp
								});
							}

							if (cookable.amountOfBecome != info.Amount)
							{
								WriteInfo($"Changed '{Item.shortname}' amountOfBecome from {cookable.amountOfBecome} to {info.Amount}");
								cookable.amountOfBecome = info.Amount;
							}

							if (cookable.cookTime != info.CookTime)
							{
								WriteInfo($"Changed '{Item.shortname}' cookTime from {cookable.cookTime} to {info.CookTime}");
								cookable.cookTime = info.CookTime;
							}
						}

						if (Settings.NoBurntMeat && Item.shortname.Contains(".cooked"))
						{
							if (!Backup.Products.ContainsKey(Item.shortname))
							{
								Backup.Products.Add(Item.shortname, value: new PluginSettings.ProductSettings
								{
									Amount = cookable.amountOfBecome,
									CookTime = cookable.cookTime,
									LowTemp = cookable.lowTemp,
									HighTemp = cookable.highTemp
								});
							}

							cookable.highTemp = -1;
							cookable.lowTemp = -1;
						}
					}

					ItemModBurnable Burnable = mod as ItemModBurnable;
					if (Burnable != null && Burnable.byproductItem != null)
					{
						PluginSettings.FuelSettings info;
						if (Settings.Fuel.TryGetValue(Item.shortname, out info))
						{
							Backup.Fuel.Add(Item.shortname, value: new PluginSettings.FuelSettings
							{
								FuelAmount = Burnable.fuelAmount,
								ByProductChance = Burnable.byproductChance,
								ByProductAmount = Burnable.byproductAmount
							});

							Burnable.fuelAmount = info.FuelAmount;
							Burnable.byproductAmount = info.ByProductAmount;
							Burnable.byproductChance = 1 - info.ByProductChance;
						}
					}
				}
			};
		}

		protected void RevertSettings()
		{
			foreach (KeyValuePair<string, PluginSettings.ProductSettings> kvp in Backup.Products)
			{
				if (!ItemManager.FindItemDefinition(kvp.Key).TryGetComponent(out ItemModCookable Cookable))
				{
					continue;
				}

				Cookable.amountOfBecome = kvp.Value.Amount;
				Cookable.cookTime = kvp.Value.CookTime;
				Cookable.highTemp = kvp.Value.HighTemp;
				Cookable.lowTemp = kvp.Value.LowTemp;
			}

			foreach (KeyValuePair<string, PluginSettings.FuelSettings> kvp in Backup.Fuel)
			{
				if (!ItemManager.FindItemDefinition(kvp.Key).TryGetComponent(out ItemModBurnable Burnable))
				{
					continue;
				}

				Burnable.fuelAmount = kvp.Value.FuelAmount;
				Burnable.byproductAmount = kvp.Value.ByProductAmount;
				Burnable.byproductChance = kvp.Value.ByProductChance;
			}
		}

		internal sealed class PluginSettings
		{
			public bool NoBurntMeat
			{ get; set; }

			public Dictionary<string, OvenSettings> Ovens
			{ get; set; } = new();

			public Dictionary<string, ProductSettings> Products
			{ get; set; } = new();

			public Dictionary<string, FuelSettings> Fuel
			{ get; set; } = new();

			internal sealed class OvenSettings
			{
				private int _speed = 1;
				private int _charcoalRate = 1;

				public int Multiplier
				{
					get { return _speed; }
					set { _speed = value.Clamp(1, 100); }
				}

				public int Charcoal
				{
					get { return _charcoalRate; }
					set { _charcoalRate = value.Clamp(1, 100); }
				}
			}

			internal sealed class ProductSettings
			{
				private int _amountValue = 1;
				private float _cookTimeValue = 10f;

				public float CookTime
				{
					get { return _cookTimeValue; }
					set { _cookTimeValue = value.Clamp(1f, 60f); }
				}

				public int Amount
				{
					get { return _amountValue; }
					set { _amountValue = value.Clamp(1, int.MaxValue); }
				}

				[JsonIgnore]
				public int LowTemp
				{ get; set; } = -1;

				[JsonIgnore]
				public int HighTemp
				{ get; set; } = -1;
			}

			internal sealed class FuelSettings
			{
				private float _fuelAmountValue = 1f;
				private int _byProductAmountValue = 1;
				private float _byProductChanceValue = 1f;

				public float FuelAmount
				{
					get { return _fuelAmountValue; }
					set { _fuelAmountValue = value.Clamp(1f, float.MaxValue); }
				}

				public string ByProduct
				{
					get; set;
				}

				public int ByProductAmount
				{
					get { return _byProductAmountValue; }
					set { _byProductAmountValue = value.Clamp(1, int.MaxValue); }
				}

				public float ByProductChance
				{
					get { return _byProductChanceValue; }
					set { _byProductChanceValue = value.Clamp(0f, 1f); }
				}
			}
		}

		// --- CACHE -------------------------------------------------------------------------------------------------------------
		private readonly Cache Backup = new();

		internal sealed class Cache
		{
			public Dictionary<string, PluginSettings.ProductSettings> Products
			{ get; set; } = new();

			public Dictionary<string, PluginSettings.FuelSettings> Fuel
			{ get; set; } = new();
		}

		private static readonly string[] Ovens =
		{
			"bbq.campermodule",
			"bbq.deployed",
			"campfire",
			"carvable.pumpkin",
			"chineselantern.deployed",
			"cursedcauldron.deployed",
			"electricfurnace.deployed",
			"fireplace.deployed",
			"furnace.large",
			"furnace",
			"hobobarrel.deployed",
			"jackolantern.angry",
			"jackolantern.happy",
			"lantern.deployed",
			"legacy_furnace",
			"refinery_small_deployed",
			"skull_fire_pit",
			"tunalight.deployed",
		};

		// --- LOGGING -----------------------------------------------------------------------------------------------------------
		internal void WriteInfo(string format, params object[] args)
		{
			Puts("[INFO] " + format, args);
		}

		internal void WriteWarning(string format, params object[] args)
		{
			PrintWarning("[WARNING] " + format, args);
		}

		internal void WriteError(string format, params object[] args)
		{
			PrintError("[ERROR] " + format, args);
		}
	}
}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху