Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ValheimUnified v0.11.1
plugins/ValheimUnified.dll
Decompiled 2 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.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GUIFramework; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Splatform; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.PostProcessing; using UnityEngine.UI; using ValheimUnified; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: InternalsVisibleTo("ValheimUnifiedPublishRun")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Chistix { public static class ModMenuApi { public static bool IsSettingsOpen => SettingsUI.IsOpen; public static string GetMenuInfo() { return JsonConvert.SerializeObject((object)new { Api = 1, Publisher = "Chistix", Id = "chistix.valheimunified", Name = "ValheimUnified", Version = "0.11.1", ApplyPolicies = new string[3] { "Live", "WorldRestart", "GameRestart" } }); } public static void OpenSettings(Action onClosed) { SettingsUI.Open(onClosed); } public static void CloseSettings() { SettingsUI.Reset(); } public static string GetApplyPolicy(string settingId) { return SettingsUI.Policy(settingId); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public string AssemblyName { get; } public IgnoresAccessChecksToAttribute(string assemblyName) { AssemblyName = assemblyName; } } } namespace ValheimUnified { public static class AdminBridge { public const int ApiVersion = 1; internal static readonly string[] DropScopes = new string[2] { "world", "game" }; private static bool GameHost => Network.ServerSide; internal static bool AdminPanelOpen { get { try { PluginInfo val = AdminMenuPlugin.Find(); if (val == null || !Object.op_Implicit((Object)(object)val.Instance)) { return false; } return (bool)(((object)val.Instance).GetType().GetProperty("IsPanelOpen", BindingFlags.Static | BindingFlags.Public)?.GetValue(null, null) ?? ((object)false)); } catch { return false; } } } public static string GetEquipmentBindings(string module) { try { if (!EquipmentBindings.Sections.Contains(module)) { throw new ArgumentException(Lang.L("Поддерживаются Diving и VeinMining.")); } return JsonConvert.SerializeObject((object)new { Success = true, Rows = EquipmentBindings.Get(module), Host = (Network.ServerSide && WorldProfile.WorldId != 0) }); } catch (Exception ex) { return JsonConvert.SerializeObject((object)new { Success = false, Message = ex.Message }); } } public static string SetEquipmentBindings(string module, string json) { try { WorldProfileCodec.RequireHost(Network.ServerSide, WorldProfile.WorldId); if (!Modules.Active("AdminIntegration")) { throw new InvalidOperationException(Lang.L("Хранилище настроек остановлено.")); } if (!EquipmentBindings.Sections.Contains(module)) { throw new ArgumentException(Lang.L("Поддерживаются Diving и VeinMining.")); } List<EquipmentRequirement> list = EquipmentBindings.Parse(json); WorldProfileData worldProfileData = CaptureProfile(); worldProfileData.Settings[module + ".RequiredEquipment"] = TomlTypeConverter.ConvertToString((object)JsonConvert.SerializeObject((object)list), typeof(string)); worldProfileData.Settings["General.ServerLocksRules"] = "true"; WorldProfile.Save(worldProfileData); return JsonConvert.SerializeObject((object)new { Success = true, Message = Lang.L("Привязки и бонусы экипировки сохранены для мира и отправлены клиентам.") }); } catch (Exception ex) { return JsonConvert.SerializeObject((object)new { Success = false, Message = ex.Message }); } } private static List<DropRule> ScopeRules(string scope) { if (!(scope == "game")) { return WorldProfile.WorldDrops(); } return Rules.GameDrops; } private static bool Own(IEnumerable<DropRule> rules, string prefab) { return rules.Any((DropRule r) => r.Kind == "Creature" && r.Source == prefab && r.ReplaceAll); } private static List<DropRule> RowsOf(IEnumerable<DropRule> rules, string prefab) { return rules.Where((DropRule r) => r.Kind == "Creature" && r.Source == prefab && !r.ReplaceAll && !string.IsNullOrEmpty(r.Item)).ToList(); } public static string GetCreatureDrops(string prefab) { return GetCreatureDropsScoped(prefab, "world"); } public static string GetCreatureDropsScoped(string prefab, string scope) { try { if (!DropScopes.Contains(scope)) { throw new ArgumentException(Lang.L("Область правил: world или game.")); } ZNetScene instance = ZNetScene.instance; GameObject val = ((instance != null) ? instance.GetPrefab(prefab) : null); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<Character>())) { throw new ArgumentException(Lang.L("Неизвестное существо.")); } List<DropRule> rules = ScopeRules(scope); bool flag = Own(rules, prefab); bool flag2 = !flag && scope == "world" && Own(Rules.GameDrops, prefab); bool overriddenByWorld = scope == "game" && Own(WorldProfile.WorldDrops(), prefab); List<DropRule> list = (flag ? RowsOf(rules, prefab) : (flag2 ? RowsOf(Rules.GameDrops, prefab) : new List<DropRule>())); if (!flag && !flag2) { CharacterDrop component = val.GetComponent<CharacterDrop>(); if (Object.op_Implicit((Object)(object)component)) { foreach (Drop item in component.m_drops.Where((Drop x) => Object.op_Implicit((Object)(object)x?.m_prefab))) { list.Add(new DropRule { Source = prefab, Item = ((Object)item.m_prefab).name, Min = item.m_amountMin, Max = item.m_amountMax, Chance = item.m_chance }); } } } bool host = ((scope == "game") ? GameHost : (Network.ServerSide && WorldProfile.WorldId != 0)); return JsonConvert.SerializeObject((object)new { Success = true, Scope = scope, Scopes = DropScopes, Host = host, Customized = flag, Inherited = flag2, OverriddenByWorld = overriddenByWorld, Enabled = Settings.Get<bool>("Drops", "Enabled"), Rows = list }); } catch (Exception ex) { return JsonConvert.SerializeObject((object)new { Success = false, Message = ex.Message }); } } public static string SetCreatureDrops(string prefab, string json) { return SetCreatureDropsScoped(prefab, json, "world"); } public static string SetCreatureDropsScoped(string prefab, string json, string scope) { try { if (!DropScopes.Contains(scope)) { throw new ArgumentException(Lang.L("Область правил: world или game.")); } if (scope == "game") { if (!GameHost) { throw new InvalidOperationException(Lang.L("Правила для всей игры меняет хост или одиночная игра.")); } } else { WorldProfileCodec.RequireHost(Network.ServerSide, WorldProfile.WorldId); } if (!Modules.Active("AdminIntegration")) { throw new InvalidOperationException(Lang.L("Хранилище настроек отключено.")); } ZNetScene instance = ZNetScene.instance; GameObject val = ((instance != null) ? instance.GetPrefab(prefab) : null); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<Character>()) || Object.op_Implicit((Object)(object)val.GetComponent<Player>())) { throw new ArgumentException(Lang.L("Неизвестное существо.")); } if (json == null || json.Length > 64000) { throw new ArgumentException(Lang.L("Слишком большой список дропа.")); } bool flag = json == "null"; List<DropRule> list = (flag ? new List<DropRule>() : WorldProfileCodec.Rows<DropRule>(json)); if (list.Count > 128) { throw new ArgumentException(Lang.L("Максимум 128 ячеек.")); } foreach (DropRule item in list) { ObjectDB instance2 = ObjectDB.instance; GameObject val2 = ((instance2 != null) ? instance2.GetItemPrefab(item.Item) : null); if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.GetComponent<ItemDrop>())) { throw new ArgumentException(Lang.L("Неизвестный предмет: ") + item.Item); } item.Source = prefab; item.Kind = "Creature"; item.Biome = ""; item.Replace = false; item.ReplaceAll = false; item.MinLevel = 1; item.MaxLevel = 100; } List<DropRule> list2 = (from r in ScopeRules(scope) where r.Source != prefab || r.Kind != "Creature" select r).ToList(); if (!flag) { list2.Add(new DropRule { Source = prefab, ReplaceAll = true, Chance = 0f, Min = 0, Max = 0 }); } list2.AddRange(list); if (scope == "game") { string text = JsonConvert.SerializeObject((object)list2, (Formatting)1); WorldProfile.Validate(new WorldProfileData { Drops = text }); AtomicFile.Write(Path.Combine(Plugin.RulesDir, "drops.json"), text); Rules.Reload(); Network.ForceSync(); return JsonConvert.SerializeObject((object)new { Success = true, Message = (flag ? Lang.L("Правило дропа для всей игры сброшено.") : (Own(WorldProfile.WorldDrops(), prefab) ? Lang.L("Дроп сохранён для всей игры. В этом мире действует своё правило мира.") : Lang.L("Дроп сохранён для всей игры и отправлен клиентам."))) }); } WorldProfileData worldProfileData = CaptureProfile(); worldProfileData.Drops = JsonConvert.SerializeObject((object)list2); worldProfileData.Settings["General.ServerLocksRules"] = "true"; WorldProfile.Save(worldProfileData); return JsonConvert.SerializeObject((object)new { Success = true, Message = (flag ? Lang.L("Правило мира сброшено; действует правило для всей игры, если оно задано.") : Lang.L("Дроп сохранён в ValheimUnified для этого мира и отправлен клиентам.")) }); } catch (Exception ex) { return JsonConvert.SerializeObject((object)new { Success = false, Message = ex.Message }); } } internal static WorldProfileData CaptureProfile() { return new WorldProfileData { World = WorldProfile.WorldId, Settings = Settings.Entries.Where((KeyValuePair<string, ConfigEntryBase> x) => Settings.WorldSetting(x.Value)).ToDictionary((KeyValuePair<string, ConfigEntryBase> x) => x.Key, (KeyValuePair<string, ConfigEntryBase> x) => TomlTypeConverter.ConvertToString(Settings.Value(x.Key), x.Value.SettingType)), Drops = JsonConvert.SerializeObject((object)WorldProfile.WorldDrops()), Raids = JsonConvert.SerializeObject((object)Rules.Raids), Plants = JsonConvert.SerializeObject((object)Rules.Plants), Surfaces = JsonConvert.SerializeObject((object)Rules.Surfaces), Skills = JsonConvert.SerializeObject((object)Rules.Skills) }; } public static string SetDropEnabled(bool enabled) { try { WorldProfileCodec.RequireHost(Network.ServerSide, WorldProfile.WorldId); if (!Modules.Active("AdminIntegration")) { throw new InvalidOperationException(Lang.L("Хранилище настроек отключено.")); } WorldProfileData worldProfileData = CaptureProfile(); worldProfileData.Settings["General.ServerLocksRules"] = "true"; worldProfileData.Settings["Drops.Enabled"] = (enabled ? "true" : "false"); WorldProfile.Save(worldProfileData); return JsonConvert.SerializeObject((object)new { Success = true, Message = (enabled ? Lang.L("Дроп включён для мира.") : Lang.L("Дроп выключен для мира.")) }); } catch (Exception ex) { return JsonConvert.SerializeObject((object)new { Success = false, Message = ex.Message }); } } public static string GetState() { bool host = Network.ServerSide && WorldProfile.WorldId != 0; var rows = (from x in Settings.Entries where Settings.WorldSetting(x.Value) orderby x.Key select x).Select(delegate(KeyValuePair<string, ConfigEntryBase> x) { string key = x.Key; string section = x.Value.Definition.Section; string key2 = x.Value.Definition.Key; string name = x.Value.SettingType.Name; string value = TomlTypeConverter.ConvertToString(Settings.Value(x.Key), x.Value.SettingType); string description = Settings.Describe(x.Value); AcceptableValueBase acceptableValues = x.Value.Description.AcceptableValues; return new { Id = key, Section = section, Key = key2, Type = name, Value = value, Description = description, Range = ((acceptableValues != null) ? acceptableValues.ToDescriptionString() : null), Status = (Modules.All.ContainsKey(x.Value.Definition.Section) ? Modules.All[x.Value.Definition.Section].Fault : null), Editable = (host && x.Key != "General.ServerLocksRules") }; }).ToArray(); return JsonConvert.SerializeObject((object)new { Api = 1, Version = "0.11.1", Host = host, World = WorldProfile.WorldId, WorldProfile = (WorldProfile.Current != null), Peers = Network.Peers.Count(), Rows = rows, Drops = JsonConvert.SerializeObject((object)Rules.Drops, (Formatting)1), Raids = JsonConvert.SerializeObject((object)Rules.Raids, (Formatting)1), Plants = JsonConvert.SerializeObject((object)Rules.Plants, (Formatting)1), Surfaces = JsonConvert.SerializeObject((object)Rules.Surfaces, (Formatting)1), Skills = JsonConvert.SerializeObject((object)Rules.Skills, (Formatting)1) }); } public static string Execute(string command, string payload) { try { long worldId = WorldProfile.WorldId; WorldProfileCodec.RequireHost(Network.ServerSide, worldId); if (!Modules.Active("AdminIntegration")) { throw new InvalidOperationException(Lang.L("Модуль интеграции остановлен: F8 для повторной попытки.")); } WorldProfile.Tick(); switch (command) { case "apply": WorldProfile.Save(WorldProfileCodec.Read(payload, worldId)); break; case "reset": WorldProfile.Remove(); break; case "retry": Plugin.Reload(); break; default: throw new ArgumentException(Lang.L("Неизвестная команда интеграции.")); } return JsonConvert.SerializeObject((object)new { Success = true, Message = Lang.L("Настройки этого мира применены и отправлены клиентам.") }); } catch (Exception ex) { Plugin.Log.LogWarning((object)("AdminMenu integration: " + ex.Message)); return JsonConvert.SerializeObject((object)new { Success = false, Message = ex.Message }); } } } internal static class WorldProfile { internal static WorldProfileData Current; private static long loaded; private static bool attempted; internal static long WorldId { get { if (!Object.op_Implicit((Object)(object)ZNet.instance)) { return 0L; } try { return ZNet.instance.GetWorldUID(); } catch (NullReferenceException) { return 0L; } } } private static string PathFor(long world) { return Path.Combine(Plugin.RulesDir, "world-settings", world.ToString(CultureInfo.InvariantCulture) + ".json"); } internal static void Tick() { if (Network.ShuttingDown) { return; } if (!Network.ServerSide) { if (loaded != 0L) { Reset(); } return; } long worldId = WorldId; if (worldId != 0L && (loaded != worldId || !attempted)) { Reset(); loaded = worldId; attempted = true; string path = PathFor(worldId); if (File.Exists(path)) { WorldProfileData worldProfileData = WorldProfileCodec.Read(File.ReadAllText(path), worldId); Dictionary<string, object> values = Validate(worldProfileData); Install(worldProfileData, values); Plugin.Log.LogInfo((object)("World rules loaded: " + worldId)); Network.ForceSync(); } } } internal static Dictionary<string, object> Validate(WorldProfileData data) { Dictionary<string, object> next = new Dictionary<string, object>(); foreach (KeyValuePair<string, string> setting in data.Settings) { if (!Settings.Entries.TryGetValue(setting.Key, out var value) || !Settings.WorldSetting(value)) { throw new ArgumentException(Lang.L("Неизвестный или локальный параметр: ") + setting.Key); } object obj = TomlTypeConverter.ConvertToValue(setting.Value, value.SettingType); if (obj is float && (float.IsNaN((float)obj) || float.IsInfinity((float)obj))) { throw new ArgumentException(Lang.L("Недопустимое число: ") + setting.Key); } if (value.Description.AcceptableValues != null && !value.Description.AcceptableValues.IsValid(obj)) { throw new ArgumentException(Lang.L("Значение вне диапазона: ") + setting.Key); } if (EquipmentBindings.IsSetting(setting.Key)) { EquipmentBindings.Parse((string)obj); } if (setting.Key == "GuardianPowers.PowerRules") { PowerTuning.Parse((string)obj); } FeatureSettings.Validate(setting.Key, obj); next[setting.Key] = obj; } List<SurfaceRule> list = WorldProfileCodec.Rows<SurfaceRule>(data.Surfaces); List<SkillRule> list2 = WorldProfileCodec.Rows<SkillRule>(data.Skills); SurfaceEffects.Validate(list); SkillBonuses.Validate(list2); List<DropRule> list3 = WorldProfileCodec.Rows<DropRule>(data.Drops); List<RaidRule> list4 = WorldProfileCodec.Rows<RaidRule>(data.Raids); List<PlantRule> list5 = WorldProfileCodec.Rows<PlantRule>(data.Plants); foreach (DropRule item in list3) { if ((item.Kind != "Creature" && item.Kind != "World") || (string.IsNullOrWhiteSpace(item.Item) && !item.ReplaceAll) || float.IsNaN(item.Chance) || item.Chance < 0f || item.Chance > 1f || item.Min < 0 || item.Max < item.Min || item.Max > 10000 || item.MinLevel < 1 || item.MaxLevel < item.MinLevel || (item.ReplaceAll && (item.Kind != "Creature" || item.Source == "*"))) { throw new ArgumentException(Lang.L("Некорректное правило дропа.")); } } foreach (PlantRule item2 in list5) { PlantRules.Validate(item2); } foreach (RaidRule item3 in list4) { RaidProgress.Validate(item3); if (string.IsNullOrWhiteSpace(item3.Event) || float.IsNaN(item3.Duration) || float.IsInfinity(item3.Duration) || item3.Duration < -1f || item3.Duration > 7200f) { throw new ArgumentException(Lang.L("Некорректное правило рейда.")); } if (item3.Spawns == null) { continue; } if (item3.Spawns.Count > 256) { throw new ArgumentException(Lang.L("Слишком много существ рейда.")); } foreach (RaidSpawn spawn in item3.Spawns) { if (spawn == null || string.IsNullOrWhiteSpace(spawn.Prefab) || spawn.MaxSpawned < 1 || spawn.MaxSpawned > 100 || spawn.GroupMin < 1 || spawn.GroupMax < spawn.GroupMin || spawn.GroupMax > 20 || spawn.MinLevel < 1 || spawn.MaxLevel < spawn.MinLevel || spawn.MaxLevel > 10 || float.IsNaN(spawn.Interval) || float.IsInfinity(spawn.Interval) || spawn.Interval < 1f || spawn.Interval > 600f || float.IsNaN(spawn.Chance) || spawn.Chance < 0f || spawn.Chance > 100f) { throw new ArgumentException(Lang.L("Некорректная группа существ рейда.")); } } } string config = JsonConvert.SerializeObject((object)Settings.Entries.Where((KeyValuePair<string, ConfigEntryBase> x) => Settings.WorldSetting(x.Value)).ToDictionary((KeyValuePair<string, ConfigEntryBase> x) => x.Key, (KeyValuePair<string, ConfigEntryBase> x) => TomlTypeConverter.ConvertToString(next.ContainsKey(x.Key) ? next[x.Key] : x.Value.BoxedValue, x.Value.SettingType))); if (JsonConvert.SerializeObject((object)new ServerSnapshot { Version = "0.11.1", Locked = true, Config = config, Drops = list3, Raids = list4, Plants = list5, Surfaces = list, Skills = list2 }).Length > 256000) { throw new ArgumentException(Lang.L("Правила слишком велики для передачи клиентам.")); } return next; } private static void Install(WorldProfileData profile, Dictionary<string, object> values) { Current = profile; Settings.WorldValues.Clear(); Settings.Touch(); foreach (KeyValuePair<string, object> value in values) { Settings.WorldValues[value.Key] = value.Value; } ApplyRules(); Modules.RefreshStates(); } internal static List<DropRule> WorldDrops() { if (Current != null) { return WorldProfileCodec.Rows<DropRule>(Current.Drops); } return new List<DropRule>(); } internal static void ApplyRules() { if (Current != null) { Rules.Drops = Rules.MergeDrops(WorldDrops(), Rules.GameDrops); Rules.Raids = WorldProfileCodec.Rows<RaidRule>(Current.Raids); Rules.Plants = WorldProfileCodec.Rows<PlantRule>(Current.Plants); Rules.Surfaces = WorldProfileCodec.Rows<SurfaceRule>(Current.Surfaces); Rules.Skills = WorldProfileCodec.Rows<SkillRule>(Current.Skills); } } internal static void Save(WorldProfileData profile) { Dictionary<string, object> values = Validate(profile); string text = JsonConvert.SerializeObject((object)profile, (Formatting)1); if (text.Length > 240000) { throw new ArgumentException(Lang.L("Размер правил превышает 240000 символов.")); } Directory.CreateDirectory(Path.GetDirectoryName(PathFor(profile.World))); AtomicFile.Write(PathFor(profile.World), text); Install(profile, values); Network.ForceSync(); } internal static void Reload() { if (Network.ServerSide && loaded != 0L) { string path = PathFor(loaded); if (!File.Exists(path)) { Current = null; Settings.WorldValues.Clear(); Settings.Touch(); } else { WorldProfileData worldProfileData = WorldProfileCodec.Read(File.ReadAllText(path), loaded); Dictionary<string, object> values = Validate(worldProfileData); Install(worldProfileData, values); } } } internal static void Remove() { string text = PathFor(loaded); if (File.Exists(text)) { File.Copy(text, text + ".bak", overwrite: true); File.Delete(text); } Current = null; Settings.WorldValues.Clear(); Settings.Touch(); Rules.Reload(); Modules.RefreshStates(); Network.ForceSync(); } internal static void Reset() { bool num = Current != null; Current = null; loaded = 0L; attempted = false; Settings.WorldValues.Clear(); Settings.Touch(); if (num) { Rules.Reload(); } } } internal static class AdminMenuPlugin { internal static readonly string[] Guids = new string[2] { "chistix.adminmenu", "local.valheim.adminmenu" }; internal static bool Present => Find() != null; internal static PluginInfo Find() { string[] guids = Guids; foreach (string key in guids) { if (Chainloader.PluginInfos.TryGetValue(key, out var value)) { return value; } } return null; } } internal static class Harvest { private static readonly Queue<MonoBehaviour> pending = new Queue<MonoBehaviour>(); private static readonly HashSet<ItemDrop> before = new HashSet<ItemDrop>(); private static readonly HashSet<ItemDrop> requested = new HashSet<ItemDrop>(); private static readonly Queue<ItemDrop> created = new Queue<ItemDrop>(); private static readonly HashSet<MonoBehaviour> interacted = new HashSet<MonoBehaviour>(); private static readonly HashSet<string> outputs = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static Player player; private static Vector3 origin; private static float radius; private static float expires; private static bool started; private static bool alt; private static bool watching; internal static void Created(ItemDrop item) { if (watching && created.Count < 512) { created.Enqueue(item); } } internal static bool Eligible(float distanceSquared, float range, string item, string first, bool sameOnly, string excluded) { if (distanceSquared <= range * range && !string.IsNullOrEmpty(item) && !Settings.InList(item, excluded)) { if (sameOnly) { return string.Equals(item, first, StringComparison.OrdinalIgnoreCase); } return true; } return false; } internal static bool Modifier(KeyCode configured, bool configuredHeld, bool rightShiftHeld) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 if ((int)configured != 0) { if (!configuredHeld) { return (int)configured == 304 && rightShiftHeld; } return true; } return false; } private static bool Held() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) KeyCode val = Settings.Key("AreaHarvest", "ModifierKey"); return Modifier(val, Input.GetKey(val), Input.GetKey((KeyCode)303)); } private static string Output(MonoBehaviour target) { Pickable val = (Pickable)(object)((target is Pickable) ? target : null); if (val != null) { if (!Object.op_Implicit((Object)(object)val.m_itemPrefab)) { return ""; } return Utils.GetPrefabName(val.m_itemPrefab); } Beehive val2 = (Beehive)(object)((target is Beehive) ? target : null); if (val2 != null) { if (!Object.op_Implicit((Object)(object)val2.m_honeyItem)) { return ""; } return Utils.GetPrefabName(((Component)val2.m_honeyItem).gameObject); } PickableItem val3 = (PickableItem)(object)((target is PickableItem) ? target : null); if (val3 != null) { if (!Object.op_Implicit((Object)(object)val3.m_itemPrefab)) { return ""; } return Utils.GetPrefabName(((Component)val3.m_itemPrefab).gameObject); } return ""; } private static bool Ready(MonoBehaviour target) { if (!Object.op_Implicit((Object)(object)target) || !((Behaviour)target).isActiveAndEnabled) { return false; } Pickable val = (Pickable)(object)((target is Pickable) ? target : null); if (val != null) { if (!Object.op_Implicit((Object)(object)val.m_nview) || !val.m_nview.IsValid() || val.GetEnabled == 0 || val.m_picked) { return false; } Floating val2 = ((!val.m_tarPreventsPicking) ? null : (Object.op_Implicit((Object)(object)val.m_floating) ? val.m_floating : ((Component)val).GetComponent<Floating>())); if (Object.op_Implicit((Object)(object)val2)) { return !val2.IsInTar(); } return true; } Beehive val3 = (Beehive)(object)((target is Beehive) ? target : null); if (val3 != null) { if (Settings.Get<bool>("AreaHarvest", "IncludeBeehives") && Object.op_Implicit((Object)(object)val3.m_nview) && val3.m_nview.IsValid()) { return val3.GetHoneyLevel() > 0; } return false; } PickableItem val4 = (PickableItem)(object)((target is PickableItem) ? target : null); if (val4 != null) { if (Object.op_Implicit((Object)(object)val4.m_nview) && val4.m_nview.IsValid() && !val4.m_picked) { return Object.op_Implicit((Object)(object)val4.m_itemPrefab); } return false; } return false; } private static bool Allowed(MonoBehaviour target, string first) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //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_001d: 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) if (Ready(target)) { Vector3 val = ((Component)target).transform.position - origin; if (Eligible(((Vector3)(ref val)).sqrMagnitude, radius, Output(target), first, Settings.Get<bool>("AreaHarvest", "SameItemOnly"), Settings.Get<string>("AreaHarvest", "ExcludedPrefabs"))) { return Network.Ward(((Component)target).transform.position, player.GetPlayerID()); } } return false; } private static void AddOutputs(MonoBehaviour target) { //IL_0038: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) outputs.Add(Output(target)); Pickable val = (Pickable)(object)((target is Pickable) ? target : null); if (val == null || val.m_extraDrops == null) { return; } foreach (DropData drop in val.m_extraDrops.m_drops) { if (Object.op_Implicit((Object)(object)drop.m_item)) { outputs.Add(Utils.GetPrefabName(drop.m_item)); } } } internal static bool Begin(Player actor, GameObject go, bool hold, bool alternate) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) if (hold || !Util.Local(actor) || !Util.InputAllowed() || !Held() || ((Character)actor).InAttack() || ((Character)actor).InDodge() || !Object.op_Implicit((Object)(object)go)) { return false; } Interactable componentInParent = go.GetComponentInParent<Interactable>(); MonoBehaviour val = (MonoBehaviour)(object)((componentInParent is MonoBehaviour) ? componentInParent : null); if (!(val is Pickable) && !(val is PickableItem) && !(val is Beehive)) { return false; } if (Object.op_Implicit((Object)(object)player) && pending.Count > 0) { return false; } if (!Object.op_Implicit((Object)(object)player) || (Object)(object)player != (Object)(object)actor || Time.unscaledTime >= expires) { Reset(); } if (interacted.Contains(val)) { return false; } player = actor; origin = ((Component)actor).transform.position; radius = Settings.Get<float>("AreaHarvest", "HarvestRadius"); string first = Output(val); if (!Allowed(val, first)) { Reset(); return false; } alt = alternate; interacted.Add(val); AddOutputs(val); HashSet<MonoBehaviour> hashSet = new HashSet<MonoBehaviour>(); Collider[] array = Physics.OverlapSphere(origin, radius); for (int i = 0; i < array.Length; i++) { Interactable componentInParent2 = ((Component)array[i]).GetComponentInParent<Interactable>(); MonoBehaviour val2 = (MonoBehaviour)(object)((componentInParent2 is MonoBehaviour) ? componentInParent2 : null); if (Object.op_Implicit((Object)(object)val2) && (Object)(object)val2 != (Object)(object)val && !interacted.Contains(val2) && (val2 is Pickable || val2 is PickableItem || val2 is Beehive) && Allowed(val2, first)) { hashSet.Add(val2); } } foreach (MonoBehaviour item in hashSet.OrderBy(delegate(MonoBehaviour t) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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) Vector3 val3 = ((Component)t).transform.position - origin; return ((Vector3)(ref val3)).sqrMagnitude; }).Take(Settings.Get<int>("AreaHarvest", "MaxTargets") - 1)) { pending.Enqueue(item); interacted.Add(item); AddOutputs(item); } if (Settings.Get<bool>("AreaHarvest", "PickupHarvested") && !watching) { watching = true; } return true; } internal static void Finish() { started = true; expires = Time.unscaledTime + 3f; } internal static void Tick() { //IL_0031: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)player)) { return; } if (started && Util.Local(player) && Util.InputAllowed()) { Vector3 val = ((Component)player).transform.position - origin; if (!(((Vector3)(ref val)).sqrMagnitude > radius * radius)) { for (int i = 0; i < Settings.Get<int>("AreaHarvest", "InteractionsPerFrame"); i++) { if (pending.Count <= 0) { break; } MonoBehaviour val2 = pending.Dequeue(); if (Ready(val2)) { val = ((Component)val2).transform.position - ((Component)player).transform.position; if (!(((Vector3)(ref val)).sqrMagnitude > radius * radius) && !Settings.InList(Output(val2), Settings.Get<string>("AreaHarvest", "ExcludedPrefabs")) && Network.Ward(((Component)val2).transform.position, player.GetPlayerID())) { ((Interactable)val2).Interact((Humanoid)(object)player, false, alt); expires = Time.unscaledTime + 3f; } } } if (Settings.Get<bool>("AreaHarvest", "PickupHarvested")) { int num = 0; int num2 = Math.Min(32, created.Count); for (int j = 0; j < num2; j++) { ItemDrop val3 = created.Dequeue(); if (!Object.op_Implicit((Object)(object)val3) || before.Contains(val3) || requested.Contains(val3) || val3.InTar() || !val3.m_autoPickup || !Object.op_Implicit((Object)(object)val3.m_itemData.m_dropPrefab) || !outputs.Contains(Util.Prefab(val3.m_itemData))) { continue; } val = ((Component)val3).transform.position - origin; if (Eligible(((Vector3)(ref val)).sqrMagnitude, radius + 3f, Util.Prefab(val3.m_itemData), "", sameOnly: false, Settings.Get<string>("AreaHarvest", "ExcludedPrefabs")) && Network.Ward(((Component)val3).transform.position, player.GetPlayerID()) && ((Humanoid)player).GetInventory().CanAddItem(val3.m_itemData, val3.m_itemData.m_stack)) { requested.Add(val3); val3.Pickup((Humanoid)(object)player); if (++num >= 8) { break; } } } } if (pending.Count == 0 && Time.unscaledTime >= expires) { Reset(); } return; } } Reset(); } private unsafe static string ModifierName(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 if ((int)key != 304 && (int)key != 303) { if ((int)key != 306 && (int)key != 305) { if ((int)key != 308 && (int)key != 307) { return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(); } return "Alt"; } return "Ctrl"; } return "Shift"; } internal static string Hint(MonoBehaviour target, string original) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(original) || Settings.InList(Output(target), Settings.Get<string>("AreaHarvest", "ExcludedPrefabs"))) { return original; } return original + Localization.instance.Localize("\n[<color=yellow>" + ModifierName(Settings.Key("AreaHarvest", "ModifierKey")) + Lang.L(" + $KEY_Use</color>] Собрать рядом (") + Settings.Get<float>("AreaHarvest", "HarvestRadius").ToString("0.#") + Lang.L(" м)")); } internal static void Reset() { pending.Clear(); before.Clear(); requested.Clear(); created.Clear(); outputs.Clear(); interacted.Clear(); player = null; started = (watching = false); } } [HarmonyPatch(typeof(Player), "Interact", new Type[] { typeof(GameObject), typeof(bool), typeof(bool) })] internal static class AreaHarvestHooks { private static void Prefix(Player __instance, GameObject go, bool hold, bool alt, out bool __state) { __state = Modules.Try("AreaHarvest", () => Harvest.Begin(__instance, go, hold, alt), fallback: false); } private static void Postfix(bool __state) { if (__state) { Modules.Run("AreaHarvest", Harvest.Finish); } } } [HarmonyPatch] internal static class HarvestHintHooks { private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(Pickable), "GetHoverText", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(PickableItem), "GetHoverText", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(Beehive), "GetHoverText", (Type[])null, (Type[])null); } private static void Postfix(MonoBehaviour __instance, ref string __result) { string original = __result; __result = Modules.Try("AreaHarvest", () => ((int)Settings.Key("AreaHarvest", "ModifierKey") != 0) ? Harvest.Hint(__instance, original) : original, original); } } internal static class AutoConsumption { private sealed class Demand { internal string Role; internal string[] Items; internal int Capacity; } private static readonly HashSet<ZNetView> index = new HashSet<ZNetView>(); private static int cursor; private static readonly Dictionary<ZNetView, float> checks = new Dictionary<ZNetView, float>(); private static readonly HashSet<ZNetView> waiting = new HashSet<ZNetView>(); private static readonly HashSet<string> warned = new HashSet<string>(); private static readonly List<ZNetView> owned = new List<ZNetView>(); private static readonly List<ZNetView> stale = new List<ZNetView>(); internal static void Add(Component component) { ZNetView component2 = component.GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component2) && component2.IsValid()) { index.Add(component2); } } internal static void Reset() { index.Clear(); checks.Clear(); waiting.Clear(); warned.Clear(); cursor = 0; } internal static void ApplyTick() { } private static bool On(string role) { string k = role switch { "Shield" => "SupplyShields", "Cooking" => "SupplyCookingFuel", "Fire" => "SupplyFireplaces", "Food" => "FeedAnimals", _ => "SupplySmelters", }; if (Modules.Active("NearbyResources")) { return Settings.Get<bool>("NearbyResources", k); } return false; } internal static void Tick() { if (!Network.Ready || !Modules.Active("NearbyResources")) { return; } index.RemoveWhere((ZNetView v) => !Object.op_Implicit((Object)(object)v) || !v.IsValid()); stale.Clear(); foreach (ZNetView key in checks.Keys) { if (!Object.op_Implicit((Object)(object)key) || !index.Contains(key)) { stale.Add(key); } } foreach (ZNetView item in stale) { checks.Remove(item); } stale.Clear(); waiting.RemoveWhere((ZNetView v) => !Object.op_Implicit((Object)(object)v) || !index.Contains(v)); owned.Clear(); foreach (ZNetView item2 in index) { if (item2.IsOwner()) { owned.Add(item2); } } if (owned.Count == 0) { return; } int num = Settings.Get<int>("NearbyResources", "DevicesPerPass"); int num2 = 0; int num3 = Settings.Get<int>("NearbyResources", "ConsumerResultsPerFrame"); cursor %= owned.Count; for (int num4 = 0; num4 < num && num4 < owned.Count; num4++) { if (num2 >= num3) { break; } ZNetView val = owned[(cursor + num4) % owned.Count]; bool flag = false; try { flag = Serve(val); } catch (Exception ex) { Containers.Warn("Supply " + (Object.op_Implicit((Object)(object)val) ? Utils.GetPrefabName(((Component)val).gameObject) : "?"), ex); } if (flag) { num2++; } } cursor = (cursor + num) % owned.Count; owned.Clear(); } private static bool Serve(ZNetView view) { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) if (Legacy(view)) { return false; } if (!waiting.Contains(view) && checks.TryGetValue(view, out var value) && Time.unscaledTime < value) { return false; } checks[view] = Time.unscaledTime + Settings.Get<float>("NearbyResources", "ConsumerInterval"); Demand demand = Need(view); if (demand == null || demand.Capacity < 1) { waiting.Remove(view); return false; } int reserve = (Settings.Get<bool>("NearbyResources", "LeaveLastItem") ? 1 : 0); foreach (Container chest in Nearby(view)) { string item = demand.Items.FirstOrDefault((string prefab) => Available(chest, prefab) > reserve); if (item == null) { continue; } string reason; switch (Lease.Acquire(chest, LeasePurpose.Feed, view.GetZDO().m_uid, out reason, hold: false)) { case LeaseState.Waiting: waiting.Add(view); return false; case LeaseState.Failed: if (reason != null && warned.Add(reason)) { Plugin.Log.LogInfo((object)("Supply skipped a chest: " + reason)); } continue; } waiting.Remove(view); int num = BatchLimit((demand.Role == "Food") ? 1 : Settings.Get<int>("NearbyResources", "ConsumerBatch"), Available(chest, item), demand.Capacity, reserve > 0); if (num >= 1) { List<ItemData> taken = new List<ItemData>(); if (ExactInventory.Withdraw(chest.GetInventory(), (ItemData i) => Util.Prefab(i) == item && i.m_worldLevel >= Game.m_worldLevel, num, taken) >= 1) { Apply(view, demand.Role, item, taken); checks[view] = Time.unscaledTime + Math.Min(1f, Settings.Get<float>("NearbyResources", "ConsumerInterval")); return true; } } } waiting.Remove(view); return false; } private static int Available(Container c, string prefab) { int num = 0; foreach (ItemData allItem in c.GetInventory().GetAllItems()) { if (Util.Prefab(allItem) == prefab && allItem.m_worldLevel >= Game.m_worldLevel && !allItem.m_equipped) { num += allItem.m_stack; } } return num; } private static Demand Need(ZNetView view) { ZDO zDO = view.GetZDO(); string protectedList = Settings.Get<string>("NearbyResources", "ProtectedFuelPrefabs"); Func<IEnumerable<string>, string[]> func = (IEnumerable<string> list) => list.Where((string x) => !string.IsNullOrEmpty(x) && !Settings.InList(x, protectedList)).Distinct().ToArray(); Smelter component = ((Component)view).GetComponent<Smelter>(); if (Object.op_Implicit((Object)(object)component) && On("Fuel")) { if (component.m_maxFuel > 0 && Object.op_Implicit((Object)(object)component.m_fuelItem)) { int num = Capacity(zDO, "Fuel"); string[] array = func(new string[1] { ((Object)((Component)component.m_fuelItem).gameObject).name }); if (num > 0 && array.Length != 0) { return new Demand { Role = "Fuel", Items = array, Capacity = num }; } } if (component.m_maxOre > 0) { int num2 = Capacity(zDO, "Ore"); string[] array2 = func(from c in component.m_conversion where Object.op_Implicit((Object)(object)c.m_from) select ((Object)((Component)c.m_from).gameObject).name); if (num2 > 0 && array2.Length != 0) { return new Demand { Role = "Ore", Items = array2, Capacity = num2 }; } } return null; } Tameable component2 = ((Component)view).GetComponent<Tameable>(); if (Object.op_Implicit((Object)(object)component2)) { if (!On("Food") || !component2.IsTamed() || !component2.IsHungry() || !Object.op_Implicit((Object)(object)component2.m_monsterAI) || ((BaseAI)component2.m_monsterAI).IsAlerted() || component2.m_character.IsDead() || component2.m_monsterAI.m_consumeItems == null) { return null; } string[] array3 = func(from i in component2.m_monsterAI.m_consumeItems where Object.op_Implicit((Object)(object)i) select ((Object)((Component)i).gameObject).name); if (array3.Length == 0) { return null; } return new Demand { Role = "Food", Items = array3, Capacity = 1 }; } Fireplace component3 = ((Component)view).GetComponent<Fireplace>(); if (Object.op_Implicit((Object)(object)component3)) { if (!On("Fire") || component3.m_infiniteFuel || !Object.op_Implicit((Object)(object)component3.m_fuelItem)) { return null; } string[] array4 = func(new string[1] { ((Object)((Component)component3.m_fuelItem).gameObject).name }); int num3 = Capacity(zDO, "Fire"); if (num3 <= 0 || array4.Length == 0) { return null; } return new Demand { Role = "Fire", Items = array4, Capacity = num3 }; } CookingStation component4 = ((Component)view).GetComponent<CookingStation>(); if (Object.op_Implicit((Object)(object)component4)) { if (!On("Cooking") || !component4.m_useFuel || !Object.op_Implicit((Object)(object)component4.m_fuelItem)) { return null; } string[] array5 = func(new string[1] { ((Object)((Component)component4.m_fuelItem).gameObject).name }); int num4 = Capacity(zDO, "Cooking"); if (num4 <= 0 || array5.Length == 0) { return null; } return new Demand { Role = "Cooking", Items = array5, Capacity = num4 }; } ShieldGenerator component5 = ((Component)view).GetComponent<ShieldGenerator>(); if (Object.op_Implicit((Object)(object)component5)) { if (!On("Shield")) { return null; } string[] array6 = func(from i in component5.m_fuelItems where Object.op_Implicit((Object)(object)i) select ((Object)((Component)i).gameObject).name); int num5 = Capacity(zDO, "Shield"); if (num5 <= 0 || array6.Length == 0) { return null; } return new Demand { Role = "Shield", Items = array6, Capacity = num5 }; } return null; } private static IEnumerable<Container> Nearby(ZNetView view) { //IL_0022: 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) float range = Settings.Get<float>("NearbyResources", "ConsumerRange"); Vector3 at = ((Component)view).transform.position; return Containers.Index.Where((Container c) => Containers.Zdo(c) != null && Containers.Ordinary(c) && !Containers.InUseByOther(c) && ChestAccess.ConsumerAllowed(c) && (!Settings.Get<bool>("NearbyResources", "PlayerBuiltOnly") || (Object.op_Implicit((Object)(object)c.m_piece) && c.m_piece.GetCreator() != 0L)) && Vector3.Distance(at, ((Component)c).transform.position) <= range).OrderBy(delegate(Container c) { //IL_0006: 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) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)c).transform.position - at; return ((Vector3)(ref val)).sqrMagnitude; }).ToArray(); } internal static int BatchLimit(int requested, int available, int capacity, bool leaveOne) { return Math.Max(0, Math.Min(Math.Min(requested, capacity), available - (leaveOne ? 1 : 0))); } private static int Capacity(ZDO z, string role) { GameObject prefab = ZNetScene.instance.GetPrefab(z.GetPrefab()); if (!Object.op_Implicit((Object)(object)prefab)) { return 0; } float num = z.GetFloat(ZDOVars.s_fuel, 0f); Smelter component = prefab.GetComponent<Smelter>(); switch (role) { case "Fuel": if (!Object.op_Implicit((Object)(object)component)) { return 0; } return Math.Max(0, (int)Math.Floor((float)Production.Scaled(component.m_maxFuel, Production.Capacity) - num)); case "Ore": if (!Object.op_Implicit((Object)(object)component)) { return 0; } return Math.Max(0, Production.Scaled(component.m_maxOre, Production.Capacity) - z.GetInt(ZDOVars.s_queued, 0)); case "Fire": { Fireplace component3 = prefab.GetComponent<Fireplace>(); if (!Object.op_Implicit((Object)(object)component3)) { return 0; } return Math.Max(0, (int)Math.Floor(component3.m_maxFuel - num)); } case "Cooking": { CookingStation component4 = prefab.GetComponent<CookingStation>(); if (!Object.op_Implicit((Object)(object)component4) || !component4.m_useFuel) { return 0; } return Math.Max(0, (int)Math.Floor((float)component4.m_maxFuel - num)); } case "Shield": { ShieldGenerator component2 = prefab.GetComponent<ShieldGenerator>(); if (!Object.op_Implicit((Object)(object)component2)) { return 0; } return Math.Max(0, (int)Math.Floor((float)component2.m_maxFuel - z.GetFloat(ZDOVars.s_fuel, (float)component2.m_defaultFuel))); } default: return (role == "Food") ? 1 : 0; } } private static void Apply(ZNetView view, string role, string item, List<ItemData> taken) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) int num = taken.Sum((ItemData i) => i.m_stack); Transform transform = ((Component)view).transform; switch (role) { case "Fuel": { Smelter component = ((Component)view).GetComponent<Smelter>(); component.SetFuel(Math.Min(component.m_maxFuel, component.GetFuel() + (float)num)); component.m_fuelAddedEffects.Create(transform.position, transform.rotation, transform, 1f, -1, default(ZDOID)); return; } case "Ore": { Smelter component2 = ((Component)view).GetComponent<Smelter>(); foreach (ItemData item2 in taken) { for (int num2 = 0; num2 < item2.m_stack; num2++) { component2.QueueOre(item, item2.m_cheated); } } component2.m_oreAddedEffects.Create(transform.position, transform.rotation, (Transform)null, 1f, -1, default(ZDOID)); return; } case "Fire": ((Component)view).GetComponent<Fireplace>().RPC_AddFuelAmount(ZNet.GetUID(), (float)num); return; case "Cooking": { CookingStation component4 = ((Component)view).GetComponent<CookingStation>(); component4.SetFuel(Math.Min(component4.m_maxFuel, component4.GetFuel() + (float)num)); component4.m_fuelAddedEffects.Create(transform.position, transform.rotation, transform, 1f, -1, default(ZDOID)); return; } case "Shield": { ShieldGenerator component3 = ((Component)view).GetComponent<ShieldGenerator>(); component3.SetFuel(Math.Min(component3.m_maxFuel, component3.GetFuel() + (float)num)); component3.m_fuelAddedEffects.Create(transform.position, transform.rotation, transform, 1f, -1, default(ZDOID)); return; } } Tameable component5 = ((Component)view).GetComponent<Tameable>(); ItemDrop component6 = ObjectDB.instance.GetItemPrefab(item).GetComponent<ItemDrop>(); component5.OnConsumedItem(component6); Character character = component5.m_character; Humanoid val = (Humanoid)(object)((character is Humanoid) ? character : null); if (Object.op_Implicit((Object)(object)val)) { val.m_consumeItemEffects.Create(((Component)component5).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } ((BaseAI)component5.m_monsterAI).m_animator.SetTrigger("consume"); } private static bool Legacy(ZNetView view) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = view.GetZDO(); string text = zDO.GetString("VU.ConsumerTicket", ""); if (text.Length == 0) { return false; } zDO.Set("VU.ConsumerTicket", ""); ConsumerTicket consumerTicket = JsonConvert.DeserializeObject<ConsumerTicket>(text); if (consumerTicket == null || consumerTicket.State == "Applied") { return true; } ZDO zDO2 = ZDOMan.instance.GetZDO(new ZDOID(consumerTicket.ContainerUser, consumerTicket.ContainerId)); if (zDO2 == null) { return true; } string text2 = zDO2.GetString("VU.ConsumerLedger", ""); if (text2.Length == 0) { return true; } Dictionary<string, ConsumerTicket> dictionary = JsonConvert.DeserializeObject<Dictionary<string, ConsumerTicket>>(text2); if (dictionary == null || !dictionary.TryGetValue(consumerTicket.MachineUser + ":" + consumerTicket.MachineId, out var value) || value.Id != consumerTicket.Id || value.State != "Reserved" || string.IsNullOrEmpty(value.Data)) { return true; } List<ItemData> allItems = ExactInventory.Load(value.Data).GetAllItems(); int num = Capacity(zDO, consumerTicket.Role); List<ItemData> list = new List<ItemData>(); foreach (ItemData item in allItems) { ItemData val = item.Clone(); val.m_stack = Math.Max(0, Math.Min(num, item.m_stack)); num -= val.m_stack; if (val.m_stack > 0) { list.Add(val); } int num2 = item.m_stack - val.m_stack; if (num2 > 0) { ItemDrop.DropItem(item, num2, ((Component)view).transform.position + Vector3.up, Quaternion.identity); } } if (list.Count > 0 && On(consumerTicket.Role)) { Apply(view, consumerTicket.Role, consumerTicket.Item, list); } else { foreach (ItemData item2 in list) { ItemDrop.DropItem(item2, item2.m_stack, ((Component)view).transform.position + Vector3.up, Quaternion.identity); } } Plugin.Log.LogWarning((object)("Legacy supply ticket " + consumerTicket.Id + " settled at " + Utils.GetPrefabName(((Component)view).gameObject))); return true; } } [HarmonyPatch] internal static class ConsumerHooks { [HarmonyPostfix] [HarmonyPatch(typeof(Smelter), "Awake")] private static void Smelter(Smelter __instance) { Modules.Run("ConsumerTransport", delegate { AutoConsumption.Add((Component)(object)__instance); }); } [HarmonyPostfix] [HarmonyPatch(typeof(Fireplace), "Awake")] private static void Fire(Fireplace __instance) { Modules.Run("ConsumerTransport", delegate { AutoConsumption.Add((Component)(object)__instance); }); } [HarmonyPostfix] [HarmonyPatch(typeof(CookingStation), "Awake")] private static void Cooking(CookingStation __instance) { Modules.Run("ConsumerTransport", delegate { AutoConsumption.Add((Component)(object)__instance); }); } [HarmonyPostfix] [HarmonyPatch(typeof(ShieldGenerator), "Start")] private static void Shield(ShieldGenerator __instance) { Modules.Run("ConsumerTransport", delegate { AutoConsumption.Add((Component)(object)__instance); }); } [HarmonyPostfix] [HarmonyPatch(typeof(Tameable), "Awake")] private static void Animal(Tameable __instance) { Modules.Run("ConsumerTransport", delegate { AutoConsumption.Add((Component)(object)__instance); }); } } internal static class DivingSkill { internal const int Id = 189404321; internal static readonly SkillType Type = (SkillType)189404321; internal static void Register(Skills skills) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown if (!skills.m_skills.Any((SkillDef s) => (int)s.m_skill == 189404321)) { SkillDef val = ((IEnumerable<SkillDef>)skills.m_skills).FirstOrDefault((Func<SkillDef, bool>)((SkillDef s) => (int)s.m_skill == 103)); skills.m_skills.Add(new SkillDef { m_skill = Type, m_icon = val?.m_icon, m_description = Lang.Token("vu_skill_diving_desc", () => Lang.L("Увеличивает объём лёгких. Развивается при погружении под воду.")), m_increseStep = 1f }); } } internal static float Level(Player p) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)p)) { return 0f; } return ((Character)p).GetSkills().GetSkillLevel(Type); } } [HarmonyPatch] internal static class DivingSkillHooks { [HarmonyPostfix] [HarmonyPriority(0)] [HarmonyPatch(typeof(Skills), "Awake")] private static void Awake(Skills __instance) { Modules.Run("CustomSkills", delegate { DivingSkill.Register(__instance); ExtraSkills.Register(__instance); }); } [HarmonyPostfix] [HarmonyPatch(typeof(Skills), "IsSkillValid")] private static void Valid(SkillType type, ref bool __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected I4, but got Unknown if ((int)type == 189404321 || ExtraSkills.Own((int)type)) { __result = true; } } [HarmonyPrefix] [HarmonyPatch(typeof(Localization), "Localize", new Type[] { typeof(string) })] private static void Localize(ref string text) { if (text != null && text.IndexOf("$skill_18940432", StringComparison.Ordinal) >= 0) { text = text.Replace("$skill_" + 189404321, Lang.L("Подводник")).Replace("$skill_" + 189404322, Lang.L("Мореход")).Replace("$skill_" + 189404323, Lang.L("Картограф")); } } } internal static class Breath { private static Player tracked; private static float oxygen = -1f; private static float damageClock; private static float xpClock; private static GameObject bar; private static Hud hud; private static GuiBar[] bars; private static TMP_Text[] labels; private static Canvas canvas; private static CanvasGroup visibility; private static bool submerged; private static float maximum; private static int shownSeconds = -1; private static int shownMaximum = -1; internal static float Capacity(float level) { float value = Settings.Get<float>("Diving", "OxygenSeconds") + Mathf.Clamp(level, 0f, 100f) * Settings.Get<float>("Diving", "OxygenPerSkillLevel"); return StatModifiers.Apply(Player.m_localPlayer, "Oxygen", value); } internal static void Reset() { tracked = null; oxygen = -1f; damageClock = (xpClock = 0f); if (Object.op_Implicit((Object)(object)bar)) { Object.Destroy((Object)(object)bar); } bar = null; hud = null; bars = null; labels = null; canvas = null; visibility = null; submerged = false; maximum = 0f; shownSeconds = (shownMaximum = -1); } internal static void Tick(Player player, float dt, bool train = true) { //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) if (!Settings.Get<bool>("Diving", "Breathing")) { Reset(); return; } if ((Object)(object)tracked != (Object)(object)player) { Reset(); tracked = player; DivingSkill.Register(((Character)player).GetSkills()); } maximum = Capacity(DivingSkill.Level(player)); bool num = (submerged = DivingSpace.Read(player).Underwater); if (oxygen < 0f) { oxygen = maximum; } oxygen = Mathf.Min(oxygen, maximum); if (num) { oxygen = Mathf.Max(0f, oxygen - dt); if (train) { xpClock += dt; } else { xpClock = 0f; } if (train && xpClock >= 1f) { float num2 = xpClock; xpClock = 0f; ((Character)player).RaiseSkill(DivingSkill.Type, Settings.Get<float>("Diving", "DivingXpPerSecond") * num2); } if (!(oxygen <= 0f)) { return; } damageClock += dt; if (damageClock >= 1f) { float num3 = Settings.Get<float>("Diving", "DrowningDamage") * damageClock; damageClock = 0f; if (num3 > 0f) { HitData val = new HitData(); val.m_damage.m_damage = num3; val.m_hitType = (HitType)4; val.m_point = ((Character)player).GetEyePoint(); ((Character)player).Damage(val); } } } else { oxygen = Mathf.Min(maximum, oxygen + Settings.Get<float>("Diving", "OxygenRecovery") * dt); damageClock = (xpClock = 0f); } } internal static bool Visible(bool hidden, bool underwater, float air, float capacity) { if (!hidden && capacity > 0f) { if (!underwater) { return air < capacity - 0.1f; } return true; } return false; } internal static Rect Layout(Rect stamina, Rect eitr, bool hasEitr, float scale, float screenWidth, float screenHeight) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) float num = Math.Max(160f * scale, ((Rect)(ref stamina)).width); float num2 = Math.Max(24f * scale, ((Rect)(ref stamina)).height); float num3 = (hasEitr ? Math.Min(((Rect)(ref stamina)).y, ((Rect)(ref eitr)).y) : ((Rect)(ref stamina)).y); return new Rect(Mathf.Clamp(((Rect)(ref stamina)).center.x - num / 2f, 4f, Math.Max(4f, screenWidth - num - 4f)), Mathf.Clamp(num3 - num2 - 10f * scale, 4f, Math.Max(4f, screenHeight - num2 - 4f)), num, num2); } private static void Create(Hud current) { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)bar)) { Object.Destroy((Object)(object)bar); } hud = current; canvas = ((Component)current.m_staminaBar2Root).GetComponentInParent<Canvas>(); Transform val = ((Object.op_Implicit((Object)(object)current.m_rootObject) && current.m_rootObject.transform is RectTransform) ? current.m_rootObject.transform : ((Component)canvas).transform); bar = Object.Instantiate<GameObject>(((Component)current.m_staminaBar2Root).gameObject, val); ((Object)bar).name = "Chistix Oxygen"; Animator[] componentsInChildren = bar.GetComponentsInChildren<Animator>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } Transform[] componentsInChildren2 = bar.GetComponentsInChildren<Transform>(true); foreach (Transform val2 in componentsInChildren2) { ((Component)val2).gameObject.SetActive(true); Vector3 localScale = val2.localScale; if (((Vector3)(ref localScale)).sqrMagnitude < 0.001f) { val2.localScale = Vector3.one; } } RectTransform val3 = (RectTransform)bar.transform; ((Transform)val3).localScale = Vector3.one; ((Transform)val3).localRotation = Quaternion.identity; CanvasGroup[] componentsInChildren3 = bar.GetComponentsInChildren<CanvasGroup>(true); foreach (CanvasGroup obj in componentsInChildren3) { obj.alpha = 1f; obj.interactable = false; obj.blocksRaycasts = false; } visibility = bar.GetComponent<CanvasGroup>(); if (!Object.op_Implicit((Object)(object)visibility)) { visibility = bar.AddComponent<CanvasGroup>(); } visibility.alpha = 1f; visibility.interactable = false; visibility.blocksRaycasts = false; visibility.ignoreParentGroups = true; Image[] componentsInChildren4 = bar.GetComponentsInChildren<Image>(true); foreach (Image val4 in componentsInChildren4) { ((Graphic)val4).raycastTarget = false; ((Behaviour)val4).enabled = true; if (Object.op_Implicit((Object)(object)val4.sprite) && ((Graphic)val4).color.a < 0.01f) { Color color = ((Graphic)val4).color; color.a = 1f; ((Graphic)val4).color = color; } } bars = bar.GetComponentsInChildren<GuiBar>(true); GuiBar[] array = bars; foreach (GuiBar obj2 in array) { ((Behaviour)obj2).enabled = true; obj2.m_smoothDrain = (obj2.m_smoothFill = false); obj2.SetMaxValue(1f); obj2.SetValue(1f); obj2.SetColor(new Color(0.15f, 0.65f, 0.95f, 1f)); } labels = bar.GetComponentsInChildren<TMP_Text>(true); TMP_Text[] array2 = labels; foreach (TMP_Text val5 in array2) { ((Behaviour)val5).enabled = true; ((Graphic)val5).raycastTarget = false; Color color2 = ((Graphic)val5).color; color2.a = 1f; ((Graphic)val5).color = color2; val5.transform.SetParent(bar.transform, false); RectTransform rectTransform = val5.rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = new Vector2(3f, 0f); rectTransform.offsetMax = new Vector2(-3f, 0f); val5.alignment = (TextAlignmentOptions)514; val5.enableAutoSizing = true; val5.fontSizeMin = 10f; val5.fontSizeMax = Math.Max(10f, val5.fontSize); } shownSeconds = (shownMaximum = -1); } internal static void Present() { //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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_0148: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)tracked) || !Settings.Get<bool>("Diving", "Breathing")) { return; } Hud instance = Hud.instance; if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)instance.m_staminaBar2Root)) { return; } if (!Visible(Hud.IsUserHidden() || ((Character)tracked).InCutscene(), submerged, oxygen, maximum)) { if (Object.op_Implicit((Object)(object)bar)) { bar.SetActive(false); } return; } if ((Object)(object)hud != (Object)(object)instance || !Object.op_Implicit((Object)(object)bar)) { Create(instance); } if (!bar.activeSelf) { bar.SetActive(true); } visibility.alpha = 1f; float scale = Mathf.Clamp((float)Screen.height / 1080f, 0.6f, 2f); bool flag = Object.op_Implicit((Object)(object)instance.m_eitrBarRoot) && ((Component)instance.m_eitrBarRoot).gameObject.activeInHierarchy; Rect stamina = InventoryPanel.Bounds(instance.m_staminaBar2Root); Rect val; Rect eitr; if (!flag) { val = default(Rect); eitr = val; } else { eitr = InventoryPanel.Bounds(instance.m_eitrBarRoot); } Rect screen = Layout(stamina, eitr, flag, scale, Screen.width, Screen.height); RectTransform val2 = (RectTransform)bar.transform; InventoryPanel.Place(val2, canvas, screen); float value = ((maximum > 0f) ? (oxygen / maximum) : 0f); val = val2.rect; float width = Math.Max(1f, ((Rect)(ref val)).width - instance.m_staminaBarBorderBuffer); GuiBar[] array = bars; foreach (GuiBar obj in array) { obj.SetWidth(width); obj.SetValue(value); } int num = Mathf.CeilToInt(oxygen); int num2 = Mathf.CeilToInt(maximum); if (num != shownSeconds || num2 != shownMaximum) { shownSeconds = num; shownMaximum = num2; string text = Lang.L("Дыхание ") + num + " / " + num2; TMP_Text[] array2 = labels; for (int i = 0; i < array2.Length; i++) { array2[i].text = text; } } } internal static void Draw() { } } internal static class Building { internal static bool NoRain; internal static bool Vehicles; private static PieceTable hammer; private static GameObject listed; private static float next; internal static void Tick() { NoRain = Settings.Get<bool>("Building", "NoRainDamage"); Vehicles = Settings.Get<bool>("Building", "InstantRemoveVehicles"); if (!(Time.unscaledTime < next)) { next = Time.unscaledTime + 1f; List(Settings.Get<bool>("Building", "TrashCan")); } } internal static void Reset() { NoRain = (Vehicles = false); List(show: false); hammer = null; next = 0f; } private static void List(bool show) { if (!Object.op_Implicit((Object)(object)ObjectDB.instance) || !Object.op_Implicit((Object)(object)ZNetScene.instance)) { hammer = null; listed = null; return; } PieceTable val = Table(); if (!Object.op_Implicit((Object)(object)val)) { return; } if (show) { GameObject val2 = CustomPrefabs.Get("VU_TrashCan"); if (Object.op_Implicit((Object)(object)val2) && !val.m_pieces.Contains(val2)) { int num = val.m_pieces.FindIndex((GameObject p) => Object.op_Implicit((Object)(object)p) && ((Object)p).name == "piece_chest_wood"); val.m_pieces.Insert((num < 0) ? val.m_pieces.Count : (num + 1), val2); listed = val2; } } else if (Object.op_Implicit((Object)(object)listed)) { val.m_pieces.Remove(listed); listed = null; } } private static PieceTable Table() { if (Object.op_Implicit((Object)(object)hammer)) { return hammer; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Hammer"); ItemDrop val = (Object.op_Implicit((Object)(object)itemPrefab) ? itemPrefab.GetComponent<ItemDrop>() : null); hammer = (Object.op_Implicit((Object)(object)val) ? val.m_itemData.m_shared.m_buildPieces : null); return hammer; } internal static Piece Target(Player p) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)GameCamera.instance) || !Object.op_Implicit((Object)(object)((Character)p).m_eye)) { return null; } Transform transform = ((Component)GameCamera.instance).transform; RaycastHit val = default(RaycastHit); if (!Physics.Raycast(transform.position, transform.forward, ref val, 50f, p.m_removeRayMask) || Vector3.Distance(((RaycastHit)(ref val)).point, ((Character)p).m_eye.position) >= p.m_maxPlaceDistance) { return null; } return ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Piece>(); } internal static bool Vehicle(Piece piece) { if (Object.op_Implicit((Object)(object)piece)) { if (!Object.op_Implicit((Object)(object)((Component)piece).GetComponent<Ship>())) { return Object.op_Implicit((Object)(object)((Component)piece).GetComponent<Vagon>()); } return true; } return false; } } internal static class TrashCan { internal const string Name = "VU_TrashCan"; internal static bool Is(Container c) { if (Object.op_Implicit((Object)(object)c)) { return Utils.GetPrefabName(((Component)c).gameObject) == "VU_TrashCan"; } return false; } internal static void Define() { CustomPrefabs.Define("VU_TrashCan", Make); } private static GameObject Make() { //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Expected O, but got Unknown //IL_013b: 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_0159: Unknown result type (might be due to invalid IL or missing references) GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab("piece_chest_wood") : null); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<Container>())) { return null; } GameObject val2 = CustomPrefabs.Clone(val, "VU_TrashCan"); Piece component = val2.GetComponent<Piece>(); if (Object.op_Implicit((Object)(object)component)) { component.m_name = Lang.Token("vu_trashcan", () => Lang.L("Урна")); component.m_description = Lang.Token("vu_trashcan_desc", () => Lang.L("Всё, что осталось в урне, удаляется, когда её закрывают.")); } Container component2 = val2.GetComponent<Container>(); component2.m_name = Lang.Token("vu_trashcan", () => Lang.L("Урна")); component2.m_privacy = (PrivacySetting)2; Renderer[] componentsInChildren = val2.GetComponentsInChildren<Renderer>(true); foreach (Renderer val3 in componentsInChildren) { Material[] sharedMaterials = val3.sharedMaterials; for (int num2 = 0; num2 < sharedMaterials.Length; num2++) { if (Object.op_Implicit((Object)(object)sharedMaterials[num2]) && sharedMaterials[num2].HasProperty("_Color")) { Material val4 = new Material(sharedMaterials[num2]); val4.color *= new Color(0.42f, 0.42f, 0.48f, 1f); sharedMaterials[num2] = val4; } } val3.sharedMaterials = sharedMaterials; } return val2; } internal static void Empty(Container chest) { Inventory inventory = chest.GetInventory(); int num = inventory.NrOfItems(); if (num > 0) { inventory.RemoveAll(); if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { ((Character)Player.m_localPlayer).Message((MessageType)1, Lang.L("Урна: удалено предметов — ") + num, 0, (Sprite)null, false); } } } } internal static class TrashSlot { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<Image, bool> <>9__10_0; public static UnityAction <>9__10_1; internal bool <Build>b__10_0(Image i) { if ((Object)(object)((Component)i).gameObject != (Object)(object)plaque) { return Object.op_Implicit((Object)(object)i.sprite); } return false; } internal void <Build>b__10_1() { Modules.Run("Building", Click); } } private static GameObject plaque; private static InventoryGui owner; private static TMP_Text label; private static Button button; private static UITooltip tip; private static Sprite bin; private static float armed; private static string shown; internal static void Reset() { if (Object.op_Implicit((Object)(object)plaque)) { Object.Destroy((Object)(object)plaque); } plaque = null; owner = null; label = null; button = null; tip = null; armed = 0f; shown = null; } private static RectTransform Source(InventoryGui gui) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_0063: 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) TMP_Text weight = gui.m_weight; RectTransform val = (RectTransform)(Object.op_Implicit((Object)(object)weight) ? /*isinst with value type is only supported in some contexts*/: null); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)((Component)val).GetComponent<Image>())) { return null; } Rect rect = val.rect; Vector2 size = ((Rect)(ref rect)).size; if (!(size.x > 0f) || !(size.x < 260f) || !(size.y > 0f) || !(size.y < 260f)) { return null; } return val; } private static void Build(InventoryGui gui) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0061: 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) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Expected O, but got Unknown Reset(); owner = gui; RectTransform val = Source(gui); if (!Object.op_Implicit((Object)(object)val)) { return; } plaque = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Transform)val).parent, false); ((Object)plaque).name = "VU trash plaque"; RectTransform val2 = (RectTransform)plaque.transform; Vector2 anchoredPosition = val.anchoredPosition; Rect rect = val.rect; val2.anchoredPosition = anchoredPosition + new Vector2(0f, ((Rect)(ref rect)).height + 10f); label = plaque.GetComponentsInChildren<TMP_Text>(true).FirstOrDefault(); Localize[] componentsInChildren = plaque.GetComponentsInChildren<Localize>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } Image val3 = ((IEnumerable<Image>)plaque.GetComponentsInChildren<Image>(true)).FirstOrDefault((Func<Image, bool>)((Image val5) => (Object)(object)((Component)val5).gameObject != (Object)(object)plaque && Object.op_Implicit((Object)(object)val5.sprite))); if (Object.op_Implicit((Object)(object)val3)) { val3.sprite = Bin(); val3.preserveAspect = true; } Image component = plaque.GetComponent<Image>(); ((Graphic)component).raycastTarget = true; button = plaque.GetComponent<Button>() ?? plaque.AddComponent<Button>(); ((Selectable)button).targetGraphic = (Graphic)(object)component; ((Selectable)button).transition = (Transition)1; ColorBlock defaultColorBlock = ColorBlock.defaultColorBlock; ((ColorBlock)(ref defaultColorBlock)).highlightedColor = new Color(1f, 0.86f, 0.6f); ((ColorBlock)(ref defaultColorBlock)).pressedColor = new Color(1f, 0.7f, 0.4f); ((ColorBlock)(ref defaultColorBlock)).disabledColor = new Color(0.62f, 0.62f, 0.62f, 0.85f); ((Selectable)button).colors = defaultColorBlock; Button obj = button; Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)obj).navigation = navigation; ((UnityEventBase)button.onClick).RemoveAllListeners(); ButtonClickedEvent onClick = button.onClick; object obj2 = <>c.<>9__10_1; if (obj2 == null) { UnityAction val4 = delegate { Modules.Run("Building", Click); }; <>c.<>9__10_1 = val4; obj2 = (object)val4; } ((UnityEvent)onClick).AddListener((UnityAction)obj2); tip = plaque.GetComponent<UITooltip>() ?? plaque.AddComponent<UITooltip>(); if (!Object.op_Implicit((Object)(object)tip.m_tooltipPrefab)) { tip.m_tooltipPrefab = InventoryTips.Template(gui, null); } shown = null; } private static Sprite Bin() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)bin)) { return bin; } Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false) { hideFlags = (HideFlags)61, filterMode = (FilterMode)1 }; Color val2 = default(Color); ((Color)(ref val2))..ctor(0f, 0f, 0f, 0f); Color ink = new Color(0.86f, 0.8f, 0.68f, 1f); Color[] px = (Color[])(object)new Color[1024]; for (int i = 0; i < px.Length; i++) { px[i] = val2; } for (int j = 5; j <= 26; j++) { Dot(j, 24); Dot(j, 25); } for (int k = 12; k <= 19; k++) { Dot(k, 27); Dot(k, 28); } Dot(12, 26); Dot(19, 26); for (int l = 3; l <= 22; l++) { int num = (22 - l) / 7; for (int m = 0; m < 2; m++) { Dot(7 + num + m, l); Dot(24 - num - m, l); } } for (int n = 9; n <= 22; n++) { Dot(n, 3); Dot(n, 4); } for (int num2 = 6; num2 <= 20; num2++) { Dot(12, num2); Dot(15, num2); Dot(16, num2); Dot(19, num2); } val.SetPixels(px); val.Apply(); bin = Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f), 100f); return bin; void Dot(int x, int y) { //IL_001f: 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) if (x >= 0 && y >= 0 && x < 32 && y < 32) { px[y * 32 + x] = ink; } } } internal static void Tick() { InventoryGui instance = InventoryGui.instance; if (!Settings.Get<bool>("Building", "TrashSlot") || !Object.op_Implicit((Object)(object)instance) || !InventoryGui.IsVisible() || ChestNames.Editing) { if (Object.op_Implicit((Object)(object)plaque) && plaque.activeSelf) { plaque.SetActive(false); } return; } if (!Object.op_Implicit((Object)(object)plaque) || (Object)(object)owner != (Object)(object)instance) { Build(instance); } if (Object.op_Implicit((Object)(object)plaque)) { if (!plaque.activeSelf) { plaque.SetActive(true); } bool flag = instance.m_dragItem != null; bool flag2 = flag && Time.unscaledTime < armed; ((Selectable)button).interactable = flag; string text = (flag2 ? Lang.L("<color=#ff6a5a>Точно?</color>") : Lang.L("Урна")); if (Object.op_Implicit((Object)(object)label) && text != shown) { shown = text; label.text = text; } if (Object.op_Implicit((Object)(object)tip)) { tip.m_topic = Lang.L("Урна"); tip.m_text = ((!flag) ? Lang.L("Возьмите предмет из ячейки и нажмите на урну, чтобы удалить его") : (flag2 ? Lang.L("Нажмите ещё раз — предмет удалится") : Lang.L("Нажмите, чтобы удалить взятый предмет. Shift — сразу"))); } } } private static void Click() { InventoryGui instance = InventoryGui.instance; Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)localPlayer) || instance.m_dragItem == null || instance.m_dragInventory == null) { return; } bool flag = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); if (Settings.Get<bool>("Building", "TrashConfirm") && !flag && Time.unscaledTime >= armed) { armed = Time.unscaledTime + 3f; return; } armed = 0f; ItemData dragItem = instance.m_dragItem; Inventory dragInventory = instance.m_dragInventory; int num = Math.Max(1, Math.Min(instance.m_dragAmount, dragItem.m_stack)); if (dragInventory == ((Humanoid)localPlayer).GetInventory() && ((Humanoid)localPlayer).IsItemEquiped(dragItem)) { ((Humanoid)localPlayer).UnequipItem(dragItem, true); } dragInventory.RemoveItem(dragItem, num); instance.SetupDragItem((ItemData)null, (Inventory)null, 1); ((Character)localPlayer).Message((MessageType)1, Lang.L("Удалено: ") + Lang.Game(dragItem.m_shared.m_name) + ((num > 1) ? (" ×" + num) : ""), 0, (Sprite)null, false); } } [HarmonyPatch] internal static class BuildingHooks { [HarmonyPrefix] [HarmonyPatch(typeof(WearNTear), "UpdateWear")] private static void Wear(WearNTear __instance, float time) { if (Building.NoRain) { __instance.m_rainTimer = time; } } [HarmonyPrefix] [HarmonyPatch(typeof(Player), "RemovePiece")] private static void Remove(Player __instance, out Piece __state) { __state = null; if (!Building.Vehicles || (Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } try { Piece val = Building.Target(__instance); if (Object.op_Implicit((Object)(object)val) && !val.m_canBeRemoved && Building.Vehicle(val)) { val.m_canBeRemoved = true; __state = val; } } catch (Exception ex) { Modules.Fault("Building", "Remove", ex); } } [HarmonyFinalizer] [HarmonyPatch(typeof(Player), "RemovePiece")] private static Exception Removed(Piece __state, Exception __exception) { if (Object.op_Implicit((Object)(object)__state)) { __state.m_canBeRemoved = false; } return __exception; } [HarmonyPrefix] [HarmonyPatch(typeof(Container), "SetInUse")] private static void Close(Container __instance, bool inUse) { if (inUse || !TrashCan.Is(__instance) || !Object.op_Implicit((Object)(object)__instance.m_nview) || !__instance.m_nview.IsValid() || !__instance.m_nview.IsOwner()) { return; } Modules.Run("Building", delegate { if (Settings.Get<bool>("Building", "TrashCan")) { TrashCan.Empty(__instance); } }); } } public static class BuildResources { public const int Version = 1; public static bool Reserve(Player player, Requirement[] requirements, int multiplier, Action onReady) { if (!Object.op_Implicit((Object)(object)player) || (Object)(object)player != (Object)(object)Player.m_localPlayer || requirements == null || requirements.Length == 0 || multiplier < 1) { return true; } if (!Modules.Active("NearbyResources") || !Settings.Get<bool>("NearbyResources", "Build") || player.NoCostCheat() || (Object.op_Implicit((Object)(object)ZoneSystem.instance) && ZoneSystem.instance.GetGlobalKey((GlobalKeys)24))) { return true; } try { List<Need> list = Resources.Requirements(player, requirements, 1, multiplier, one: false); return list == null || list.Count == 0 || Resources.Gate(player, list, onReady); } catch (Exception ex) { Containers.Warn("Build reserve", ex); Util.Message(Lang.L("Сундуки сейчас недоступны.")); return false; } } } internal static class Cartography { private static Minimap map; private static float native = -1f; private static uint fogCount; private static bool tracking; internal static float Factor(float common, float skill, float skillBonus) { return Math.Max(0.1f, common / 100f * (1f + skill * skillBonus / 100f)); } internal static float Radius(Player p) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) float num = 1f; if (Modules.Active("Cartography")) { num *= Factor(Settings.Get<int>("Map", "RadiusPercent"), Settings.Get<bool>("Map", "Skill") ? ExtraSkills.Factor(p, ExtraSkills.Cartography) : 0f, Settings.Get<int>("Map", "SkillRadius")); } if (Modules.Active("Sailing")) { num *= Sailing.ExploreFactor(p); } return native * num; } internal static void Before(Minimap m, Player p) { if ((Object)(object)map != (Object)(object)m) { map = m; native = m.m_exploreRadius; } float num = Radius(p); if (m.m_exploreRadius != num) { m.m_exploreRadius = num; } tracking = Object.op_Implicit((Object)(object)m.m_fogTexture); if (tracking) { fogCount = ((Texture)m.m_fogTexture).updateCount; } } internal static void After(Minimap m, Player p) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (tracking && Object.op_Implicit((Object)(object)m.m_fogTexture) && ((Texture)m.m_fogTexture).updateCount != fogCount && Modules.Active("Cartography") && Settings.Get<bool>("Map", "Skill")) { ((Character)p).RaiseSkill(ExtraSkills.Cartography, Settings.Get<float>("Map", "SkillXp")); } } internal static void Reset() { if (Object.op_Implicit((Object)(object)map) && native > 0f) { map.m_exploreRadius = native; } } } [HarmonyPatch] internal static class CartographyHooks { [HarmonyPrefix] [HarmonyPatch(typeof(Minimap), "UpdateExplore")] private static void Before(Minimap __instance, Player player) { if (!Object.op_Implicit((Object)(object)player)) { return; } try { Cartography.Before(__instance, player); } catch (Exception ex) { Modules.Fault("MapRadius", "Explore", ex); } } [HarmonyPostfix] [HarmonyPatch(typeof(Minimap), "UpdateExplore")] private static void After(Minimap __instance, Player player) { if (!Object.op_Implicit((Object)(object)player)) { return; } try { Cartography.After(__instance, player); } catch (Exception ex) { Modules.Fault("MapRadius", "Explore", ex); } } } internal static class CatalogBridge { private static Assembly assembly; private static MethodInfo items; private static MethodInfo creatures; private static MethodInfo icon; private static MethodInfo categoryMap; private static bool failed; private static bool Bind() { PluginInfo val = AdminMenuPlugin.Find(); if (val == null || !Object.op_Implicit((Object)(object)val.Instance)) { return false; } Assembly assembly = ((object)val.Instance).GetType().Assembly; if (assembly == CatalogBridge.assembly) { return !failed; } CatalogBridge.assembly = assembly; failed = false; try { Type type = assembly.GetType("AdminMenu.ModCatalogApi", throwOnError: true); if ((int)type.GetField("ApiVersion", BindingFlags.Static | BindingFlags.Public).GetRawConstantValue() != 1) { throw new InvalidOperationException("Unsupported catalog API"); } items = type.GetMethod("GetItemPrefabs", Type.EmptyTypes); creatures = type.GetMethod("GetCreaturePrefabs", Type.EmptyTypes); icon = type.GetMethod("GetCreatureIcon", new Type[1] { typeof(string) }); categoryMap = type.GetMethod("GetItemCategoryMap", Type.EmptyTypes); if (categoryMap != null && (!categoryMap.IsStatic || categoryMap.ReturnType != typeof(string))) { categoryMap = null; } if (items == null || creatures == null || icon == null || items.ReturnType != typeof(GameObject[]) || creatures.ReturnType != typeof(GameObject[]) || icon.ReturnType != typeof(Sprite) || !items.IsStatic || !creatures.IsStatic || !icon.IsStatic) { throw new MissingMethodException("Catalog contract incomplete"); } return true; } catch (Exception ex) { Fail(ex); return false; } } private static void Fail(Exception ex) { failed = true; Plugin.Log.LogWarning((object)("AdminMenu catalog unavailable; using game registries: " + (ex.InnerException ?? ex).Message)); } internal static GameObject[] Items() { if (Bind()) { try { return (GameObject[])(((object)(GameObject[])items.Invoke(null, null)) ?? ((object)new GameObject[0])); } catch (Exception ex) { Fail(ex); } } if (!Object.op_Implicit((Object)(object)ObjectDB.instance)) { return (GameObject[])(object)new GameObject[0]; } return ObjectDB.instance.m_items.ToArray(); } internal static string CategoryMap() { if (Bind() && categoryMap != null) { try { return (string)categoryMap.Invoke(null, null); } catch (Exception ex) { Fail(ex); } } return null; } internal static GameObject[] Creatures() { if (Bind()) { try { return (GameObject[])(((object)(GameObject[])creatures.Invoke(null, null)) ?? ((object)new GameObject[0])); } catch (Exception ex) { Fail(ex); } } if (!Object.op_Implicit((Object)(object)ZNetScene.instance)) { return (GameObject[])(object)new GameObject[0]; } return ZNetScene.instance.m_prefabs.ToAr