Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of TimedCraftSpeed v1.0.5
plugins/TimedCraftSpeed.dll
Decompiled 6 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("TimedCraftSpeed")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.5.0")] [assembly: AssemblyInformationalVersion("1.0.5")] [assembly: AssemblyProduct("TimedCraftSpeed")] [assembly: AssemblyTitle("TimedCraftSpeed")] [assembly: AssemblyVersion("1.0.5.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace TimedCraftSpeed { internal sealed class ConfigurationManagerAttributes { public string DispName; } [BepInPlugin("local.timedcraftspeed", "Timed Craft Speed", "1.0.5")] public sealed class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(Smelter), "Awake")] private static class SmelterAwakePatch { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(Smelter __instance) { if ((Object)(object)_instance != (Object)null) { _instance.ApplySmelter(__instance); } } } [HarmonyPatch(typeof(Fermenter), "Awake")] private static class FermenterAwakePatch { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(Fermenter __instance) { if ((Object)(object)_instance != (Object)null) { _instance.ApplyFermenter(__instance); } } } [HarmonyPatch(typeof(CookingStation), "Awake")] private static class CookingStationAwakePatch { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(CookingStation __instance) { if ((Object)(object)_instance != (Object)null) { _instance.ApplyCookingStation(__instance); } } } private sealed class ReferenceComparer : IEqualityComparer<object> { public static readonly ReferenceComparer Instance = new ReferenceComparer(); public new bool Equals(object x, object y) { return x == y; } public int GetHashCode(object obj) { return RuntimeHelpers.GetHashCode(obj); } } public const string PluginGuid = "local.timedcraftspeed"; public const string PluginName = "Timed Craft Speed"; public const string PluginVersion = "1.0.5"; private const string ConfigSection = "Multiplicateurs de vitesse"; private static Plugin _instance; private Harmony _harmony; private float _nextLabelRefresh; private static readonly Dictionary<string, ConfigEntry<float>> Multipliers = new Dictionary<string, ConfigEntry<float>>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, ConfigurationManagerAttributes> DisplayAttributes = new Dictionary<string, ConfigurationManagerAttributes>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, string> EnglishNames = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "smelter", "Smelter" }, { "charcoal_kiln", "Charcoal Kiln" }, { "blastfurnace", "Blast Furnace" }, { "windmill", "Windmill" }, { "piece_spinningwheel", "Spinning Wheel" }, { "eitrrefinery", "Eitr Refinery" }, { "fermenter", "Fermenter" }, { "piece_cookingstation", "Cooking Station" }, { "piece_cookingstation_iron", "Iron Cooking Station" }, { "piece_oven", "Stone Oven" }, { "piece_FrostKiln", "Frigid Kiln" }, { "piece_FrostFoundry", "Frost Foundry" } }; private static readonly Dictionary<string, string> LocalizationTokens = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "smelter", "$piece_smelter" }, { "charcoal_kiln", "$piece_charcoalkiln" }, { "blastfurnace", "$piece_blastfurnace" }, { "windmill", "$piece_windmill" }, { "piece_spinningwheel", "$piece_spinningwheel" }, { "eitrrefinery", "$piece_eitrrefinery" }, { "fermenter", "$piece_fermenter" }, { "piece_cookingstation", "$piece_cookingstation" }, { "piece_cookingstation_iron", "$piece_cookingstation_iron" }, { "piece_oven", "$piece_oven" }, { "piece_FrostKiln", "$piece_frostkiln" }, { "piece_FrostFoundry", "$piece_frostfoundry" } }; private static readonly Dictionary<string, string> LegacyNames = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "smelter", "Fonderie" }, { "charcoal_kiln", "Four a charbon" }, { "blastfurnace", "Haut fourneau" }, { "windmill", "Moulin" }, { "piece_spinningwheel", "Rouet" }, { "eitrrefinery", "Raffinerie d'Eitr" }, { "fermenter", "Fermenteur" }, { "piece_cookingstation", "Station de cuisson" }, { "piece_cookingstation_iron", "Station de cuisson en fer" }, { "piece_oven", "Four en pierre" }, { "piece_FrostKiln", "Four glacial" }, { "piece_FrostFoundry", "Fonderie du givre" } }; private static readonly Dictionary<string, float> FloatBaselines = new Dictionary<string, float>(); private static readonly Dictionary<object, float> ConversionBaselines = new Dictionary<object, float>(ReferenceComparer.Instance); private void Awake() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown _instance = this; RegisterDefaultSettings(); _harmony = new Harmony("local.timedcraftspeed"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Timed Craft Speed actif."); } private void Update() { if (!(Time.unscaledTime < _nextLabelRefresh)) { _nextLabelRefresh = Time.unscaledTime + 1f; RefreshLocalizedLabels(); } } private void OnDestroy() { if (_harmony != null) { _harmony.UnpatchSelf(); } _instance = null; } private void RegisterDefaultSettings() { EnsureMultiplier("smelter"); EnsureMultiplier("charcoal_kiln"); EnsureMultiplier("blastfurnace"); EnsureMultiplier("windmill"); EnsureMultiplier("piece_spinningwheel"); EnsureMultiplier("eitrrefinery"); EnsureMultiplier("fermenter"); EnsureMultiplier("piece_cookingstation"); EnsureMultiplier("piece_cookingstation_iron"); EnsureMultiplier("piece_oven"); EnsureMultiplier("piece_FrostKiln"); EnsureMultiplier("piece_FrostFoundry"); } private ConfigEntry<float> EnsureMultiplier(string prefabName) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown prefabName = NormalizePrefabName(prefabName); if (string.IsNullOrEmpty(prefabName)) { return null; } if (Multipliers.TryGetValue(prefabName, out var value)) { return value; } string englishName = GetEnglishName(prefabName); if (!LegacyNames.TryGetValue(prefabName, out var value2)) { value2 = englishName; } string text = SanitizeConfigKey(value2 + " - " + prefabName); ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes { DispName = englishName }; ConfigEntry<float> val = ((BaseUnityPlugin)this).Config.Bind<float>("Multiplicateurs de vitesse", text, 1f, new ConfigDescription("Multiplicateur de vitesse.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 20f), new object[1] { configurationManagerAttributes })); Multipliers[prefabName] = val; DisplayAttributes[prefabName] = configurationManagerAttributes; val.SettingChanged += delegate { RefreshLiveMachines(); }; return val; } private static string GetEnglishName(string prefabName) { if (EnglishNames.TryGetValue(prefabName, out var value)) { return value; } value = prefabName; if (value.StartsWith("piece_", StringComparison.OrdinalIgnoreCase)) { value = value.Substring(6); } return value.Replace('_', ' '); } private static string SanitizeConfigKey(string value) { if (string.IsNullOrEmpty(value)) { return "Machine"; } char[] array = new char[8] { '=', '\n', '\t', '\\', '"', '\'', '[', ']' }; foreach (char oldChar in array) { value = value.Replace(oldChar, '-'); } return value.Trim(); } private static string NormalizePrefabName(string name) { if (string.IsNullOrEmpty(name)) { return string.Empty; } if (name.EndsWith("(Clone)", StringComparison.Ordinal)) { name = name.Substring(0, name.Length - "(Clone)".Length); } return name.Trim(); } private static object GetLocalizationInstance() { BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { Type type = assemblies[i].GetType("Localization", throwOnError: false); if (!(type == null)) { FieldInfo field = type.GetField("instance", bindingAttr); if (field == null) { field = type.GetField("m_instance", bindingAttr); } if (field != null) { return field.GetValue(null); } PropertyInfo property = type.GetProperty("instance", bindingAttr); if (property != null) { return property.GetValue(null, null); } } } return null; } private static string LocalizeGameText(string token) { if (string.IsNullOrEmpty(token)) { return null; } object localizationInstance = GetLocalizationInstance(); if (localizationInstance == null) { return null; } MethodInfo method = localizationInstance.GetType().GetMethod("Localize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null); if (method == null) { return null; } try { return method.Invoke(localizationInstance, new object[1] { token }) as string; } catch { return null; } } private void RefreshLocalizedLabels() { foreach (KeyValuePair<string, string> localizationToken in LocalizationTokens) { string text = LocalizeGameText(localizationToken.Value); if (!string.IsNullOrWhiteSpace(text)) { SetDisplayName(localizationToken.Key, text); } } } private static void SetDisplayName(string prefabName, string localized) { if (DisplayAttributes.TryGetValue(prefabName, out var value)) { string englishName = GetEnglishName(prefabName); if (string.IsNullOrWhiteSpace(localized) || localized.StartsWith("$")) { value.DispName = englishName; } else { value.DispName = englishName + " (" + localized + ")"; } } } private void UpdateDisplayNameFromPiece(Component component, string prefabName) { if ((Object)(object)component == (Object)null) { return; } Piece val = component.GetComponent<Piece>(); if ((Object)(object)val == (Object)null) { val = component.GetComponentInParent<Piece>(); } if ((Object)(object)val == (Object)null) { val = component.GetComponentInChildren<Piece>(true); } if (!((Object)(object)val == (Object)null) && !string.IsNullOrEmpty(val.m_name)) { string text = LocalizeGameText(val.m_name); if (!string.IsNullOrWhiteSpace(text)) { SetDisplayName(prefabName, text); } } } private string GetPrefabName(Component component) { if ((Object)(object)component == (Object)null) { return string.Empty; } ZNetView val = component.GetComponent<ZNetView>(); if ((Object)(object)val == (Object)null) { val = component.GetComponentInParent<ZNetView>(); } if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null) { return NormalizePrefabName(((Object)((Component)val).gameObject).name); } return NormalizePrefabName(((Object)component.gameObject).name); } private static FieldInfo GetFieldSilent(Type type, string name) { while (type != null) { FieldInfo field = type.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field; } type = type.BaseType; } return null; } private void ApplySmelter(Smelter smelter) { if ((Object)(object)smelter == (Object)null) { return; } string prefabName = GetPrefabName((Component)(object)smelter); ConfigEntry<float> val = EnsureMultiplier(prefabName); UpdateDisplayNameFromPiece((Component)(object)smelter, prefabName); if (val != null) { FieldInfo fieldSilent = GetFieldSilent(((object)smelter).GetType(), "m_secPerProduct"); if (!(fieldSilent == null) && !(fieldSilent.FieldType != typeof(float))) { ApplyFloatTimer((Component)(object)smelter, fieldSilent, prefabName, val); } } } private void ApplyFermenter(Fermenter fermenter) { if ((Object)(object)fermenter == (Object)null) { return; } string prefabName = GetPrefabName((Component)(object)fermenter); ConfigEntry<float> val = EnsureMultiplier(prefabName); UpdateDisplayNameFromPiece((Component)(object)fermenter, prefabName); if (val != null) { FieldInfo fieldSilent = GetFieldSilent(((object)fermenter).GetType(), "m_fermentationDuration"); if (!(fieldSilent == null) && !(fieldSilent.FieldType != typeof(float))) { ApplyFloatTimer((Component)(object)fermenter, fieldSilent, prefabName, val); } } } private void ApplyCookingStation(CookingStation station) { if ((Object)(object)station == (Object)null) { return; } string prefabName = GetPrefabName((Component)(object)station); ConfigEntry<float> val = EnsureMultiplier(prefabName); UpdateDisplayNameFromPiece((Component)(object)station, prefabName); if (val == null) { return; } FieldInfo fieldSilent = GetFieldSilent(((object)station).GetType(), "m_conversion"); if (fieldSilent == null || !(fieldSilent.GetValue(station) is IEnumerable enumerable)) { return; } foreach (object item in enumerable) { if (item != null) { FieldInfo fieldSilent2 = GetFieldSilent(item.GetType(), "m_cookTime"); if (!(fieldSilent2 == null) && !(fieldSilent2.FieldType != typeof(float))) { ApplyCookTimer(item, fieldSilent2, val); } } } } private void ApplyFloatTimer(Component component, FieldInfo field, string prefabName, ConfigEntry<float> multiplier) { string key = ((Object)component).GetInstanceID() + "|" + field.DeclaringType.FullName + "|" + field.Name; if (!FloatBaselines.TryGetValue(key, out var value)) { object value2 = field.GetValue(component); if (!(value2 is float)) { return; } value = (float)value2; FloatBaselines[key] = value; } float num = Math.Max(0.01f, multiplier.Value); field.SetValue(component, value / num); } private void ApplyCookTimer(object conversion, FieldInfo cookTime, ConfigEntry<float> multiplier) { if (!ConversionBaselines.TryGetValue(conversion, out var value)) { object value2 = cookTime.GetValue(conversion); if (!(value2 is float)) { return; } value = (float)value2; ConversionBaselines[conversion] = value; } float num = Math.Max(0.01f, multiplier.Value); cookTime.SetValue(conversion, value / num); } private void RefreshLiveMachines() { Smelter[] array = Resources.FindObjectsOfTypeAll<Smelter>(); foreach (Smelter val in array) { if (IsLive((Component)(object)val)) { ApplySmelter(val); } } Fermenter[] array2 = Resources.FindObjectsOfTypeAll<Fermenter>(); foreach (Fermenter val2 in array2) { if (IsLive((Component)(object)val2)) { ApplyFermenter(val2); } } CookingStation[] array3 = Resources.FindObjectsOfTypeAll<CookingStation>(); foreach (CookingStation val3 in array3) { if (IsLive((Component)(object)val3)) { ApplyCookingStation(val3); } } } private static bool IsLive(Component component) { if ((Object)(object)component == (Object)null) { return false; } ZNetView val = component.GetComponent<ZNetView>(); if ((Object)(object)val == (Object)null) { val = component.GetComponentInParent<ZNetView>(); } if ((Object)(object)val == (Object)null) { return false; } try { MethodInfo methodInfo = AccessTools.Method(typeof(ZNetView), "GetZDO", (Type[])null, (Type[])null); return methodInfo != null && methodInfo.Invoke(val, null) != null; } catch { return false; } } } }