Please disclose if your mod was created primarily 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 Structure Tweaks v1.36.0
StructureTweaks.dll
Decompiled 4 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using ServerSync; using Service; using StructureTweaksPlugin; using TMPro; 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("StructureTweaks")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+c520c010e54f91faa1c6fe068280f29451a544a1")] [assembly: AssemblyProduct("StructureTweaks")] [assembly: AssemblyTitle("StructureTweaks")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 Service { public class ConfigWrapper { private readonly ConfigFile ConfigFile; private readonly ConfigSync ConfigSync; private readonly Dictionary<string, Action<Terminal, string>> SettingHandlers = new Dictionary<string, Action<Terminal, string>>(); private static readonly HashSet<string> Truthies = new HashSet<string> { "1", "true", "yes", "on" }; private static readonly HashSet<string> Falsies = new HashSet<string> { "0", "false", "no", "off" }; public ConfigWrapper(string command, ConfigFile configFile, ConfigSync configSync) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_004a: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) ConfigFile = configFile; ConfigSync = configSync; new ConsoleCommand(command, "[key] [value] - Toggles or sets a config value.", (ConsoleEvent)delegate(ConsoleEventArgs args) { if (args.Length >= 2 && SettingHandlers.TryGetValue(args[1].ToLower(), out Action<Terminal, string> value)) { if (args.Length == 2) { value(args.Context, ""); } else { value(args.Context, string.Join(" ", args.Args.Skip(2))); } } }, false, false, false, false, false, (ConsoleOptionsFetcher)(() => SettingHandlers.Keys.ToList()), false, false, false); } public ConfigEntry<bool> BindLocking(string group, string name, bool value, ConfigDescription description) { ConfigEntry<bool> val = ConfigFile.Bind<bool>(group, name, value, description); Register(val); ConfigSync.AddLockingConfigEntry<bool>(val).SynchronizedConfig = true; return val; } public ConfigEntry<bool> BindLocking(string group, string name, bool value, string description) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown return BindLocking(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>())); } public ConfigEntry<T> Bind<T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true) { ConfigEntry<T> val = ConfigFile.Bind<T>(group, name, value, description); Register<T>(val); ConfigSync.AddConfigEntry<T>(val).SynchronizedConfig = synchronizedSetting; return val; } public ConfigEntry<T> Bind<T>(string group, string name, T value, string description, bool synchronizedSetting = true) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return Bind(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting); } private static void AddMessage(Terminal context, string message) { context.AddString(message); Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, message, 0, (Sprite)null); } } private void Register(ConfigEntry<bool> setting) { ConfigEntry<bool> setting2 = setting; string name = ((ConfigEntryBase)setting2).Definition.Key; string key = name.ToLower().Replace(' ', '_'); SettingHandlers.Add(key, delegate(Terminal terminal, string value) { Toggle(terminal, setting2, name, value); }); } private void Register<T>(ConfigEntry<T> setting) { ConfigEntry<T> setting2 = setting; string name = ((ConfigEntryBase)setting2).Definition.Key; string key = name.ToLower().Replace(' ', '_'); SettingHandlers.Add(key, delegate(Terminal terminal, string value) { SetValue<T>(terminal, setting2, name, value); }); } private static string State(bool value) { if (!value) { return "disabled"; } return "enabled"; } private static bool IsTruthy(string value) { return Truthies.Contains(value); } private static bool IsFalsy(string value) { return Falsies.Contains(value); } private static void Toggle(Terminal context, ConfigEntry<bool> setting, string name, string value) { if (value == "") { setting.Value = !setting.Value; } else if (IsTruthy(value)) { setting.Value = true; } else if (IsFalsy(value)) { setting.Value = false; } AddMessage(context, name + " " + State(setting.Value) + "."); } public static int TryParseInt(string value, int defaultValue) { if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return result; } return defaultValue; } public static int TryParseInt(ConfigEntry<string> setting) { if (int.TryParse(setting.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return result; } return TryParseInt((string)((ConfigEntryBase)setting).DefaultValue, 0); } private static float TryParseFloat(string value, float defaultValue) { if (float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return result; } return defaultValue; } public static float TryParseFloat(ConfigEntry<string> setting) { if (float.TryParse(setting.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return result; } return TryParseFloat((string)((ConfigEntryBase)setting).DefaultValue, 0f); } private static void SetValue<T>(Terminal context, ConfigEntry<T> setting, string name, string value) { if (value == "") { AddMessage(context, $"{name}: {setting.Value}."); return; } setting.Value = (T)(object)value; AddMessage(context, name + " set to " + value + "."); } } public static class Hash { public static readonly int Name = StringExtensionMethods.GetStableHashCode("override_name"); public static readonly int Destroy = StringExtensionMethods.GetStableHashCode("override_destroy"); public static readonly int DestroyEffect = StringExtensionMethods.GetStableHashCode("override_destroy_effect"); public static readonly int DungeonWeather = StringExtensionMethods.GetStableHashCode("override_dungeon_weather"); public static readonly int EnterText = StringExtensionMethods.GetStableHashCode("override_dungeon_enter_text"); public static readonly int EnterHover = StringExtensionMethods.GetStableHashCode("override_dungeon_enter_hover"); public static readonly int ExitText = StringExtensionMethods.GetStableHashCode("override_dungeon_exit_text"); public static readonly int ExitHover = StringExtensionMethods.GetStableHashCode("override_dungeon_exit_hover"); public static readonly int DoorKey = StringExtensionMethods.GetStableHashCode("override_door_key"); public static readonly int DoorNoClose = StringExtensionMethods.GetStableHashCode("override_door_no_close"); public static readonly int DoorConsume = StringExtensionMethods.GetStableHashCode("override_door_consume"); public static readonly int DoorOpenEffect = StringExtensionMethods.GetStableHashCode("override_open_effect"); public static readonly int DoorCloseEffect = StringExtensionMethods.GetStableHashCode("override_close_effect"); public static readonly int DoorLockedEffect = StringExtensionMethods.GetStableHashCode("override_locked_effect"); public static readonly int Weather = StringExtensionMethods.GetStableHashCode("override_weather"); public static readonly int Event = StringExtensionMethods.GetStableHashCode("override_event"); public static readonly int Effect = StringExtensionMethods.GetStableHashCode("override_effect"); public static readonly int Status = StringExtensionMethods.GetStableHashCode("override_status"); public static readonly int Component = StringExtensionMethods.GetStableHashCode("override_component"); public static readonly int Water = StringExtensionMethods.GetStableHashCode("override_water"); public static readonly int Fall = StringExtensionMethods.GetStableHashCode("override_fall"); public static readonly int Unlock = StringExtensionMethods.GetStableHashCode("override_unlock"); public static readonly int Growth = StringExtensionMethods.GetStableHashCode("override_growth"); public static readonly int Radius = StringExtensionMethods.GetStableHashCode("override_music_radius"); public static readonly int Condition = StringExtensionMethods.GetStableHashCode("override_music_condition"); public static readonly int Audio = StringExtensionMethods.GetStableHashCode("override_music_audio"); public static readonly int NoCollision = StringExtensionMethods.GetStableHashCode("override_collision"); public static readonly int Portal = StringExtensionMethods.GetStableHashCode("portal_wood"); public static readonly int NoInteract = StringExtensionMethods.GetStableHashCode("override_interact"); public static readonly int NoRender = StringExtensionMethods.GetStableHashCode("override_render"); public static readonly int Text = StringExtensionMethods.GetStableHashCode("override_text"); public static readonly int Topic = StringExtensionMethods.GetStableHashCode("override_topic"); public static readonly int Compendium = StringExtensionMethods.GetStableHashCode("override_compendium"); public static readonly int Discover = StringExtensionMethods.GetStableHashCode("override_discover"); public static readonly int Smoke = StringExtensionMethods.GetStableHashCode("override_smoke"); public static readonly int Restrict = StringExtensionMethods.GetStableHashCode("override_restrict"); public static readonly int Wear = StringExtensionMethods.GetStableHashCode("override_wear"); } public struct Discovery { public string name; public string pin; public PinType type; public bool showMap; } public class Helper { private static readonly HashSet<string> Truthies = new HashSet<string> { "1", "true", "yes", "on" }; private static readonly HashSet<string> Falsies = new HashSet<string> { "0", "false", "no", "off", "" }; public static ZDO? GetZDO(ZNetView? view) { if (!Object.op_Implicit((Object)(object)view) || !view.IsValid()) { return null; } return view.GetZDO(); } public static bool IsFinite(ZNetView view, float defaultValue) { ZDO zDO = GetZDO(view); if (zDO != null) { return IsFinite(zDO.GetFloat(ZDOVars.s_health, defaultValue)); } return false; } public static bool IsFinite(float value) { if (0f <= value) { return value < 1E+19f; } return false; } public static void AddMessage(Terminal context, string message, bool priority = true) { context.AddString(message); MessageHud instance = MessageHud.instance; if (!Object.op_Implicit((Object)(object)instance)) { return; } if (priority) { MsgData[] array = instance.m_msgQeue.ToArray(); instance.m_msgQeue.Clear(); Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, message, 0, (Sprite)null); } MsgData[] array2 = array; foreach (MsgData item in array2) { instance.m_msgQeue.Enqueue(item); } instance.m_msgQueueTimer = 10f; } else { Player localPlayer2 = Player.m_localPlayer; if (localPlayer2 != null) { ((Character)localPlayer2).Message((MessageType)1, message, 0, (Sprite)null); } } } public static ZNetView GetHover(string mode) { GameObject val = Player.m_localPlayer?.m_hovering; if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val == (Object)null) { throw new InvalidOperationException("Not hovering anything."); } Piece component = val.GetComponent<Piece>(); if (!Object.op_Implicit((Object)(object)component)) { throw new InvalidOperationException("Not hovering anything."); } ZNetView nview = component.m_nview; if (!Object.op_Implicit((Object)(object)nview)) { throw new InvalidOperationException("Not hovering anything."); } if (!CanEdit(nview, mode)) { throw new InvalidOperationException("Not allowed to edit."); } return nview; } public static void Command(string name, string description, ConsoleEvent action, ConsoleOptionsFetcher? fetcher = null) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand(name, description, Catch(action), false, false, false, false, false, fetcher, false, false, false); } public static void AddError(Terminal context, string message, bool priority = true) { AddMessage(context, "Error: " + message, priority); } public static ConsoleEvent Catch(ConsoleEvent action) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown ConsoleEvent action2 = action; return (ConsoleEvent)delegate(ConsoleEventArgs args) { try { if (!Object.op_Implicit((Object)(object)Player.m_localPlayer)) { throw new InvalidOperationException("Player not found."); } action2.Invoke(args); } catch (InvalidOperationException ex) { AddError(args.Context, ex.Message); } }; } public static float Float(string arg, float defaultValue = 0f) { if (!float.TryParse(arg, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return defaultValue; } return result; } public static int Int(string arg, int defaultValue = 0) { if (!int.TryParse(arg, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return defaultValue; } return result; } public static GameObject? GetPrefab(string hashStr) { if (int.TryParse(hashStr, out var result)) { return GetPrefab(result); } return GetPrefab(StringExtensionMethods.GetStableHashCode(hashStr)); } public static GameObject? GetPrefab(int hash) { if (hash == 0) { return null; } GameObject prefab = ZNetScene.instance.GetPrefab(hash); if (!Object.op_Implicit((Object)(object)prefab)) { return null; } return prefab; } public static Discovery ParseDiscovery(string data) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) string[] array = data.Split(new char[1] { ',' }); Discovery discovery = default(Discovery); discovery.name = array[0]; discovery.pin = ""; discovery.type = (PinType)8; Discovery result = discovery; if (array.Length > 1) { result.pin = array[1]; } if (array.Length > 2 && Enum.TryParse<PinType>(array[2], ignoreCase: true, out PinType result2)) { result.type = result2; } if (array.Length > 3) { result.showMap = Int(array[3]) > 0; } return result; } public static void Float(ZNetView? view, int hash, Action<float> action) { ZDO zDO = GetZDO(view); if (zDO != null) { float @float = zDO.GetFloat(hash, 0f); if (@float != 0f) { action(@float); } } } public static void Int(ZNetView? view, int hash, Action<int> action) { ZDO zDO = GetZDO(view); if (zDO != null) { int @int = zDO.GetInt(hash, 0); if (@int != 0) { action(@int); } } } public static void Bool(ZNetView? view, int hash, Action action) { ZDO zDO = GetZDO(view); if (zDO != null && zDO.GetBool(hash, false)) { action(); } } public static bool Bool(ZNetView? view, int hash) { ZDO zDO = GetZDO(view); if (zDO == null) { return false; } return zDO.GetBool(hash, false); } public static int Int(ZNetView? view, int hash) { ZDO zDO = GetZDO(view); if (zDO == null) { return 0; } return zDO.GetInt(hash, 0); } public static void String(ZNetView? view, int hash, Action<string> action) { ZDO zDO = GetZDO(view); if (zDO != null) { string @string = zDO.GetString(hash, ""); if (!(@string == "")) { action(@string); } } } public static bool Prefab(ZNetView? view, int hash, Action<GameObject> action) { ZDO zDO = GetZDO(view); if (zDO == null) { return false; } int num = zDO.GetInt(hash, 0); if (num == 0) { num = StringExtensionMethods.GetStableHashCode(zDO.GetString(hash, "")); } GameObject prefab = GetPrefab(num); if ((Object)(object)prefab == (Object)null) { return false; } action(prefab); return true; } public static ItemDrop? GetItem(int hash) { GameObject? prefab = GetPrefab(hash); if (prefab == null) { return null; } return prefab.GetComponent<ItemDrop>(); } public static void Item(ZNetView view, int hash, Action<ItemDrop> action) { ZDO zDO = GetZDO(view); if (zDO != null) { int num = zDO.GetInt(hash, 0); if (num == 0) { num = StringExtensionMethods.GetStableHashCode(zDO.GetString(hash, "")); } ItemDrop item = GetItem(num); if (!((Object)(object)item == (Object)null)) { action(item); } } } public static bool CanEdit(ZNetView? view, string mode) { ZDO zDO = GetZDO(view); if (zDO == null) { return false; } if (ZNet.instance.IsServer() || Plugin.ConfigSync.IsAdmin || mode == "All") { return true; } long playerID = Game.instance.GetPlayerProfile().GetPlayerID(); return zDO.GetLong(ZDOVars.s_creator, 0L) == playerID; } public static float TryFloat(string[] args, int index, float defaultValue = 1f) { if (args.Length <= index) { return defaultValue; } return Float(args[index], defaultValue); } public static Vector3 TryVectorXZY(string[] args, int index, Vector3 defaultValue) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) Vector3 zero = Vector3.zero; zero.x = TryFloat(args, index, defaultValue.x); zero.y = TryFloat(args, index + 2, defaultValue.y); zero.z = TryFloat(args, index + 1, defaultValue.z); return zero; } public static Vector3 TryScale(string[] args, int index) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return SanityCheck(TryVectorXZY(args, index, Vector3.zero)); } private static Vector3 SanityCheck(Vector3 scale) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (scale.x == 0f) { scale.x = 1f; } if (scale.y == 0f) { scale.y = scale.x; } if (scale.z == 0f) { scale.z = scale.x; } return scale; } public static bool IsTruthy(string value) { return Truthies.Contains(value); } public static bool IsFalsy(string value) { return Falsies.Contains(value); } public static T Get<T>(ZNetView view) where T : Component { T result = default(T); if (((Component)view).TryGetComponent<T>(ref result)) { return result; } return ((Component)view).gameObject.AddComponent<T>(); } public static EffectList ParseEffects(string data) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown IEnumerable<EffectData> source = from effect in data.Split(new char[1] { '|' }) select ParseEffect(effect) into effect where effect != null select effect; return new EffectList { m_effectPrefabs = source.ToArray() }; } public static EffectData? ParseEffect(string data) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown string[] array = data.Split(new char[1] { ',' }); EffectData val = new EffectData { m_prefab = GetPrefab(array[0]) }; if ((Object)(object)val.m_prefab == (Object)null) { return null; } if (array.Length > 1 && int.TryParse(array[1], out var result)) { val.m_randomRotation = (result & 1) > 0; val.m_inheritParentRotation = (result & 2) > 0; val.m_scale = (result & 4) > 0; val.m_inheritParentScale = (result & 8) > 0; val.m_attach = (result & 0x10) > 0; } if (array.Length > 2 && int.TryParse(array[2], out var result2)) { val.m_variant = result2; } if (array.Length > 3) { val.m_childTransform = array[3]; } return val; } } } namespace StructureTweaksPlugin { [HarmonyPatch(typeof(ZNetScene), "Awake")] public class AllScalable { private static readonly Dictionary<int, bool> Originals = new Dictionary<int, bool>(); public static readonly HashSet<int> HasSystems = new HashSet<int>(); public static void Update() { Update(ZNetScene.instance); } public static void UpdateParticles(ZNetScene scene) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Invalid comparison between Unknown and I4 //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) GameObject[] array = scene.m_namedPrefabs.Values.Where((GameObject v) => Object.op_Implicit((Object)(object)v.GetComponent<Fireplace>())).ToArray(); List<ParticleSystem> list = new List<ParticleSystem>(); GameObject[] array2 = array; for (int i = 0; i < array2.Length; i++) { array2[i].GetComponentsInChildren<ParticleSystem>(true, list); foreach (ParticleSystem item in list) { MainModule main = item.main; if ((int)((MainModule)(ref main)).scalingMode == 1) { MainModule main2 = item.main; ((MainModule)(ref main2)).scalingMode = (ParticleSystemScalingMode)0; } } } } public static void Update(int prefab, ZNetView obj) { bool value; if (Configuration.configAllScalable.Value) { obj.m_syncInitialScale = true; } else if (Originals.TryGetValue(prefab, out value)) { obj.m_syncInitialScale = value; } } public static void Update(ZNetScene scene) { Dictionary<int, bool> dictionary = new Dictionary<int, bool>(); foreach (KeyValuePair<int, GameObject> namedPrefab in scene.m_namedPrefabs) { ZNetView component = namedPrefab.Value.GetComponent<ZNetView>(); if (component != null) { Update(namedPrefab.Key, component); dictionary[namedPrefab.Key] = component.m_syncInitialScale; } } foreach (KeyValuePair<ZDO, ZNetView> instance in scene.m_instances) { int prefab = instance.Key.GetPrefab(); if (dictionary.ContainsKey(prefab)) { ZNetView component2 = ((Component)instance.Value).GetComponent<ZNetView>(); if (component2 != null) { component2.m_syncInitialScale = dictionary[prefab]; } } } } [HarmonyPriority(0)] private static void Postfix(ZNetScene __instance) { foreach (KeyValuePair<int, GameObject> namedPrefab in __instance.m_namedPrefabs) { if (!Originals.ContainsKey(namedPrefab.Key)) { ZNetView component = namedPrefab.Value.GetComponent<ZNetView>(); if (component != null) { Originals[namedPrefab.Key] = component.m_syncInitialScale; } } } Update(__instance); UpdateParticles(__instance); } } [HarmonyPatch(typeof(Container), "Awake")] public class ChestAwake { private static void Postfix(Container __instance) { Container __instance2 = __instance; if (Configuration.configRuneStone.Value) { Helper.String(__instance2.m_nview, Hash.Name, delegate(string value) { __instance2.m_name = value; }); } } } public class Configuration { public static ConfigEntry<bool> configAllScalable; public static ConfigEntry<bool> configNoTargeting; public static ConfigEntry<bool> configDisableStructureSystems; public static ConfigEntry<bool> configDisableFalling; public static ConfigEntry<bool> configGrowth; public static ConfigEntry<bool> configWear; public static ConfigEntry<bool> configCollision; public static ConfigEntry<bool> configRuneStone; public static ConfigEntry<bool> configMusic; public static ConfigEntry<string> configRuneStoneEditing; public static ConfigEntry<bool> configInteract; public static ConfigEntry<bool> configWardUnlock; public static ConfigEntry<bool> configToggleContainerUnlock; public static ConfigEntry<bool> configToggleDoorUnlock; public static ConfigEntry<bool> configRendering; public static ConfigEntry<bool> configFalling; public static ConfigEntry<bool> configEffects; public static ConfigEntry<bool> configTeleportable; public static ConfigEntry<bool> configSmokeBlock; public static ConfigEntry<string> configGrowthEditing; public static ConfigEntry<string> configWearEditing; public static ConfigEntry<bool> configIgnoreDamage; public static ConfigEntry<bool> configIgnoreRemove; public static ConfigEntry<bool> configIgnoreSupport; public static ConfigEntry<bool> configWaterHideParent; public static void Init(ConfigWrapper wrapper) { //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Expected O, but got Unknown //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Expected O, but got Unknown //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Expected O, but got Unknown string group = "1. General"; configAllScalable = wrapper.Bind(group, "All objects can be scaled", value: true, "Scaling works for every object."); configAllScalable.SettingChanged += delegate { AllScalable.Update(); }; configIgnoreDamage = wrapper.Bind(group, "Ignore damage when infinite health", value: true, "Damage is fully ignored for objects with infinite health."); configIgnoreRemove = wrapper.Bind(group, "Protect pieces with infinite health", value: true, "Pieces with infinite health can't be deconstructed with the hammer."); configIgnoreSupport = wrapper.Bind(group, "Max support with infinite health", value: true, "Pieces with infinite health have max structure support."); configDisableStructureSystems = wrapper.Bind(group, "Disable structure system", value: false, "Structure systems are disabled for all pieces."); configDisableFalling = wrapper.Bind(group, "Disable falling", value: false, "Falling is disabled for all static objects."); configNoTargeting = wrapper.Bind(group, "No enemy targeting when no creator", value: true, "Enemies won't target neutral structure."); configNoTargeting.SettingChanged += delegate { NoTargeting.Update(); }; configCollision = wrapper.Bind(group, "Override collision", value: true, "Collision can be overridden (requires reloading the area)."); configGrowth = wrapper.Bind(group, "Override growth", value: true, "Growth visual can be overridden."); configRuneStone = wrapper.Bind(group, "Override runestones", value: true, "Runestone properties can be overridden."); configMusic = wrapper.Bind(group, "Override music", value: true, "Music properties can be overridden."); configInteract = wrapper.Bind(group, "Override interact", value: true, "Interactability can be overridden."); configRendering = wrapper.Bind(group, "Override rendering", value: true, "Rendering can be overridden (requires reloading the area)."); configFalling = wrapper.Bind(group, "Override falling", value: true, "Falling can be overridden (requires reloading the area)."); configTeleportable = wrapper.Bind(group, "Override portal restrictions", value: true, "Teleporting with restricted items can be overridden."); configSmokeBlock = wrapper.Bind(group, "Override smoke restrictions", value: true, "Fireplaces going out can be overridden."); configWear = wrapper.Bind(group, "Override wear", value: true, "Wear visual can be overridden."); configEffects = wrapper.Bind(group, "Override effects", value: true, "New area effects can be added."); configWardUnlock = wrapper.Bind(group, "Override unlock", value: true, "Chests and doors can be force unlocked."); configWaterHideParent = wrapper.Bind(group, "Water hides the parent object", value: false, "If enabled, adding water hides and removes the collider of the parent object."); group = "2. Commands"; string[] array = new string[3] { "Admin only", "Owned", "All" }; configGrowthEditing = wrapper.Bind(group, "Command growth", "Owned", new ConfigDescription("Growth editing", (AcceptableValueBase)(object)new AcceptableValueList<string>(array), Array.Empty<object>())); configWearEditing = wrapper.Bind(group, "Command wear", "Owned", new ConfigDescription("Wear editing", (AcceptableValueBase)(object)new AcceptableValueList<string>(array), Array.Empty<object>())); configRuneStoneEditing = wrapper.Bind(group, "Allow editing runestones", "Admin only", new ConfigDescription("Runestone editing", (AcceptableValueBase)(object)new AcceptableValueList<string>(array), Array.Empty<object>())); configToggleContainerUnlock = wrapper.Bind(group, "Allow unlocking chests", value: true, "Players can unlock chests to ignore wards."); configToggleDoorUnlock = wrapper.Bind(group, "Allow unlocking doors", value: true, "Players can unlock doors to ignore wards."); } } [HarmonyPatch(typeof(TimedDestruction), "DestroyNow")] public class Destroy { public static void Handle(ZNetView view) { ZNetView view2 = view; Helper.Float(view2, Hash.Destroy, delegate(float value) { TimedDestruction obj = Helper.Get<TimedDestruction>(view2); obj.m_triggerOnAwake = true; obj.m_timeout = value; ((MonoBehaviour)obj).CancelInvoke("DestroyNow"); obj.Trigger(); }); } private static void Prefix(TimedDestruction __instance) { TimedDestruction __instance2 = __instance; Helper.String(__instance2.m_nview, Hash.DestroyEffect, delegate(string value) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) Helper.ParseEffects(value).Create(((Component)__instance2).transform.position, ((Component)__instance2).transform.rotation, ((Component)__instance2).transform, 1f, -1); }); } } [HarmonyPatch(typeof(LocationProxy), "SpawnLocation")] public class LocationAwake { private static void Postfix(LocationProxy __instance) { LocationProxy __instance2 = __instance; if (!Object.op_Implicit((Object)(object)__instance2.m_instance)) { return; } Helper.String(__instance2.m_nview, Hash.DungeonWeather, delegate(string value) { EnvZone componentInChildren = __instance2.m_instance.GetComponentInChildren<EnvZone>(); if (Object.op_Implicit((Object)(object)componentInChildren)) { componentInChildren.m_environment = value; } }); Teleport[] portals = Array.Empty<Teleport>(); Helper.String(__instance2.m_nview, Hash.EnterText, delegate(string value) { if (portals.Length == 0) { portals = __instance2.m_instance.GetComponentsInChildren<Teleport>(); } Teleport val4 = ((IEnumerable<Teleport>)portals).FirstOrDefault((Func<Teleport, bool>)((Teleport p) => ((Component)p).transform.position.y <= 3000f)); if (Object.op_Implicit((Object)(object)val4)) { val4.m_enterText = value; } }); Helper.String(__instance2.m_nview, Hash.EnterHover, delegate(string value) { if (portals.Length == 0) { portals = __instance2.m_instance.GetComponentsInChildren<Teleport>(); } Teleport val3 = ((IEnumerable<Teleport>)portals).FirstOrDefault((Func<Teleport, bool>)((Teleport p) => ((Component)p).transform.position.y <= 3000f)); if (Object.op_Implicit((Object)(object)val3)) { val3.m_hoverText = value; } }); Helper.String(__instance2.m_nview, Hash.ExitText, delegate(string value) { if (portals.Length == 0) { portals = __instance2.m_instance.GetComponentsInChildren<Teleport>(); } Teleport val2 = ((IEnumerable<Teleport>)portals).FirstOrDefault((Func<Teleport, bool>)((Teleport p) => ((Component)p).transform.position.y > 3000f)); if (Object.op_Implicit((Object)(object)val2)) { val2.m_enterText = value; } }); Helper.String(__instance2.m_nview, Hash.ExitHover, delegate(string value) { if (portals.Length == 0) { portals = __instance2.m_instance.GetComponentsInChildren<Teleport>(); } Teleport val = ((IEnumerable<Teleport>)portals).FirstOrDefault((Func<Teleport, bool>)((Teleport p) => ((Component)p).transform.position.y > 3000f)); if (Object.op_Implicit((Object)(object)val)) { val.m_hoverText = value; } }); } } public class EffectHelper { private static int Layer; public static GameObject CreateEffect(string name, float radius, Transform parent) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown if (Layer == 0) { Layer = LayerMask.NameToLayer("character_trigger"); } GameObject val = new GameObject(name) { layer = Layer }; SphereCollider obj = val.AddComponent<SphereCollider>(); ((Collider)obj).isTrigger = true; obj.radius = radius; val.transform.parent = parent; val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; return val; } } [HarmonyPatch(typeof(ZNetView), "Awake")] public class ZNetViewAwake { private static readonly int RoomCrypt = StringExtensionMethods.GetStableHashCode("sunkencrypt_new_Corridor1"); private static readonly string WaterCrypt = "WaterCube_sunkencrypt"; private static readonly int RoomCave = StringExtensionMethods.GetStableHashCode("cave_new_deeproom_bottom_lake"); private static readonly string WaterCave = "WaterCube_cave"; private static void HandleWeather(ZNetView view) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = Helper.GetZDO(view); if (zDO == null) { return; } string @string = zDO.GetString(Hash.Weather, ""); if (@string == "") { return; } string[] array = @string.Split(new char[1] { ',' }); if (array.Length < 2) { return; } float num = Helper.Float(array[0]); bool force = array.Length > 2 && !Helper.IsFalsy(array[2]); EnvZone val = default(EnvZone); if (((Component)view).TryGetComponent<EnvZone>(ref val)) { if (num != 0f) { ((Component)val).transform.localScale = Vector3.one * num; } val.m_force = force; val.m_environment = array[1]; } else if (num != 0f) { val = EffectHelper.CreateEffect("EnvArea", num, ((Component)view).transform).AddComponent<EnvZone>(); val.m_force = force; val.m_environment = array[1]; } } private static void HandleEvent(ZNetView view) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = Helper.GetZDO(view); if (zDO == null) { return; } string @string = zDO.GetString(Hash.Event, ""); if (@string == "") { return; } string[] array = @string.Split(new char[1] { ',' }); if (array.Length < 2) { return; } float num = Helper.Float(array[0]); EventZone val = default(EventZone); if (((Component)view).TryGetComponent<EventZone>(ref val)) { if (num != 0f) { ((Component)val).transform.localScale = Vector3.one * num; } val.m_event = array[1]; } else if (num != 0f) { EffectHelper.CreateEffect("EventArea", num, ((Component)view).transform).AddComponent<EventZone>().m_event = array[1]; } } private static Type ParseType(string[] values) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) Type val = (Type)0; for (int i = 0; i < values.Length; i++) { if (Enum.TryParse<Type>(values[i], ignoreCase: true, out Type result) && (int)result != 0) { val |= result; } } return val; } private static void HandleEffect(ZNetView view) { ZDO zDO = Helper.GetZDO(view); if (zDO == null) { return; } string @string = zDO.GetString(Hash.Status, ""); string string2 = zDO.GetString(Hash.Effect, ""); if (!(@string == "") || !(string2 == "")) { EffectArea[] componentsInChildren = ((Component)view).GetComponentsInChildren<EffectArea>(true); EffectArea[] array = componentsInChildren; foreach (EffectArea obj in array) { Transform parent = ((Component)obj).transform.parent; Object.Destroy((Object)(object)obj.m_collider); Object.Destroy((Object)(object)obj); AddEffect(parent, @string, string2); } if (componentsInChildren.Length == 0) { AddEffect(((Component)view).transform, @string, string2); } } } private static void AddEffect(Transform parent, string statusStr, string effectStr) { //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) GameObject obj = EffectHelper.CreateEffect("EffectArea", 0f, parent); SphereCollider component = obj.GetComponent<SphereCollider>(); CustomEffectArea customEffectArea = obj.AddComponent<CustomEffectArea>(); if (statusStr != "") { string[] array = statusStr.Split(new char[1] { ',' }); if (array.Length > 1) { component.radius = Math.Max(component.radius, Helper.Float(array[0])); ((EffectArea)customEffectArea).m_playerOnly = ((EffectArea)customEffectArea).m_playerOnly || (array.Length > 2 && Helper.IsTruthy(array[2])); ((EffectArea)customEffectArea).m_statusEffect = array[1]; ((EffectArea)customEffectArea).m_statusEffectHash = StringExtensionMethods.GetStableHashCode(((EffectArea)customEffectArea).m_statusEffect); ((EffectArea)customEffectArea).m_type = (Type)0; if (array.Length > 3) { customEffectArea.m_duration = Helper.Float(array[3]); } if (array.Length > 4) { customEffectArea.m_damage = Helper.Float(array[4]); } if (array.Length > 5) { customEffectArea.m_interval = Helper.Float(array[5]); } } } if (effectStr != "") { string[] array2 = effectStr.Split(new char[1] { ',' }); if (array2.Length > 1) { component.radius = Math.Max(component.radius, Helper.Float(array2[0])); List<string> list = new List<string>(); list.AddRange(array2.Skip(1)); ((EffectArea)customEffectArea).m_type = ParseType(list.ToArray()); ((EffectArea)customEffectArea).m_playerOnly = ((EffectArea)customEffectArea).m_playerOnly || (array2.Length > 2 && Helper.IsTruthy(array2[^1])); } } } private static void HandleComponent(ZNetView view) { if (Object.op_Implicit((Object)(object)((Component)view).gameObject.GetComponent<DungeonGenerator>())) { return; } ZDO zDO = Helper.GetZDO(view); if (zDO == null) { return; } string text = zDO.GetString(Hash.Component, "").ToLower(); if (text == "") { return; } string[] array = text.Split(new char[1] { ',' }); foreach (string obj in array) { if (obj == "runestone" && !Object.op_Implicit((Object)(object)((Component)view).gameObject.GetComponent<RuneStone>())) { ((Component)view).gameObject.AddComponent<RuneStone>(); } if (obj == "chest" && !Object.op_Implicit((Object)(object)((Component)view).gameObject.GetComponent<Container>())) { ((Component)view).gameObject.AddComponent<Container>(); } if (obj == "door" && !Object.op_Implicit((Object)(object)((Component)view).gameObject.GetComponent<Door>())) { ((Component)view).gameObject.AddComponent<Door>(); } if (obj == "destroy" && !Object.op_Implicit((Object)(object)((Component)view).gameObject.GetComponent<TimedDestruction>())) { Object.Destroy((Object)(object)((Component)view).gameObject.GetComponent<Growup>()); ((Component)view).gameObject.AddComponent<TimedDestruction>(); } if (obj == "portal" && !Object.op_Implicit((Object)(object)((Component)view).gameObject.GetComponent<TeleportWorld>())) { ((Component)view).gameObject.AddComponent<TeleportWorld>(); } } } private static void HandleWater(ZNetView view) { ZNetView view2 = view; Helper.String(view2, Hash.Water, delegate(string value) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) string[] array = value.Split(new char[1] { ',' }); Vector3 localScale = Helper.TryScale(array, 1); int key = 0; string text = ""; if (array[0] == "crypt") { key = RoomCrypt; text = WaterCrypt; localScale.x *= 2f; localScale.z *= 2f; } if (array[0] == "cave") { key = RoomCave; text = WaterCave; } if (DungeonDB.instance.m_roomByHash.TryGetValue(key, out var value2)) { if (!value2.m_prefab.IsLoaded) { value2.m_prefab.Load(); } Transform val = value2.m_prefab.Asset.transform.Find(text); if (Object.op_Implicit((Object)(object)val)) { if (Configuration.configWaterHideParent.Value) { Renderer[] componentsInChildren = ((Component)view2).GetComponentsInChildren<Renderer>(); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } Collider[] componentsInChildren2 = ((Component)view2).GetComponentsInChildren<Collider>(); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].isTrigger = true; } } GameObject obj = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)view2).transform); obj.transform.localPosition = Vector3.zero; obj.transform.localRotation = Quaternion.identity; obj.transform.localScale = localScale; } } }); } private static void Postfix(ZNetView __instance) { if (Configuration.configEffects.Value && Object.op_Implicit((Object)(object)__instance) && __instance.IsValid()) { HandleWeather(__instance); HandleEvent(__instance); HandleEffect(__instance); HandleComponent(__instance); HandleWater(__instance); Destroy.Handle(__instance); } } } public class CustomEffectArea : EffectArea { public float m_duration; public float m_damage; public float m_interval; private static readonly int HashBurning = StringExtensionMethods.GetStableHashCode("Burning"); public void OnTriggerExit(Collider collider) { ((EffectArea)this).OnTriggerExit(collider); if ((Object)(object)ZNet.instance == (Object)null || string.IsNullOrEmpty(base.m_statusEffect)) { return; } Character component = ((Component)collider).GetComponent<Character>(); if (Object.op_Implicit((Object)(object)component) && component.IsOwner() && (!base.m_playerOnly || component.IsPlayer())) { SEMan sEMan = component.GetSEMan(); StatusEffect statusEffect = sEMan.GetStatusEffect(base.m_statusEffectHash); if (Object.op_Implicit((Object)(object)statusEffect) && statusEffect.m_ttl == 0f) { sEMan.RemoveStatusEffect(base.m_statusEffectHash, false); } } } public void OnTriggerStay(Collider collider) { //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) Character component = ((Component)collider).GetComponent<Character>(); if (!Object.op_Implicit((Object)(object)component) || !component.IsOwner() || (base.m_playerOnly && !component.IsPlayer())) { return; } if (!string.IsNullOrEmpty(base.m_statusEffect)) { SEMan sEMan = component.GetSEMan(); StatusEffect val = sEMan.GetStatusEffect(base.m_statusEffectHash); if ((Object)(object)val == (Object)null) { val = sEMan.AddStatusEffect(base.m_statusEffectHash, true, 0, 0f); } else { val.ResetTime(); } if (m_damage == 0f && m_duration != 0f) { val.m_ttl = m_duration; } if (m_damage != 0f) { SE_Burning val2 = (SE_Burning)(object)((val is SE_Burning) ? val : null); if (val2 != null) { if (val2.m_fireDamageLeft > 0f || val.m_nameHash == HashBurning) { DamageModifier damageModifier = component.GetDamageModifier((DamageType)32); float num = m_damage * ModToMultiplier(damageModifier); if (val2.m_fireDamageLeft < num) { val.m_ttl = m_duration; if (m_interval != 0f) { val2.m_damageInterval = m_interval; } val2.m_fireDamageLeft = num; val2.m_fireDamagePerHit = num * val2.m_damageInterval / val.m_ttl; } } else { DamageModifier damageModifier2 = component.GetDamageModifier((DamageType)512); float num2 = m_damage * ModToMultiplier(damageModifier2); if (val2.m_spiritDamageLeft < num2) { val.m_ttl = m_duration; if (m_interval != 0f) { val2.m_damageInterval = m_interval; } val2.m_spiritDamageLeft = num2; val2.m_spiritDamagePerHit = num2 * val2.m_damageInterval / val.m_ttl; } } } SE_Poison val3 = (SE_Poison)(object)((val is SE_Poison) ? val : null); if (val3 != null) { DamageModifier damageModifier3 = component.GetDamageModifier((DamageType)256); float num3 = m_damage * ModToMultiplier(damageModifier3); if (val3.m_damageLeft < num3) { val.m_ttl = m_duration; if (m_interval != 0f) { val3.m_damageInterval = m_interval; } val3.m_damageLeft = num3; val3.m_damagePerHit = num3 * val3.m_damageInterval / val.m_ttl; } } } } if ((base.m_type & 1) != 0) { component.OnNearFire(((Component)this).transform.position); } } private static float ModToMultiplier(DamageModifier mod) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 if ((int)mod == 1) { return 0.5f; } if ((int)mod == 5) { return 0.25f; } if ((int)mod == 2) { return 1.5f; } if ((int)mod == 6) { return 2f; } if ((int)mod == 3) { return 0f; } if ((int)mod == 4) { return 0f; } return 1f; } } [HarmonyPatch(typeof(StaticPhysics), "Awake")] public class Fall { private static void Postfix(StaticPhysics __instance) { StaticPhysics __instance2 = __instance; if (Configuration.configFalling.Value) { Helper.Int(__instance2.m_nview, Hash.Fall, delegate(int value) { __instance2.m_fall = value == 1 || value == 2; __instance2.m_pushUp = value == 1 || value == 2; __instance2.m_checkSolids = value == 2; }); } } } [HarmonyPatch(typeof(StaticPhysics), "SUpdate")] public class GlobalFall { private static bool Prefix() { return !Configuration.configDisableFalling.Value; } } [HarmonyPatch] public class Unlock { private static bool CheckAccess(Component obj, float radius, bool flash, bool wardCheck) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ZNetView componentInParent = obj.GetComponentInParent<ZNetView>(); bool force = false; if (Configuration.configWardUnlock.Value) { Helper.Bool(componentInParent, Hash.Unlock, delegate { force = true; }); } if (!force) { return PrivateArea.CheckAccess(obj.transform.position, radius, flash, wardCheck); } return true; } private static IEnumerable<CodeInstruction> ReplacePrivateCheck(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(PrivateArea), "CheckAccess", (Type[])null, (Type[])null), (string)null) }).Set(OpCodes.Call, Transpilers.EmitDelegate<Func<Component, float, bool, bool, bool>>((Func<Component, float, bool, bool, bool>)CheckAccess).operand).MatchBack(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null) }) .Advance(1) .SetOpcodeAndAdvance(OpCodes.Nop) .SetOpcodeAndAdvance(OpCodes.Nop) .InstructionEnumeration(); } [HarmonyPatch(typeof(Door), "Interact")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> DoorInteract(IEnumerable<CodeInstruction> instructions) { return ReplacePrivateCheck(instructions); } [HarmonyPatch(typeof(Container), "Interact")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> ContainerInteract(IEnumerable<CodeInstruction> instructions) { return ReplacePrivateCheck(instructions); } [HarmonyPatch(typeof(Door), "GetHoverText")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> DoorGetHoverText(IEnumerable<CodeInstruction> instructions) { return ReplacePrivateCheck(instructions); } [HarmonyPatch(typeof(Container), "GetHoverText")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> ContainerGetHoverText(IEnumerable<CodeInstruction> instructions) { return ReplacePrivateCheck(instructions); } private static string OverrideHoverText(string result, ZNetView view, Vector3 point) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (!Configuration.configWardUnlock.Value || !Object.op_Implicit((Object)(object)view)) { return result; } if (!PrivateArea.CheckAccess(point, 0f, false, false)) { return result; } ZDO zDO = Helper.GetZDO(view); if (zDO == null) { return result; } if (zDO.GetBool(Hash.Unlock, false)) { return result + Localization.instance.Localize("\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] Remove unlock"); } return result + Localization.instance.Localize("\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] Force unlock"); } [HarmonyPatch(typeof(Door), "GetHoverText")] [HarmonyPostfix] private static string DoorGetHoverText(string result, Door __instance) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!Configuration.configToggleDoorUnlock.Value || !__instance.CanInteract()) { return result; } if (string.IsNullOrEmpty(result)) { return result; } return OverrideHoverText(result, __instance.m_nview, ((Component)__instance).transform.position); } [HarmonyPatch(typeof(Container), "GetHoverText")] [HarmonyPostfix] private static string ContainerGetHoverText(string result, Container __instance) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!Configuration.configToggleContainerUnlock.Value || !__instance.m_checkGuardStone) { return result; } if (string.IsNullOrEmpty(result)) { return result; } return OverrideHoverText(result, __instance.m_nview, ((Component)__instance).transform.position); } private static bool OverrideInteract(ZNetView view, Vector3 point, bool alt, bool hold, ref bool __result) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (!Configuration.configWardUnlock.Value || !alt) { return true; } if (hold) { return false; } if (!PrivateArea.CheckAccess(point, 0f, false, false)) { return true; } ZDO zDO = Helper.GetZDO(view); if (zDO == null) { return true; } if (!view.HasOwner()) { view.ClaimOwnership(); } view.InvokeRPC("ST_ForceUnlock", new object[1] { !zDO.GetBool(Hash.Unlock, false) }); __result = true; return false; } [HarmonyPatch(typeof(Door), "Interact")] [HarmonyPrefix] private static bool DoorInteract(Door __instance, bool alt, bool hold, ref bool __result) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!Configuration.configToggleDoorUnlock.Value || !__instance.CanInteract()) { return true; } return OverrideInteract(__instance.m_nview, ((Component)__instance).transform.position, alt, hold, ref __result); } [HarmonyPatch(typeof(Container), "Interact")] [HarmonyPrefix] private static bool ContainerInteract(Container __instance, bool alt, bool hold, ref bool __result) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!Configuration.configToggleContainerUnlock.Value || !__instance.m_checkGuardStone) { return true; } return OverrideInteract(__instance.m_nview, ((Component)__instance).transform.position, alt, hold, ref __result); } private static void ForceUnlock(ZNetView view, bool value) { ZDO zDO = Helper.GetZDO(view); if (zDO != null) { zDO.Set(Hash.Unlock, value); } } private static void Register(ZNetView view) { ZNetView view2 = view; if (Object.op_Implicit((Object)(object)view2)) { view2.Unregister("ST_ForceUnlock"); view2.Register<bool>("ST_ForceUnlock", (Action<long, bool>)delegate(long uid, bool value) { ForceUnlock(view2, value); }); } } [HarmonyPatch(typeof(Door), "Awake")] [HarmonyPostfix] private static void DoorAwake(Door __instance) { Door __instance2 = __instance; Register(__instance2.m_nview); Helper.Item(__instance2.m_nview, Hash.DoorKey, delegate(ItemDrop item) { __instance2.m_keyItem = item; }); Helper.Int(__instance2.m_nview, Hash.DoorNoClose, delegate(int value) { __instance2.m_canNotBeClosed = value > 0; }); Helper.String(__instance2.m_nview, Hash.DoorOpenEffect, delegate(string value) { __instance2.m_openEffects = Helper.ParseEffects(value); }); Helper.String(__instance2.m_nview, Hash.DoorCloseEffect, delegate(string value) { __instance2.m_closeEffects = Helper.ParseEffects(value); }); Helper.String(__instance2.m_nview, Hash.DoorLockedEffect, delegate(string value) { __instance2.m_lockedEffects = Helper.ParseEffects(value); }); } [HarmonyPatch(typeof(Container), "Awake")] [HarmonyPostfix] private static void ContainerAwake(Container __instance) { Register(__instance.m_nview); } [HarmonyPatch(typeof(Door), "Open")] [HarmonyPostfix] private static void DoorOpen(Door __instance) { Door __instance2 = __instance; Helper.Bool(__instance2.m_nview, Hash.DoorConsume, delegate { string text = __instance2.m_keyItem?.m_itemData?.m_shared.m_name; if (text != null) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Humanoid)localPlayer).GetInventory().RemoveItem(text, 1, -1, true); } } }); } } [HarmonyPatch(typeof(Plant))] public class Growth { public static int Number(string value) { return value switch { "small" => 4, "small_bad" => 1, "big" => 2, "big_bad" => 3, _ => 0, }; } [HarmonyPatch(typeof(Plant), "SUpdate")] [HarmonyPrefix] private static void StoreTime(Plant __instance, ref float __state) { __state = __instance.m_updateTime; } [HarmonyPatch(typeof(Plant), "SUpdate")] [HarmonyPostfix] private static void OverrideGrowth(Plant __instance, float __state) { Plant __instance2 = __instance; if (!Configuration.configGrowth.Value || !Object.op_Implicit((Object)(object)__instance2) || !__instance2.m_nview.IsValid() || __state == __instance2.m_updateTime) { return; } Helper.Int(__instance2.m_nview, Hash.Growth, delegate(int growth) { bool flag = growth == 4; bool flag2 = growth == 1; bool flag3 = growth == 2; bool flag4 = growth == 3; if (Object.op_Implicit((Object)(object)__instance2.m_healthyGrown)) { __instance2.m_healthy.SetActive(flag); __instance2.m_unhealthy.SetActive(flag2); __instance2.m_healthyGrown.SetActive(flag3); __instance2.m_unhealthyGrown.SetActive(flag4); } else { __instance2.m_healthy.SetActive(flag || flag3); __instance2.m_unhealthy.SetActive(flag2 || flag4); } }); } public static void SetGrowth(ZNetView view, string value) { if (!view.IsOwner()) { return; } ZDO zDO = Helper.GetZDO(view); if (zDO != null) { int num = Number(value); zDO.Set(Hash.Growth, num, false); long num2; if (num >= 0) { DateTime maxValue = DateTime.MaxValue; num2 = maxValue.Ticks / 2; } else { num2 = ZNet.instance.GetTime().Ticks; } long num3 = num2; zDO.Set(ZDOVars.s_plantTime, num3); } } private static void Register(ZNetView view) { ZNetView view2 = view; if (Object.op_Implicit((Object)(object)view2)) { view2.Unregister("ST_SetGrowth"); view2.Register<string>("ST_SetGrowth", (Action<long, string>)delegate(long uid, string value) { SetGrowth(view2, value); }); } } [HarmonyPatch(typeof(Plant), "Awake")] [HarmonyPostfix] private static void RegisterRPC(Plant __instance) { Register(__instance.m_nview); } } public class GrowthCommand { private void Execute(Terminal terminal, ZNetView view, string value) { if (view.IsOwner()) { Growth.SetGrowth(view, value); } else { view.InvokeRPC("ST_SetGrowth", new object[1] { value }); } Plant val = default(Plant); if (((Component)view).TryGetComponent<Plant>(ref val)) { val.m_updateTime = 0f; } if (Growth.Number(value) < 0) { Helper.AddMessage(terminal, "Removed growth override."); } else { Helper.AddMessage(terminal, "Growth set to " + value + "."); } } public GrowthCommand() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_006b: Expected O, but got Unknown List<string> values = new List<string>(4) { "big", "big_bad", "small", "small_bad" }; Helper.Command("growth", "[big/big_bad/small/small_bad] - Overrides the plant growth.", (ConsoleEvent)delegate(ConsoleEventArgs args) { ZNetView hover = Helper.GetHover(Configuration.configGrowthEditing.Value); Execute(args.Context, hover, (args.Length > 1) ? args[1] : ""); }, (ConsoleOptionsFetcher)(() => values)); } } [HarmonyPatch] public class IgnoreDamage { private static bool Check(ZNetView view, float defaultValue) { if (Configuration.configIgnoreDamage.Value) { return Helper.IsFinite(view, defaultValue); } return true; } [HarmonyPatch(typeof(Character), "IsDodgeInvincible")] [HarmonyPostfix] private static bool Character_IsDodgeInvincible(bool result, Character __instance) { return !Check(__instance.m_nview, 0f) || result; } [HarmonyPatch(typeof(MineRock5), "RPC_Damage")] [HarmonyPrefix] private static bool MineRock5_RPC_Damage(MineRock5 __instance) { return Check(__instance.m_nview, 0f); } [HarmonyPatch(typeof(TreeLog), "RPC_Damage")] [HarmonyPrefix] private static bool TreeLog_RPC_Damage(TreeLog __instance) { return Check(__instance.m_nview, 0f); } [HarmonyPatch(typeof(WearNTear), "RPC_Damage")] [HarmonyPrefix] private static bool WearNTear_RPC_Damage(WearNTear __instance) { return Check(__instance.m_nview, __instance.m_health); } [HarmonyPatch(typeof(TreeBase), "RPC_Damage")] [HarmonyPrefix] private static bool TreeBase_RPC_Damage(TreeBase __instance) { return Check(__instance.m_nview, __instance.m_health); } [HarmonyPatch(typeof(Destructible), "RPC_Damage")] [HarmonyPrefix] private static bool Destructible_RPC_Damage(Destructible __instance) { return Check(__instance.m_nview, __instance.m_health); } [HarmonyPatch(typeof(Character), "RPC_Damage")] [HarmonyPrefix] private static bool Character_RPC_Damage(Character __instance) { return Check(__instance.m_nview, __instance.GetMaxHealth()); } [HarmonyPatch(typeof(MineRock), "GetDestructibleType")] [HarmonyPostfix] private static DestructibleType MineRock_GetDestructibleType(DestructibleType type, MineRock __instance) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!Check(__instance.m_nview, __instance.m_health)) { return (DestructibleType)0; } return type; } [HarmonyPatch(typeof(MineRock5), "GetDestructibleType")] [HarmonyPostfix] private static DestructibleType MineRock5_GetDestructibleType(DestructibleType type, MineRock5 __instance) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!Check(__instance.m_nview, __instance.m_health)) { return (DestructibleType)0; } return type; } [HarmonyPatch(typeof(TreeLog), "GetDestructibleType")] [HarmonyPostfix] private static DestructibleType TreeLog_GetDestructibleType(DestructibleType type, TreeLog __instance) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!Check(__instance.m_nview, __instance.m_health)) { return (DestructibleType)0; } return type; } [HarmonyPatch(typeof(WearNTear), "GetDestructibleType")] [HarmonyPostfix] private static DestructibleType WearNTear_GetDestructibleType(DestructibleType type, WearNTear __instance) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!Check(__instance.m_nview, __instance.m_health)) { return (DestructibleType)0; } return type; } [HarmonyPatch(typeof(TreeBase), "GetDestructibleType")] [HarmonyPostfix] private static DestructibleType TreeBase_GetDestructibleType(DestructibleType type, TreeBase __instance) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!Check(__instance.m_nview, __instance.m_health)) { return (DestructibleType)0; } return type; } [HarmonyPatch(typeof(Destructible), "GetDestructibleType")] [HarmonyPostfix] private static DestructibleType Destructible_GetDestructibleType(DestructibleType type, Destructible __instance) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!Check(__instance.m_nview, __instance.m_health)) { return (DestructibleType)0; } return type; } [HarmonyPatch(typeof(Character), "GetDestructibleType")] [HarmonyPostfix] private static DestructibleType Character_GetDestructibleType(DestructibleType type, Character __instance) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!Check(__instance.m_nview, __instance.GetMaxHealth())) { return (DestructibleType)0; } return type; } } [HarmonyPatch(typeof(WearNTear))] public class IgnoreSupport { public const float INFITE = 1E+19f; [HarmonyPatch("UpdateWear")] [HarmonyPrefix] private static bool UpdateWear() { return !Configuration.configDisableStructureSystems.Value; } [HarmonyPatch("UpdateSupport")] [HarmonyPrefix] private static bool UpdateSupport(WearNTear __instance) { if (!Configuration.configIgnoreSupport.Value) { return true; } if (!Object.op_Implicit((Object)(object)__instance) || !__instance.m_nview.IsValid()) { return true; } ZNetView nview = __instance.m_nview; if (Helper.IsFinite(nview, __instance.m_health)) { return true; } if (__instance.m_support == 1E+19f) { return false; } ZDO zDO = Helper.GetZDO(nview); if (zDO == null) { return true; } __instance.m_support = 1E+19f; zDO.Set(ZDOVars.s_support, 1E+19f); return false; } } [HarmonyPatch(typeof(MusicLocation), "Awake")] public class MusicLocationAwake { private static Dictionary<string, AudioClip> Clips = new Dictionary<string, AudioClip>(); private static void Postfix(MusicLocation __instance) { if (!Configuration.configMusic.Value) { return; } MusicLocation obj = __instance; ZNetView nview = obj.m_nview; Helper.Float(nview, Hash.Radius, delegate(float value) { obj.m_radius = value; }); Helper.Int(nview, Hash.Condition, delegate(int value) { obj.m_oneTime = (value & 1) > 0; obj.m_notIfEnemies = (value & 2) > 0; obj.m_forceFade = (value & 3) > 0; }); Helper.String(nview, Hash.Audio, delegate(string value) { if (Clips.Count == 0) { Clips = Resources.FindObjectsOfTypeAll<AudioClip>().ToDictionary((AudioClip x) => ((Object)x).name, (AudioClip x) => x); } if (Clips.TryGetValue(value, out AudioClip value2)) { obj.m_audioSource.clip = value2; } else { Debug.LogWarning((object)("Audio clip " + value + " not found")); } }); } } [HarmonyPatch(typeof(ZNetScene), "CreateObject")] public class NoCollision { private static void Postfix(ZDO zdo, GameObject __result) { if (!Object.op_Implicit((Object)(object)__result) || !Configuration.configCollision.Value || zdo == null || !zdo.GetBool(Hash.NoCollision, false)) { return; } Collider[] componentsInChildren = __result.GetComponentsInChildren<Collider>(); if (zdo.GetPrefab() == Hash.Portal) { Collider[] array = componentsInChildren; for (int i = 0; i < array.Length; i++) { array[i].enabled = false; } } else { Collider[] array = componentsInChildren; for (int i = 0; i < array.Length; i++) { array[i].isTrigger = true; } } } } [HarmonyPatch(typeof(Player), "UpdateHover")] public class NoHover { private static void Postfix(Player __instance) { Player __instance2 = __instance; if (!Configuration.configInteract.Value) { return; } GameObject hovering = __instance2.m_hovering; if (Object.op_Implicit((Object)(object)hovering)) { Helper.Bool(((Component)hovering.transform.root).GetComponent<ZNetView>(), Hash.NoInteract, delegate { __instance2.m_hovering = null; }); } } } [HarmonyPatch(typeof(Player), "CheckCanRemovePiece")] public class NoRemove { private static bool Postfix(bool result, Piece piece) { if (!result) { return result; } if (!Configuration.configIgnoreRemove.Value) { return result; } if (!Object.op_Implicit((Object)(object)piece) || !Object.op_Implicit((Object)(object)piece.m_nview) || !piece.m_nview.IsValid()) { return true; } if (Game.instance.GetPlayerProfile().GetPlayerID() == piece.GetCreator()) { return true; } WearNTear val = default(WearNTear); return Helper.IsFinite(piece.m_nview, ((Component)piece).TryGetComponent<WearNTear>(ref val) ? val.m_health : 0f); } } [HarmonyPatch(typeof(ZNetScene), "CreateObject")] public class NoRender { private static void Postfix(ZDO zdo, GameObject __result) { if (Object.op_Implicit((Object)(object)__result) && Configuration.configRendering.Value && zdo != null && zdo.GetBool(Hash.NoRender, false)) { Renderer[] componentsInChildren = __result.GetComponentsInChildren<Renderer>(); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } } } } [HarmonyPatch(typeof(ZNetScene), "Awake")] public class NoTargeting { private static readonly Dictionary<int, bool> Originals = new Dictionary<int, bool>(); public static void Update() { Update(ZNetScene.instance); } public static void Update(int prefab, Piece obj) { bool value; if (Configuration.configNoTargeting.Value) { obj.m_targetNonPlayerBuilt = false; } else if (Originals.TryGetValue(prefab, out value)) { obj.m_targetNonPlayerBuilt = value; } } public static void Update(ZNetScene scene) { Dictionary<int, bool> dictionary = new Dictionary<int, bool>(); foreach (KeyValuePair<int, GameObject> namedPrefab in scene.m_namedPrefabs) { Piece component = namedPrefab.Value.GetComponent<Piece>(); if (component != null) { Update(namedPrefab.Key, component); dictionary[namedPrefab.Key] = component.m_targetNonPlayerBuilt; } } foreach (KeyValuePair<ZDO, ZNetView> instance in scene.m_instances) { int prefab = instance.Key.GetPrefab(); if (dictionary.ContainsKey(prefab)) { Piece component2 = ((Component)instance.Value).GetComponent<Piece>(); if (component2 != null) { component2.m_targetNonPlayerBuilt = dictionary[prefab]; } } } } [HarmonyPriority(0)] private static void Postfix(ZNetScene __instance) { foreach (KeyValuePair<int, GameObject> namedPrefab in __instance.m_namedPrefabs) { if (!Originals.ContainsKey(namedPrefab.Key)) { Piece component = namedPrefab.Value.GetComponent<Piece>(); if (component != null) { Originals[namedPrefab.Key] = component.m_targetNonPlayerBuilt; } } } Update(__instance); } } public class ZdoTextReceiver : MonoBehaviour, TextReceiver { private int Index; private readonly int[] Hashes = new int[4] { Hash.Name, Hash.Text, Hash.Topic, Hash.Compendium }; private readonly string[] Topics = new string[4] { "Enter name", "$piece_sign_input", "Enter topic", "Enter compendium topic" }; private ZNetView? m_nview; private bool Queued; public void Awake() { m_nview = ((Component)this).GetComponentInParent<ZNetView>(); } public void LateUpdate() { if (Queued) { TextInput.instance.RequestText((TextReceiver)(object)this, Topics[Index], 1000); } Queued = false; } public void Show() { Index = 0; Queued = true; } public string GetText() { string text = ""; Helper.String(m_nview, Hashes[Index], delegate(string value) { text = value; }); return text; } public void SetText(string text) { ZDO zDO = Helper.GetZDO(m_nview); if (zDO != null) { zDO.Set(Hashes[Index], text); Index++; if (Index == Hashes.Length) { Index = 0; } else { Queued = true; } } } } [HarmonyPatch(typeof(RuneStone))] public class RuneStoneText { private static readonly int Name = StringExtensionMethods.GetStableHashCode("override_name"); private static readonly int Text = StringExtensionMethods.GetStableHashCode("override_text"); private static readonly int Topic = StringExtensionMethods.GetStableHashCode("override_topic"); private static readonly int Compendium = StringExtensionMethods.GetStableHashCode("override_compendium"); private static readonly int Discover = StringExtensionMethods.GetStableHashCode("override_discover"); [HarmonyPatch(typeof(RuneStone), "GetHoverText")] [HarmonyPrefix] private static void GetHoverText(RuneStone __instance) { RuneStone __instance2 = __instance; if (Configuration.configRuneStone.Value) { Helper.String(((Component)__instance2).GetComponentInParent<ZNetView>(), Name, delegate(string value) { __instance2.m_name = value; }); } } [HarmonyPatch(typeof(RuneStone), "GetHoverText")] [HarmonyPostfix] private static string GetHoverTextUseKey(string result, RuneStone __instance) { if (!Configuration.configRuneStone.Value) { return result; } if (!Helper.CanEdit(((Component)__instance).GetComponentInParent<ZNetView>(), Configuration.configRuneStoneEditing.Value)) { return result; } return result + Localization.instance.Localize("\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] Edit"); } [HarmonyPatch(typeof(RuneStone), "GetHoverName")] [HarmonyPrefix] private static void GetHoverName(RuneStone __instance) { RuneStone __instance2 = __instance; if (Configuration.configRuneStone.Value) { Helper.String(((Component)__instance2).GetComponentInParent<ZNetView>(), Name, delegate(string value) { __instance2.m_name = value; }); } } [HarmonyPatch(typeof(RuneStone), "Interact")] [HarmonyPrefix] private static bool Interact(RuneStone __instance, bool alt, ref bool __result) { RuneStone __instance2 = __instance; if (!Configuration.configRuneStone.Value) { return true; } ZNetView componentInParent = ((Component)__instance2).GetComponentInParent<ZNetView>(); bool flag = Helper.CanEdit(componentInParent, Configuration.configRuneStoneEditing.Value); if (alt && flag) { __result = true; ZdoTextReceiver zdoTextReceiver = ((Component)__instance2).GetComponent<ZdoTextReceiver>(); if (!Object.op_Implicit((Object)(object)zdoTextReceiver)) { zdoTextReceiver = ((Component)__instance2).gameObject.AddComponent<ZdoTextReceiver>(); } zdoTextReceiver.Show(); return false; } RuneStone val = __instance2; if (val.m_randomTexts == null) { val.m_randomTexts = new List<RandomRuneText>(); } Helper.String(componentInParent, Text, delegate(string value) { __instance2.m_randomTexts = new List<RandomRuneText>(); __instance2.m_text = value; }); Helper.String(componentInParent, Topic, delegate(string value) { __instance2.m_randomTexts = new List<RandomRuneText>(); __instance2.m_topic = value; }); Helper.String(componentInParent, Compendium, delegate(string value) { __instance2.m_randomTexts = new List<RandomRuneText>(); __instance2.m_label = value; }); Helper.String(componentInParent, Discover, delegate(string value) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) Discovery discovery = Helper.ParseDiscovery(value); __instance2.m_locationName = discovery.name; __instance2.m_pinName = discovery.pin; __instance2.m_pinType = discovery.type; __instance2.m_showMap = discovery.showMap; }); return true; } } [HarmonyPatch(typeof(Player), "AddKnownText")] public class AddKnownText { private static bool Prefix(Player __instance, string label, string text) { string[] array = label.Split(new char[1] { '|' }); if (array.Length > 1) { string[] array2 = array; foreach (string text2 in array2) { __instance.AddKnownText(text2, text); } return false; } if (label.StartsWith("-", StringComparison.Ordinal)) { __instance.m_knownTexts.Remove(label.Substring(1)); return false; } return true; } } [HarmonyPatch(typeof(SmokeSpawner), "IsBlocked")] public class SmokeBlock { private static bool Postfix(bool result, SmokeSpawner __instance) { if (!Configuration.configSmokeBlock.Value) { return result; } if (!result) { return result; } return Helper.Int(((Component)__instance).GetComponentInParent<ZNetView>(), Hash.Smoke) == 0; } } [HarmonyPatch(typeof(SmokeSpawner), "Spawn")] public class SmokeSpawn { private static bool Prefix(SmokeSpawner __instance) { if (!Configuration.configSmokeBlock.Value) { return true; } return Helper.Int(((Component)__instance).GetComponentInParent<ZNetView>(), Hash.Smoke) != 1; } } [HarmonyPatch] [BepInPlugin("structure_tweaks", "Structure Tweaks", "1.36")] public class Plugin : BaseUnityPlugin { private const string GUID = "structure_tweaks"; private const string NAME = "Structure Tweaks"; private const string VERSION = "1.36"; public static ConfigSync ConfigSync = new ConfigSync("structure_tweaks") { DisplayName = "Structure Tweaks", CurrentVersion = "1.36", IsLocked = true, ModRequired = true }; public void Awake() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) Configuration.Init(new ConfigWrapper("structure_config", ((BaseUnityPlugin)this).Config, ConfigSync)); new Harmony("structure_tweaks").PatchAll(); } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] public class SetCommands { private static void Postfix() { new GrowthCommand(); new WearCommand(); } } [HarmonyPatch(typeof(TeleportWorld), "Teleport")] public class Teleportable { private static void Prefix(TeleportWorld __instance) { if (Configuration.configTeleportable.Value) { Helper.Bool(__instance.m_nview, Hash.Restrict, delegate { ForceTeleportable.Force = true; }); } } private static void Postfix() { ForceTeleportable.Force = false; } } [HarmonyPatch(typeof(Humanoid), "IsTeleportable")] public class ForceTeleportable { public static bool Force; private static bool Postfix(bool result) { if (!result) { return Force; } return true; } } [HarmonyPatch(typeof(Vegvisir))] public class VegvisirText { private static void Setup(Vegvisir obj) { Vegvisir obj2 = obj; if (!Configuration.configRuneStone.Value) { return; } ZNetView componentInParent = ((Component)obj2).GetComponentInParent<ZNetView>(); Helper.String(componentInParent, Hash.Name, delegate(string value) { obj2.m_name = value; }); Helper.String(componentInParent, Hash.Discover, delegate(string value) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown Discovery discovery = Helper.ParseDiscovery(value); if (obj2.m_locations.Count == 0) { obj2.m_locations.Add(new VegvisrLocation()); } VegvisrLocation obj3 = obj2.m_locations[0]; obj3.m_locationName = discovery.name; obj3.m_pinName = discovery.pin; obj3.m_pinType = discovery.type; }); } [HarmonyPatch(typeof(Vegvisir), "GetHoverText")] [HarmonyPrefix] private static void GetHoverText(Vegvisir __instance) { Setup(__instance); } [HarmonyPatch(typeof(Vegvisir), "GetHoverName")] [HarmonyPrefix] private static void GetHoverName(Vegvisir __instance) { Setup(__instance); } [HarmonyPatch(typeof(Vegvisir), "Interact")] [HarmonyPrefix] private static void Interact(Vegvisir __instance) { Setup(__instance); } } [HarmonyPatch(typeof(WearNTear))] public class Wear { public static int Number(string value) { return value switch { "broken" => 3, "damaged" => 1, "healthy" => 2, _ => 0, }; } public static void SetWear(ZNetView view, string value) { if (view.IsOwner()) { ZDO zDO = Helper.GetZDO(view); if (zDO != null) { int num = Number(value); zDO.Set(Hash.Wear, num, false); } } } private static void Register(ZNetView view) { ZNetView view2 = view; if (Object.op_Implicit((Object)(object)view2)) { view2.Unregister("TC_SetWear"); view2.Register<string>("TC_SetWear", (Action<long, string>)delegate(long uid, string value) { SetWear(view2, value); }); } } [HarmonyPatch(typeof(WearNTear), "Awake")] [HarmonyPostfix] private static void RegisterRPC(WearNTear __instance) { Register(__instance.m_nview); } private static float Convert(int value, float defaultValue) { return value switch { 3 => 0.1f, 1 => 0.5f, 2 => 1f, _ => defaultValue, }; } [HarmonyPatch("SetHealthVisual")] [HarmonyPrefix] private static void OverrideWear(WearNTear __instance, ref float health) { if (Configuration.configWear.Value) { ZDO zDO = Helper.GetZDO(__instance.m_nview); if (zDO != null) { int @int = zDO.GetInt(Hash.Wear, 0); health = Convert(@int, health); } } } } public class WearCommand { private void Execute(Terminal terminal, ZNetView view, string value) { Wear.SetWear(view, value); if (view.IsOwner()) { Wear.SetWear(view, value); } else { view.InvokeRPC("TC_SetWear", new object[1] { value }); } if (Wear.Number(value) < 0) { Helper.AddMessage(terminal, "Removed wear override."); } else { Helper.AddMessage(terminal, "Wear set to " + value + "."); } } public WearCommand() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0060: Expected O, but got Unknown List<string> values = new List<string>(3) { "broken", "damaged", "healthy" }; Helper.Command("wear", "[broken/damaged/healthy] - Overrides the wear health.", (ConsoleEvent)delegate(ConsoleEventArgs args) { ZNetView hover = Helper.GetHover(Configuration.configGrowthEditing.Value); Execute(args.Context, hover, (args.Length > 1) ? args[1] : ""); }, (ConsoleOptionsFetcher)(() => values)); } } } namespace ServerSync { [PublicAPI] public abstract class OwnConfigEntryBase { public object? LocalBaseValue; public bool SynchronizedConfig = true; public abstract ConfigEntryBase BaseConfig { get; } } [PublicAPI] public class SyncedConfigEntry<T> : OwnConfigEntryBase { public readonly ConfigEntry<T> SourceConfig; public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig; public T Value { get { return SourceConfig.Value; } set { SourceConfig.Value = value; } } public SyncedConfigEntry(ConfigEntry<T> sourceConfig) { SourceConfig = sourceConfig; base..ctor(); } public void AssignLocalValue(T value) { if (LocalBaseValue == null) { Value = value; } else { LocalBaseValue = value; } } } internal abstract class CustomSyncedValueBase { public object? LocalBaseValue; public readonly string Identifier; public readonly Type Type; private object? boxedValue; protected bool localIsOwner; public readonly int Priority; public object? BoxedValue { get { return boxedValue; } set { boxedValue = value; this.ValueChanged?.Invoke(); } } public event Action? ValueChanged; protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority) { Priority = priority; Identifier = identifier; Type = type; configSync.AddCustomValue(this); localIsOwner = configSync.IsSourceOfTruth; configSync.SourceOfTruthChanged += delegate(bool truth) { localIsOwner = truth; }; } } [PublicAPI] internal sealed class CustomSyncedValue<T> : CustomSyncedValueBase { public T Value { get { return (T)base.BoxedValue; } set { base.BoxedValue = value; } } public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0) : base(configSync, identifier, typeof(T), priority) { Value = value; } public void AssignLocalValue(T value) { if (localIsOwner) { Value = value; } else { LocalBaseValue = value; } } } internal class ConfigurationManagerAttributes { [UsedImplicitly] public bool? ReadOnly = false; } [PublicAPI] public class ConfigSync { [HarmonyPatch(typeof(ZRpc), "HandlePackage")] private static class SnatchCurrentlyHandlingRPC { public static ZRpc? currentRpc; [HarmonyPrefix] private static void Prefix(ZRpc __instance) { currentRpc = __instance; } } [HarmonyPatch(typeof(ZNet), "Awake")] internal static class RegisterRPCPatch { [HarmonyPostfix] private static void Postfix(ZNet __instance) { isServer = __instance.IsServer(); foreach (ConfigSync configSync2 in configSyncs) { ZRoutedRpc.instance.Register<ZPackage>(configSync2.Name + " ConfigSync", (Action<long, ZPackage>)configSync2.RPC_FromOtherClientConfigSync); if (isServer) { configSync2.InitialSyncDone = true; Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections")); } } if (isServer) { ((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges()); } static void SendAdmin(List<ZNetPeer> peers, bool isAdmin) { ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1] { new PackageEntry { section = "Internal", key = "lockexempt", type = typeof(bool), value = isAdmin } }); ConfigSync configSync = configSyncs.First(); if (configSync != null) { ((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package)); } } static IEnumerator WatchAdminListChanges() { MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); List<string> CurrentList = new List<string>(adminList.GetList()); while (true) { yield return (object)new WaitForSeconds(30f); if (!adminList.GetList().SequenceEqual(CurrentList)) { CurrentList = new List<string>(adminList.GetList()); List<ZNetPeer> adminPeer = ZNet.instance.GetPeers().Where(delegate(ZNetPeer p) { string hostName = p.m_rpc.GetSocket().GetHostName(); return ((object)listContainsId == null) ? adminList.Contains(hostName) : ((bool)listContainsId.Invoke(ZNet.instance, new object[2] { adminList, hostName })); }).ToList(); List<ZNetPeer> nonAdminPeer = ZNet.instance.GetPeers().Except(adminPeer).ToList(); SendAdmin(nonAdminPeer, isAdmin: false); SendAdmin(adminPeer, isAdmin: true); } } } } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] private static class RegisterClientRPCPatch { [HarmonyPostfix] private static void Postfix(ZNet __instance, ZNetPeer peer) { if (__instance.IsServer()) { return; } foreach (ConfigSync configSync in configSyncs) { peer.m_rpc.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<ZRpc, ZPackage>)configSync.RPC_FromServerConfigSync); } } } private class ParsedConfigs { public readonly Dictionary<OwnConfigEntryBase, object?> configValues = new Dictionary<OwnConfigEntryBase, object>(); public readonly Dictionary<CustomSyncedValueBase, object?> customValues = new Dictionary<CustomSyncedValueBase, object>(); } [HarmonyPatch(typeof(ZNet), "Shutdown")] private class ResetConfigsOnShutdown { [HarmonyPostfix] private static void Postfix() { ProcessingServerUpdate = true; foreach (ConfigSync configSync in configSyncs) { configSync.resetConfigsFromServer(); configSync.IsSourceOfTruth = true; configSync.InitialSyncDone = false; } ProcessingServerUpdate = false; } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] private class SendConfigsAfterLogin { private class BufferingSocket : ZPlayFabSocket, ISocket { public volatile bool finished = false; public volatile int versionMatchQueued = -1; public readonly List<ZPackage> Package = new List<ZPackage>(); public readonly ISocket Original; public BufferingSocket(ISocket original) { Original = original; ((ZPlayFabSocket)this)..ctor(); } public bool IsConnected() { return Original.IsConnected(); } public ZPackage Recv() { return Original.Recv(); } public int GetSendQueueSize() { return Original.GetSendQueueSize(); } public int GetCurrentSendRate() { return Original.GetCurrentSendRate(); } public bool IsHost() { return Original.IsHost(); } public void Dispose() { Original.Dispose(); } public bool GotNewData() { return Original.GotNewData(); } public void Close() { Original.Close(); } public string GetEndPointString() { return Original.GetEndPointString(); } public void GetAndResetStats(out int totalSent, out int totalRecv) { Original.GetAndResetStats(ref totalSent, ref totalRecv); } public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec) { Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec); } public ISocket Accept() { return Original.Accept(); } public int GetHostPort() { return Original.GetHostPort(); } public bool Flush() { return Original.Flush(); } public string GetHostName() { return Original.GetHostName(); } public void VersionMatch() { if (finished) { Original.VersionMatch(); } else { versionMatchQueued = Package.Count; } } public void Send(ZPackage pkg) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown int pos = pkg.GetPos(); pkg.SetPos(0); int num = pkg.ReadInt(); if ((num == StringExtensionMethods.GetStableHashCode("PeerInfo") || num == StringExtensionMethods.GetStableHashCode("RoutedRPC") || num == StringExtensionMethods.GetStableHashCode("ZDOData")) && !finished) { ZPackage val = new ZPackage(pkg.GetArray()); val.SetPos(pos); Package.Add(val); } else { pkg.SetPos(pos); Original.Send(pkg); } } } [HarmonyPriority(800)] [HarmonyPrefix] private static void Prefix(ref Dictionary<Assembly, BufferingSocket>? __state, ZNet __instance, ZRpc rpc) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Invalid comparison between Unknown and I4 if (!__instance.IsServer()) { return; } BufferingSocket bufferingSocket = new BufferingSocket(rpc.GetSocket()); AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, bufferingSocket); object? obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc }); ZNetPeer val = (ZNetPeer)((obj is ZNetPeer) ? obj : null); if (val != null && (int)ZNet.m_onlineBackend > 0) { FieldInfo fieldInfo = AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket"); object? value = fieldInfo.GetValue(val); ZPlayFabSocket val2 = (ZPlayFabSocket)((value is ZPlayFabSocket) ? value : null); if (val2 != null) { typeof(ZPlayFabSocket).GetField("m_remotePlayerId").SetValue(bufferingSocket, val2.m_remotePlayerId); } fieldInfo.SetValue(val, bufferingSocket); } if (__state == null) { __state = new Dictionary<Assembly, BufferingSocket>(); } __state[Assembly.GetExecutingAssembly()] = bufferingSocket; } [HarmonyPostfix] private static void Postfix(Dictionary<Assembly, BufferingSocket> __state, ZNet __instance, ZRpc rpc) { ZRpc rpc2 = rpc; ZNet __instance2 = __instance; Dictionary<Assembly, BufferingSocket> __state2 = __state; ZNetPeer peer; if (__instance2.IsServer()) { object obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 }); peer = (ZNetPeer)((obj is ZNetPeer) ? obj : null); if (peer == null) { SendBufferedData(); } else { ((MonoBehaviour)__instance2).StartCoroutine(sendAsync()); } } void SendBufferedData() { if (rpc2.GetSocket() is BufferingSocket bufferingSocket) { AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc2, bufferingSocket.Original); object? obj2 = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 }); ZNetPeer val = (ZNetPeer)((obj2 is ZNetPeer) ? obj2 : null); if (val != null) { AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, bufferingSocket.Original); } } BufferingSocket bufferingSocket2 = __state2[Assembly.GetExecutingAssembly()]; bufferingSocket2.finished = true; for (int i = 0; i < bufferingSocket2.Package.Count; i++) { if (i == bufferingSocket2.versionMatchQueued) { bufferingSocket2.Original.VersionMatch(); } bufferingSocket2.Original.Send(bufferingSocket2.Package[i]); } if (bufferingSocket2.Package.Count == bufferingSocket2.versionMatchQueued) { bufferingSocket2.Original.VersionMatch(); } } IEnumerator sendAsync() { foreach (ConfigSync configSync in configSyncs) { List<PackageEntry> entries = new List<PackageEntry>(); if (configSync.CurrentVersion != null) { entries.Add(new PackageEntry { section = "Internal", key = "serverversion", type = typeof(string), value = configSync.CurrentVersion }); } MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); entries.Add(new PackageEntry { section = "Internal", key = "lockexempt", type = typeof(bool), value = (((object)listContainsId == null) ? ((object)adminList.Contains(rpc2.GetSocket().GetHostName())) : listContainsId.Invoke(ZNet.instance, new object[2] { adminList, rpc2.GetSocket().GetHostName() })) }); ZPackage package = ConfigsToPackage(configSync.allConfigs.Select((OwnConfigEntryBase c) => c.BaseConfig), configSync.allCustomValues, entries, partial: false); yield return ((MonoBehaviour)__instance2).StartCoroutine(