using 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 { 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> Multipliers = new Dictionary>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary DisplayAttributes = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary EnglishNames = new Dictionary(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 LocalizationTokens = new Dictionary(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 LegacyNames = new Dictionary(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 FloatBaselines = new Dictionary(); private static readonly Dictionary ConversionBaselines = new Dictionary(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 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 val = ((BaseUnityPlugin)this).Config.Bind("Multiplicateurs de vitesse", text, 1f, new ConfigDescription("Multiplicateur de vitesse.", (AcceptableValueBase)(object)new AcceptableValueRange(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 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(); if ((Object)(object)val == (Object)null) { val = component.GetComponentInParent(); } if ((Object)(object)val == (Object)null) { val = component.GetComponentInChildren(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(); if ((Object)(object)val == (Object)null) { val = component.GetComponentInParent(); } 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 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 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 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 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 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(); foreach (Smelter val in array) { if (IsLive((Component)(object)val)) { ApplySmelter(val); } } Fermenter[] array2 = Resources.FindObjectsOfTypeAll(); foreach (Fermenter val2 in array2) { if (IsLive((Component)(object)val2)) { ApplyFermenter(val2); } } CookingStation[] array3 = Resources.FindObjectsOfTypeAll(); 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(); if ((Object)(object)val == (Object)null) { val = component.GetComponentInParent(); } 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; } } } }