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 Cogling v1.0.0
plugins/Cogling.dll
Decompiled a day 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.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using HeaveHo.Shared; using Microsoft.CodeAnalysis; using Nick.Shared; using Splatform; using UnityEngine; using UnityEngine.Animations; using UnityEngine.Audio; using UnityEngine.Playables; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyMetadata("AI_Assisted_Creation", "This assembly was partially or fully created with the assistance of Generative AI.")] [assembly: AssemblyMetadata("AI_Model_Vendor", "Anthropic")] [assembly: AssemblyMetadata("ClaudeTools.Reload", "world")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace HeaveHo.Shared { internal sealed class ServerSettings : IDisposable { public enum ServerMod { NotConnected, Checking, Installed, Missing } private sealed class ConfigurationManagerAttributes { public bool? ReadOnly; } private sealed class SyncedText { public string Key; public Func<string> Own; public Action<string> Use; public string Given; public bool FromServer; public bool Pending; public byte[] Packed; public bool TooBig; public MemoryStream Incoming; public int NextPart; } private sealed class Sending { public ZRpc Rpc; public string Key; public byte[] Data; public int Next; public int Parts; } private const int Protocol = 2; private const float ChangeSendGap = 0.5f; private const float AnswerWait = 20f; private const float FileWait = 1f; private const int PartSize = 65536; private const int CompressFrom = 1024; private const int WarnBytes = 262144; private const int MaxBytes = 8388608; private const int PaceBelow = 10240; private readonly string _send; private readonly string _ask; private readonly string _dAsk; private readonly string _dHello; private readonly string _dSend; private readonly string _edit; private readonly string _dTextAsk; private readonly string _dText; private readonly string _dAgain; private readonly ConfigFile _config; private readonly ManualLogSource _log; private readonly string _name; private readonly List<ConfigEntryBase> _entries = new List<ConfigEntryBase>(); private readonly Dictionary<ConfigEntryBase, object> _own = new Dictionary<ConfigEntryBase, object>(); private readonly Dictionary<ConfigEntryBase, object> _server = new Dictionary<ConfigEntryBase, object>(); private readonly List<GameObject> _guardedPieces = new List<GameObject>(); private readonly List<Recipe> _guardedRecipes = new List<Recipe>(); private ZRoutedRpc _registeredOn; private bool _applying; private bool _reloading; private bool _changePending; private float _nextChangeSend; private float _askedAt = -1f; private int _serverProtocol; private bool _directSeen; private readonly HashSet<ZRpc> _directPeers = new HashSet<ZRpc>(); private readonly List<SyncedText> _texts = new List<SyncedText>(); private readonly Dictionary<ZRpc, HashSet<string>> _textPeers = new Dictionary<ZRpc, HashSet<string>>(); private bool _textPending; private float _nextTextSend; private bool _readOnlyShown; private float _nextAdminCheck; private FileSystemWatcher _watcher; private volatile bool _fileTouched; private float _reloadAt = -1f; private string _fileText; private readonly List<Sending> _outbox = new List<Sending>(); private static readonly MethodInfo UpdateAvailablePieces = AccessTools.Method(typeof(Player), "UpdateAvailablePiecesList", (Type[])null, (Type[])null); private static readonly List<ServerSettings> Live = new List<ServerSettings>(); private static Harmony _saveHarmony; public string Version { get; } public bool FromServer => _server.Count > 0; public ServerMod Server { get; private set; } public string ServerVersion { get; private set; } public bool CanEditServer { get { if (!IsServer) { if (Server == ServerMod.Installed && _serverProtocol >= 1 && (Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.LocalPlayerIsAdminOrHost(); } return false; } return true; } } private static bool IsServer { get { if ((Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.IsServer(); } return false; } } public event Action ServerChanged; public ServerSettings(string guid, ConfigFile config, ManualLogSource log) { _send = guid + ".settings"; _ask = guid + ".settings.ask"; _dAsk = guid + ".settings.d.ask"; _dHello = guid + ".settings.d.hello"; _dSend = guid + ".settings.d.values"; _edit = guid + ".settings.d.edit"; _dTextAsk = guid + ".settings.d.textask"; _dAgain = guid + ".settings.d.again"; _dText = guid + ".settings.d.text"; _config = config; _log = log; BepInPlugin val = PluginOf(guid); _name = ((val != null) ? val.Name : null) ?? guid; Version = ((val == null) ? null : val.Version?.ToString()) ?? ""; Live.Add(this); if (Live.Count == 1) { PatchSave(); } WatchFile(); } public ConfigEntry<T> Add<T>(ConfigEntry<T> entry) { if (entry == null || _entries.Contains((ConfigEntryBase)(object)entry)) { return entry; } _entries.Add((ConfigEntryBase)(object)entry); entry.SettingChanged += OnChanged; GiveManagerAttributes((ConfigEntryBase)(object)entry); return entry; } private static void GiveManagerAttributes(ConfigEntryBase entry) { ConfigDescription description = entry.Description; if (description == null || description == ConfigDescription.Empty || (description.Tags ?? new object[0]).Any(IsManagerAttributes)) { return; } try { object[] value = new object[1] { new ConfigurationManagerAttributes() }.Concat(description.Tags ?? new object[0]).ToArray(); AccessTools.Field(typeof(ConfigDescription), "<Tags>k__BackingField")?.SetValue(description, value); } catch (Exception) { } } public ConfigEntry<T> Bind<T>(string section, string key, T value, string description, AcceptableValueBase range = null, params object[] tags) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown if (!description.Contains("[Synced with Server]")) { description += " [Synced with Server]"; } return Add<T>(_config.Bind<T>(section, key, value, new ConfigDescription(description, range, tags ?? new object[0]))); } public void NeedsServer(GameObject piecePrefab) { if (!((Object)(object)piecePrefab == (Object)null)) { _guardedPieces.RemoveAll((GameObject p) => (Object)(object)p == (Object)null || ((Object)p).name == ((Object)piecePrefab).name); _guardedPieces.Add(piecePrefab); Guard(); } } public void NeedsServer(Recipe recipe) { if (!((Object)(object)recipe == (Object)null)) { _guardedRecipes.RemoveAll((Recipe r) => (Object)(object)r == (Object)null || (Object)(object)r == (Object)(object)recipe || (!string.IsNullOrEmpty(((Object)recipe).name) && ((Object)r).name == ((Object)recipe).name)); _guardedRecipes.Add(recipe); Guard(); } } public void AddText(string key, Func<string> own, Action<string> use) { if (string.IsNullOrEmpty(key) || own == null || use == null) { ManualLogSource log = _log; if (log != null) { log.LogError((object)"AddText needs a key, own and use"); } return; } _texts.RemoveAll((SyncedText x) => x.Key == key); SyncedText syncedText = new SyncedText { Key = key, Own = own, Use = use }; _texts.Add(syncedText); Give(syncedText, OwnText(syncedText)); ZRpc val = ((!((Object)(object)ZNet.instance != (Object)null) || IsServer) ? null : ZNet.instance.GetServerPeer()?.m_rpc); if (_registeredOn != null && val != null) { val.Register<ZPackage>(_dText, (Action<ZRpc, ZPackage>)OnText); AskTexts(val); } } public void TextChanged(string key) { SyncedText syncedText = _texts.FirstOrDefault((SyncedText x) => x.Key == key); if (syncedText != null) { syncedText.Packed = null; if (!syncedText.FromServer) { Give(syncedText, OwnText(syncedText)); } if (IsServer) { syncedText.Pending = true; _textPending = true; } } } public bool TextFromServer(string key) { return _texts.Any((SyncedText x) => x.Key == key && x.FromServer); } public void Update() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != _registeredOn) { Unregister(); Restore(); RestoreTexts(give: true); _changePending = false; _textPending = false; SetServer(ServerMod.NotConnected, null, 0); if (instance != null) { Register(instance); } } float unscaledTime = Time.unscaledTime; if (_changePending && unscaledTime >= _nextChangeSend) { SendChange(); } if (_textPending && unscaledTime >= _nextTextSend) { SendTexts(); } if (_outbox.Count > 0) { Pump(); } if (Server == ServerMod.Checking && _askedAt >= 0f && unscaledTime - _askedAt > 20f) { if (_guardedPieces.Count + _guardedRecipes.Count > 0) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("The server didn't answer: " + _name + " isn't installed there (or its copy is older than 2026-10-11), so its pieces and items can't be made on this server.")); } } else { ManualLogSource log2 = _log; if (log2 != null) { log2.LogInfo((object)("The server didn't answer: " + _name + " isn't installed there, or its copy is older" + (FromServer ? " (its settings apply)." : " (your own settings apply)."))); } } SetServer(ServerMod.Missing, null, 0); } if (_fileTouched) { _fileTouched = false; _reloadAt = unscaledTime + 1f; } if (_reloadAt >= 0f && unscaledTime >= _reloadAt) { _reloadAt = -1f; ReloadFile(); } if (FromServer && unscaledTime >= _nextAdminCheck) { _nextAdminCheck = unscaledTime + 1f; ShowReadOnly(); } } public void Dispose() { Unregister(); Restore(); RestoreTexts(give: false); SetServer(ServerMod.NotConnected, null, 0); foreach (ConfigEntryBase entry in _entries) { Unsubscribe(entry); } _entries.Clear(); _texts.Clear(); try { _watcher?.Dispose(); } catch (Exception) { } _watcher = null; Live.Remove(this); if (Live.Count == 0) { UnpatchSave(); } } private void Register(ZRoutedRpc rpc) { Forget(rpc, _send); Forget(rpc, _ask); rpc.Register<ZPackage>(_send, (Action<long, ZPackage>)OnRoutedValues); rpc.Register(_ask, (Action<long>)OnRoutedAsk); rpc.m_onNewPeer = (Action<long>)Delegate.Combine(rpc.m_onNewPeer, new Action<long>(OnNewPeer)); _registeredOn = rpc; if (IsServer) { foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { ListenTo(peer); if (peer != null) { ZRpc rpc2 = peer.m_rpc; if (rpc2 != null) { rpc2.Invoke(_dAgain, Array.Empty<object>()); } } } return; } if ((Object)(object)ZNet.instance != (Object)null) { SetServer(ServerMod.Checking, null, 0); if (ZNet.instance.GetServerPeer() != null) { AskServer(); } } } private void Unregister() { if (_registeredOn == null) { return; } ZRoutedRpc registeredOn = _registeredOn; registeredOn.m_onNewPeer = (Action<long>)Delegate.Remove(registeredOn.m_onNewPeer, new Action<long>(OnNewPeer)); Forget(_registeredOn, _send); Forget(_registeredOn, _ask); if ((Object)(object)ZNet.instance != (Object)null) { foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (peer?.m_rpc != null) { string[] array = new string[7] { _dAsk, _dHello, _dSend, _edit, _dTextAsk, _dText, _dAgain }; foreach (string name in array) { ForgetDirect(peer.m_rpc, name); } } } } _directPeers.Clear(); _textPeers.Clear(); _outbox.Clear(); _directSeen = false; _registeredOn = null; } private static void Forget(ZRoutedRpc rpc, string name) { if (AccessTools.Field(typeof(ZRoutedRpc), "m_functions")?.GetValue(rpc) is IDictionary dictionary) { dictionary.Remove(StringExtensionMethods.GetStableHashCode(name)); } } private static void ForgetDirect(ZRpc rpc, string name) { if (AccessTools.Field(typeof(ZRpc), "m_functions")?.GetValue(rpc) is IDictionary dictionary) { dictionary.Remove(StringExtensionMethods.GetStableHashCode(name)); } } private void OnNewPeer(long uid) { if (IsServer) { ZNetPeer peer = ZNet.instance.GetPeer(uid); ListenTo(peer); if (peer?.m_rpc != null) { SendDirect(peer.m_rpc); } SendRouted(uid); } else if ((Object)(object)ZNet.instance != (Object)null) { ZNetPeer serverPeer = ZNet.instance.GetServerPeer(); if (serverPeer != null && serverPeer.m_uid == uid) { AskServer(); } } } private void ListenTo(ZNetPeer peer) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown if (peer?.m_rpc != null) { peer.m_rpc.Register(_dAsk, new Method(OnDirectAsk)); peer.m_rpc.Register<ZPackage>(_edit, (Action<ZRpc, ZPackage>)OnEdit); peer.m_rpc.Register<ZPackage>(_dTextAsk, (Action<ZRpc, ZPackage>)OnTextAsk); } } private void OnDirectAsk(ZRpc rpc) { if (IsServer) { _directPeers.Add(rpc); SendDirect(rpc); } } private void OnRoutedAsk(long sender) { if (IsServer) { SendRouted(sender); } } private void SendDirect(ZRpc rpc) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(2); val.Write(Version); rpc.Invoke(_dHello, new object[1] { val }); if (_entries.Count > 0) { rpc.Invoke(_dSend, new object[1] { Values() }); } } private void SendRouted(long target) { if (ZRoutedRpc.instance != null && _entries.Count > 0) { ZRoutedRpc.instance.InvokeRoutedRPC(target, _send, new object[1] { Values() }); } } private ZPackage Values() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(_entries.Count); foreach (ConfigEntryBase entry in _entries) { val.Write(entry.Definition.Section); val.Write(entry.Definition.Key); val.Write(TomlTypeConverter.ConvertToString(entry.BoxedValue, entry.SettingType)); } return val; } private void AskServer() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown ZNetPeer val = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetServerPeer() : null); if (val?.m_rpc == null) { return; } _askedAt = Time.unscaledTime; val.m_rpc.Register<ZPackage>(_dHello, (Action<ZRpc, ZPackage>)OnDirectHello); val.m_rpc.Register<ZPackage>(_dSend, (Action<ZRpc, ZPackage>)OnDirectValues); val.m_rpc.Register<ZPackage>(_dText, (Action<ZRpc, ZPackage>)OnText); val.m_rpc.Register(_dAgain, new Method(OnAskAgain)); val.m_rpc.Invoke(_dAsk, Array.Empty<object>()); AskTexts(val.m_rpc); try { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(val.m_uid, _ask, Array.Empty<object>()); } } catch (Exception) { } } private static bool IsServerConnection(ZRpc rpc) { if (!IsServer) { ZNet instance = ZNet.instance; return ((instance == null) ? null : instance.GetServerPeer()?.m_rpc) == rpc; } return false; } private void OnAskAgain(ZRpc rpc) { if (IsServerConnection(rpc)) { rpc.Invoke(_dAsk, Array.Empty<object>()); AskTexts(rpc); } } private void OnDirectHello(ZRpc rpc, ZPackage pkg) { if (!IsServerConnection(rpc)) { return; } try { int protocol = pkg.ReadInt(); string text = pkg.ReadString(); if (text != Version && text != ServerVersion) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("The server has " + _name + " " + text + ", you have " + Version + ": some things may not match. Use the same version as the server.")); } } _directSeen = true; SetServer(ServerMod.Installed, text, protocol); } catch (Exception ex) { ManualLogSource log2 = _log; if (log2 != null) { log2.LogWarning((object)("Could not read the server's hello: " + ex.Message)); } } } private void OnDirectValues(ZRpc rpc, ZPackage pkg) { if (IsServerConnection(rpc)) { TakeValues(pkg); } } private void OnRoutedValues(long sender, ZPackage pkg) { if (!_directSeen && !IsServer) { ZNetPeer val = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetServerPeer() : null); if (val != null && val.m_uid == sender) { TakeValues(pkg); } } } private void TakeValues(ZPackage pkg) { try { int num = pkg.ReadInt(); List<string> list = new List<string>(); for (int i = 0; i < num; i++) { string section = pkg.ReadString(); string key = pkg.ReadString(); string text = pkg.ReadString(); ConfigEntryBase val = ((IEnumerable<ConfigEntryBase>)_entries).FirstOrDefault((Func<ConfigEntryBase, bool>)((ConfigEntryBase x) => x.Definition.Section == section && x.Definition.Key == key)); if (val != null) { object obj; try { obj = TomlTypeConverter.ConvertToValue(text, val.SettingType); } catch (Exception) { continue; } if (!_own.ContainsKey(val)) { _own[val] = val.BoxedValue; } _server[val] = obj; if (!object.Equals(val.BoxedValue, obj)) { Apply(val, obj); list.Add(section + "/" + key + " = " + text); } } } ManualLogSource log = _log; if (log != null) { log.LogInfo((object)($"Settings from the server apply while you play here ({_server.Count})" + ((list.Count > 0) ? (": " + string.Join(", ", list.ToArray())) : ""))); } ShowReadOnly(); } catch (Exception ex2) { ManualLogSource log2 = _log; if (log2 != null) { log2.LogWarning((object)("Could not read the server's settings: " + ex2.Message)); } } } private void Apply(ConfigEntryBase e, object value) { bool saveOnConfigSet = _config.SaveOnConfigSet; _applying = true; try { _config.SaveOnConfigSet = false; e.BoxedValue = value; } finally { _config.SaveOnConfigSet = saveOnConfigSet; _applying = false; } } private void Restore() { if (_server.Count == 0) { return; } foreach (KeyValuePair<ConfigEntryBase, object> item in _own) { Apply(item.Key, item.Value); } _own.Clear(); _server.Clear(); ShowReadOnly(); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)"Your own settings apply again"); } } private void OnChanged(object sender, EventArgs args) { if (_applying) { return; } ConfigEntryBase val = (ConfigEntryBase)((sender is ConfigEntryBase) ? sender : null); if (val == null) { return; } if (_server.TryGetValue(val, out var value)) { if (!_reloading && CanEditServer) { SendEdit(val); } else { _own[val] = val.BoxedValue; } Apply(val, value); } else if (IsServer) { _changePending = true; if (Time.unscaledTime >= _nextChangeSend) { SendChange(); } } } private void SendChange() { _changePending = false; _nextChangeSend = Time.unscaledTime + 0.5f; if (!IsServer) { return; } foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (peer?.m_rpc == null) { continue; } if (_directPeers.Contains(peer.m_rpc)) { if (_entries.Count > 0) { peer.m_rpc.Invoke(_dSend, new object[1] { Values() }); } } else { SendRouted(peer.m_uid); } } } private void SendEdit(ConfigEntryBase e) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown ZNet instance = ZNet.instance; ZNetPeer val = ((instance != null) ? instance.GetServerPeer() : null); if (val?.m_rpc != null) { ZPackage val2 = new ZPackage(); val2.Write(e.Definition.Section); val2.Write(e.Definition.Key); val2.Write(TomlTypeConverter.ConvertToString(e.BoxedValue, e.SettingType)); val.m_rpc.Invoke(_edit, new object[1] { val2 }); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("Asked the server to set " + e.Definition.Section + "/" + e.Definition.Key)); } } } private void OnEdit(ZRpc rpc, ZPackage pkg) { try { if (!IsServer) { return; } ISocket socket = rpc.GetSocket(); string text = ((socket != null) ? socket.GetHostName() : null) ?? ""; ZNetPeer val = ((IEnumerable<ZNetPeer>)ZNet.instance.GetPeers()).FirstOrDefault((Func<ZNetPeer, bool>)((ZNetPeer p) => p.m_rpc == rpc)); string section = pkg.ReadString(); string key = pkg.ReadString(); string text2 = pkg.ReadString(); if (!ZNet.instance.IsAdmin(text)) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)((val?.m_playerName ?? text) + " tried to change " + section + "/" + key + " but isn't on the admin list")); } if (_entries.Count > 0) { rpc.Invoke(_dSend, new object[1] { Values() }); } return; } ConfigEntryBase val2 = ((IEnumerable<ConfigEntryBase>)_entries).FirstOrDefault((Func<ConfigEntryBase, bool>)((ConfigEntryBase x) => x.Definition.Section == section && x.Definition.Key == key)); if (val2 != null) { val2.BoxedValue = TomlTypeConverter.ConvertToValue(text2, val2.SettingType); ManualLogSource log2 = _log; if (log2 != null) { log2.LogInfo((object)("Admin " + (val?.m_playerName ?? text) + " set " + section + "/" + key + " = " + text2)); } } } catch (Exception ex) { ManualLogSource log3 = _log; if (log3 != null) { log3.LogWarning((object)("Could not take an admin's change: " + ex.Message)); } } } private void ShowReadOnly() { bool flag = FromServer && !CanEditServer; if (flag == _readOnlyShown) { return; } _readOnlyShown = flag; foreach (ConfigEntryBase entry in _entries) { ConfigDescription description = entry.Description; object[] array = ((description != null) ? description.Tags : null) ?? new object[0]; foreach (object obj in array) { if (IsManagerAttributes(obj)) { try { AccessTools.Field(obj.GetType(), "ReadOnly")?.SetValue(obj, flag ? ((object)true) : null); } catch (Exception) { } } } } } private static bool IsManagerAttributes(object tag) { if (tag != null) { return tag.GetType().Name == "ConfigurationManagerAttributes"; } return false; } private string OwnText(SyncedText t) { try { return t.Own() ?? ""; } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("Could not read " + t.Key + ": " + ex.Message)); } return t.Given ?? ""; } } private void Give(SyncedText t, string text) { if (t.Given != null && t.Given == text) { return; } t.Given = text; try { t.Use(text); } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("Could not use " + t.Key + ": " + ex)); } } } private void RestoreTexts(bool give) { foreach (SyncedText text in _texts) { text.Incoming = null; if (!text.FromServer) { continue; } text.FromServer = false; if (give) { Give(text, OwnText(text)); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("Your own " + text.Key + " applies again")); } } } } private void AskTexts(ZRpc server) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown if (_texts.Count == 0 || server == null) { return; } ZPackage val = new ZPackage(); val.Write(_texts.Count); foreach (SyncedText text in _texts) { val.Write(text.Key); } server.Invoke(_dTextAsk, new object[1] { val }); } private void OnTextAsk(ZRpc rpc, ZPackage pkg) { try { if (!IsServer) { return; } int num = pkg.ReadInt(); HashSet<string> hashSet = new HashSet<string>(); for (int i = 0; i < num && i < 1000; i++) { string key = pkg.ReadString(); if (_texts.Any((SyncedText x) => x.Key == key)) { hashSet.Add(key); } } if (_textPeers.TryGetValue(rpc, out var value)) { hashSet.UnionWith(value); } foreach (ZRpc item in _textPeers.Keys.Where((ZRpc r) => !r.IsConnected()).ToList()) { _textPeers.Remove(item); } _textPeers[rpc] = hashSet; foreach (SyncedText text in _texts) { if (hashSet.Contains(text.Key)) { SendText(rpc, text); } } } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("Could not answer a player's ask for server data: " + ex.Message)); } } } private void SendTexts() { _textPending = false; _nextTextSend = Time.unscaledTime + 0.5f; if (!IsServer) { return; } foreach (SyncedText text in _texts) { if (!text.Pending) { continue; } text.Pending = false; foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (peer?.m_rpc != null && _textPeers.TryGetValue(peer.m_rpc, out var value) && value.Contains(text.Key)) { SendText(peer.m_rpc, text); } } } } private void SendText(ZRpc rpc, SyncedText t) { byte[] array = Packed(t); if (array != null) { _outbox.RemoveAll((Sending s) => s.Rpc == rpc && s.Key == t.Key); _outbox.Add(new Sending { Rpc = rpc, Key = t.Key, Data = array, Parts = Math.Max(1, (array.Length + 65536 - 1) / 65536) }); Pump(); } } private void Pump() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown for (int num = _outbox.Count - 1; num >= 0; num--) { Sending sending = _outbox[num]; try { while (sending.Next < sending.Parts && sending.Rpc.IsConnected() && sending.Rpc.GetSocket().GetSendQueueSize() < 10240) { int num2 = sending.Next * 65536; int num3 = Math.Min(65536, sending.Data.Length - num2); byte[] array = new byte[num3]; Buffer.BlockCopy(sending.Data, num2, array, 0, num3); ZPackage val = new ZPackage(); val.Write(sending.Key); val.Write(sending.Next); val.Write(sending.Parts); val.Write(array); sending.Rpc.Invoke(_dText, new object[1] { val }); sending.Next++; } if (sending.Next >= sending.Parts || !sending.Rpc.IsConnected()) { _outbox.RemoveAt(num); } } catch (Exception ex) { _outbox.RemoveAt(num); ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("Could not send " + sending.Key + " to a player: " + ex.Message)); } } } } private byte[] Packed(SyncedText t) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown if (t.Packed == null) { string text = OwnText(t); ZPackage val = new ZPackage(); val.Write(text); ZPackage val2 = new ZPackage(); bool flag = text.Length > 1024; val2.Write(flag); if (flag) { val2.WriteCompressed(val); } else { val2.Write(val); } t.Packed = val2.GetArray(); t.TooBig = t.Packed.Length > 8388608; string arg = $"{t.Packed.Length / 1024} KB" + (flag ? $" gzipped ({text.Length / 1024} KB of text)" : ""); if (t.TooBig) { ManualLogSource log = _log; if (log != null) { log.LogError((object)$"{t.Key} is too big to send to players ({arg}, at most {8} MB): they keep their own."); } } else if (t.Packed.Length > 262144) { ManualLogSource log2 = _log; if (log2 != null) { log2.LogWarning((object)$"{t.Key} is big to send to every player who joins ({arg}): it takes about {(float)t.Packed.Length / 153600f:0} s of their connection, and their world loads slower meanwhile."); } } } if (!t.TooBig) { return t.Packed; } return null; } private void OnText(ZRpc rpc, ZPackage pkg) { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown if (!IsServerConnection(rpc)) { return; } SyncedText syncedText = null; try { string key = pkg.ReadString(); int num = pkg.ReadInt(); int num2 = pkg.ReadInt(); byte[] array = pkg.ReadByteArray(); syncedText = _texts.FirstOrDefault((SyncedText x) => x.Key == key); if (syncedText == null) { return; } if (num2 < 1 || num2 > 129 || num < 0 || num >= num2) { throw new InvalidDataException($"part {num} of {num2}"); } if (num == 0) { syncedText.Incoming = new MemoryStream(); syncedText.NextPart = 0; } if (syncedText.Incoming == null || num != syncedText.NextPart) { throw new InvalidDataException($"part {num} came out of order"); } syncedText.Incoming.Write(array, 0, array.Length); syncedText.NextPart = num + 1; if (num >= num2 - 1) { ZPackage val = new ZPackage(syncedText.Incoming.ToArray()); syncedText.Incoming = null; ZPackage val2 = (val.ReadBool() ? val.ReadCompressedPackage() : val.ReadPackage()); string text = val2.ReadString(); syncedText.FromServer = true; Give(syncedText, text); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)$"The server's {key} applies while you play here ({text.Length / 1024} KB)"); } } } catch (Exception ex) { if (syncedText != null) { syncedText.Incoming = null; } ManualLogSource log2 = _log; if (log2 != null) { log2.LogWarning((object)("Could not read the server's data" + ((syncedText != null) ? (" for " + syncedText.Key) : "") + ": " + ex.Message)); } } } private void SetServer(ServerMod state, string version, int protocol) { if (state != ServerMod.Checking) { _askedAt = -1f; } bool flag = state != Server || version != ServerVersion; Server = state; ServerVersion = version; _serverProtocol = protocol; if (!flag) { return; } Guard(); try { this.ServerChanged?.Invoke(); } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("ServerChanged: " + ex)); } } } private void Guard() { bool flag = Server == ServerMod.NotConnected || Server == ServerMod.Installed; bool flag2 = false; foreach (GameObject guardedPiece in _guardedPieces) { Piece val = (((Object)(object)guardedPiece != (Object)null) ? guardedPiece.GetComponent<Piece>() : null); if ((Object)(object)val != (Object)null && val.m_enabled != flag) { val.m_enabled = flag; flag2 = true; } } foreach (Recipe guardedRecipe in _guardedRecipes) { if ((Object)(object)guardedRecipe != (Object)null && guardedRecipe.m_enabled != flag) { guardedRecipe.m_enabled = flag; flag2 = true; } } if (flag2 && (Object)(object)Player.m_localPlayer != (Object)null) { try { UpdateAvailablePieces?.Invoke(Player.m_localPlayer, null); } catch (Exception) { } } } private void WatchFile() { try { string configFilePath = _config.ConfigFilePath; _watcher = new FileSystemWatcher(Path.GetDirectoryName(configFilePath), Path.GetFileName(configFilePath)) { NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite) }; FileSystemEventHandler value = delegate { _fileTouched = true; }; _watcher.Changed += value; _watcher.Created += value; _watcher.Renamed += delegate { _fileTouched = true; }; _watcher.EnableRaisingEvents = true; } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("Edits to the config file apply after a restart (can't watch it: " + ex.Message + ")")); } } } private void ReloadFile() { string text = ReadFile(_config.ConfigFilePath); if (text == null) { if (File.Exists(_config.ConfigFilePath)) { _reloadAt = Time.unscaledTime + 1f; } } else { if (text == _fileText) { return; } _fileText = text; bool saveOnConfigSet = _config.SaveOnConfigSet; _reloading = true; try { _config.SaveOnConfigSet = false; _config.Reload(); } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("Could not read the edited config file (check the line you changed): " + ex.Message)); } } finally { _config.SaveOnConfigSet = saveOnConfigSet; _reloading = false; } } } private void PatchSave() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_0045: 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 //IL_0067: Expected O, but got Unknown try { _saveHarmony = new Harmony(_send + ".save"); _saveHarmony.Patch((MethodBase)AccessTools.Method(typeof(ConfigFile), "Save", (Type[])null, (Type[])null), new HarmonyMethod(typeof(ServerSettings), "BeforeSave", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(ServerSettings), "AfterSave", (Type[])null), (HarmonyMethod)null); } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("Could not keep the server's values out of your config file: " + ex.Message)); } } } private static void UnpatchSave() { try { Harmony saveHarmony = _saveHarmony; if (saveHarmony != null) { saveHarmony.UnpatchSelf(); } } catch (Exception) { } _saveHarmony = null; } private static void BeforeSave(ConfigFile __instance) { foreach (ServerSettings item in Live) { if (item._config != __instance) { continue; } foreach (KeyValuePair<ConfigEntryBase, object> item2 in item._own) { SetQuietly(item2.Key, item2.Value); } } } private static Exception AfterSave(ConfigFile __instance, Exception __exception) { foreach (ServerSettings item in Live) { if (item._config != __instance) { continue; } foreach (KeyValuePair<ConfigEntryBase, object> item2 in item._server) { SetQuietly(item2.Key, item2.Value); } item._fileText = ReadFile(__instance.ConfigFilePath); } return __exception; } private static string ReadFile(string path) { try { return File.Exists(path) ? File.ReadAllText(path) : null; } catch (Exception) { return null; } } private static void SetQuietly(ConfigEntryBase e, object value) { AccessTools.Field(((object)e).GetType(), "_typedValue")?.SetValue(e, value); } private static BepInPlugin PluginOf(string guid) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown Type[] array; try { array = typeof(ServerSettings).Assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { array = ex.Types.Where((Type t) => t != null).ToArray(); } Type[] array2 = array; foreach (Type type in array2) { object[] customAttributes = type.GetCustomAttributes(typeof(BepInPlugin), inherit: false); for (int num2 = 0; num2 < customAttributes.Length; num2++) { BepInPlugin val = (BepInPlugin)customAttributes[num2]; if (val.GUID == guid || guid.StartsWith(val.GUID + ".")) { return val; } } } return null; } private void Unsubscribe(ConfigEntryBase e) { ((object)e).GetType().GetEvent("SettingChanged")?.RemoveEventHandler(e, new EventHandler(OnChanged)); } } } namespace Cogling { internal sealed class Antenna : MonoBehaviour, Hoverable, Interactable { internal const string Name = "cogling_antenna"; private float _nextRing; private static readonly List<Antenna> All = new List<Antenna>(); private ZNetView _view; private GameObject _marker; private float _nextRebuildCheck; private static readonly int GhostLayer = LayerMask.NameToLayer("ghost"); internal static GameObject Prefab; private static GameObject _holder; private static PieceTable _table; private const float DishFrom = 1.16f; private const float CutAt = 1.06f; private const float PostWidth = 0.3f; private static Mesh _post; private static Mesh _dish; private static Vector3 _pivot; private static Material _bulbMaterial; private static Vector3? _lampCentre; private static Mesh _cylinder; internal static float Radius => Plugin.AntennaRadius.Value; public string GetHoverName() { return Localization.instance.Localize("$cogling_antenna"); } public float GetHoverOffset() { return 0f; } public string GetHoverText() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) List<Antenna> network = NetworkAt(((Component)this).transform.position); if (network.Count == 0) { network = new List<Antenna> { this }; } int num = CoglingsIn(network); int num2 = network.Count * Plugin.CoglingsPerAntenna.Value; List<string> list = Character.GetAllCharacters().Where(delegate(Character c) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (CoglingStance.IsCogling(c) && !c.IsDead()) { ZNetView component = ((Component)c).GetComponent<ZNetView>(); if (((component != null) ? component.GetZDO() : null) != null) { return InArea(network, ((Component)c).transform.position); } } return false; }).Select(CoglingTag.NameOf) .ToList(); long now = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetTime().Ticks : 0); List<float> list2 = (from r in network.SelectMany((Antenna a) => Rebuilds.Pending(a)) select Mathf.Max(0f, (float)new TimeSpan(r.due - now).TotalMinutes) into m orderby m select m).ToList(); List<string> list3 = new List<string>(); list3.Add(Translations.T((network.Count > 1) ? "cogling_antenna_powers_linked" : "cogling_antenna_powers", num, num2, network.Count)); List<string> list4 = list3; if (list.Count > 0) { list4.Add(string.Join(", ", list)); } foreach (float item in list2) { list4.Add(Translations.T("cogling_antenna_rebuilding", Mathf.CeilToInt(item))); } list4.Add(Translations.T("cogling_antenna_range", Radius.ToString("0"))); return GetHoverName() + "\n<color=#bdb7a9>" + string.Join("\n", list4) + "</color>" + Localization.instance.Localize("\n[<color=yellow><b>$KEY_Use</b></color>] $cogling_antenna_bell"); } public bool Interact(Humanoid user, bool hold, bool alt) { //IL_0068: 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_00fe: Unknown result type (might be due to invalid IL or missing references) if (hold || alt || Time.time < _nextRing || (Object)(object)_view == (Object)null || !_view.IsValid() || !(user is Player)) { return false; } _nextRing = Time.time + 3f; List<Antenna> network = NetworkAt(((Component)this).transform.position); if (network.Count == 0) { network = new List<Antenna> { this }; } List<Character> list = (from c in Character.GetAllCharacters().Where(delegate(Character c) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (CoglingStance.IsCogling(c) && !c.IsDead()) { ZNetView component = ((Component)c).GetComponent<ZNetView>(); if (((component != null) ? component.GetZDO() : null) != null) { return InArea(network, ((Component)c).transform.position); } } return false; }) orderby Vector3.SignedAngle(((Component)user).transform.position - ((Component)this).transform.position, ((Component)c).transform.position - ((Component)this).transform.position, Vector3.up) select c).ToList(); for (int num = 0; num < list.Count; num++) { ((Component)list[num]).GetComponent<ZNetView>().InvokeRPC("cogling_called", new object[3] { ((Component)this).transform.position, ((Component)user).transform.position, num * 100 + Mathf.Min(99, list.Count) }); } return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } private void Awake() { _view = ((Component)this).GetComponent<ZNetView>(); Transform obj = ((Component)this).transform.Find("AreaMarker"); _marker = ((obj != null) ? ((Component)obj).gameObject : null); if ((Object)(object)_marker != (Object)null) { CircleProjector component = _marker.GetComponent<CircleProjector>(); if (component != null) { component.m_radius = Radius; } } if ((Object)(object)_view != (Object)null && _view.GetZDO() != null) { All.Add(this); _view.Unregister("cogling_rebuild_add"); _view.Register<long, long>("cogling_rebuild_add", (Action<long, long, long>)delegate(long sender, long due, long creator) { Rebuilds.RPC_Add(this, due, creator); }); } Shape(((Component)this).gameObject); if (!((Component)this).GetComponents<MonoBehaviour>().Any((MonoBehaviour m) => (Object)(object)m != (Object)null && ((object)m).GetType().Name == "AntennaLife")) { ((Component)this).gameObject.AddComponent<AntennaLife>(); } } private void OnDestroy() { All.Remove(this); if ((Object)(object)_view != (Object)null && _view.IsValid()) { _view.Unregister("cogling_rebuild_add"); } } internal static void ApplySize() { //IL_0000: 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) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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) Vector3 localScale = Vector3.one * Plugin.AntennaSize.Value; if ((Object)(object)Prefab != (Object)null) { Prefab.transform.localScale = localScale; } foreach (Antenna item in All) { if ((Object)(object)item != (Object)null) { ((Component)item).transform.localScale = localScale; } } } private void Update() { if (Time.time > _nextRebuildCheck) { _nextRebuildCheck = Time.time + 5f; Rebuilds.Tick(this); } bool flag = (((Object)(object)_view != (Object)null && _view.GetZDO() != null) || ((Component)this).gameObject.layer == GhostLayer) && ShowAreas(); if (!((Object)(object)_marker != (Object)null) || _marker.activeSelf == flag) { return; } _marker.SetActive(flag); if (flag) { CircleProjector component = _marker.GetComponent<CircleProjector>(); if (component != null) { component.m_radius = Radius; } } } private static bool ShowAreas() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !((Character)localPlayer).InPlaceMode()) { return false; } Piece selectedPiece = localPlayer.GetSelectedPiece(); if ((Object)(object)selectedPiece == (Object)null) { return false; } string name = ((Object)((Component)selectedPiece).gameObject).name; if (!(name == "cogling_antenna")) { return name == "cogling"; } return true; } internal static Antenna Nearest(Vector3 at, float within) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return (from a in All where (Object)(object)a != (Object)null && Vector3.Distance(((Component)a).transform.position, at) <= within orderby Vector3.Distance(((Component)a).transform.position, at) select a).FirstOrDefault(); } internal static bool Covers(Vector3 at) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return All.Any((Antenna a) => (Object)(object)a != (Object)null && Utils.DistanceXZ(((Component)a).transform.position, at) <= Radius); } internal static List<Antenna> NetworkAt(Vector3 at) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) List<Antenna> list = All.Where((Antenna a) => (Object)(object)a != (Object)null && Utils.DistanceXZ(((Component)a).transform.position, at) <= Radius).ToList(); for (int num = 0; num < list.Count; num++) { foreach (Antenna item in All) { if ((Object)(object)item != (Object)null && !list.Contains(item) && Utils.DistanceXZ(((Component)item).transform.position, ((Component)list[num]).transform.position) <= 2f * Radius) { list.Add(item); } } } return list; } internal static int CoglingsIn(List<Antenna> network) { return Character.GetAllCharacters().Count(delegate(Character c) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (CoglingStance.IsCogling(c) && !c.IsDead()) { ZNetView component = ((Component)c).GetComponent<ZNetView>(); if (((component != null) ? component.GetZDO() : null) != null) { return InArea(network, ((Component)c).transform.position); } } return false; }) + network.Sum((Antenna a) => ((Object)(object)a != (Object)null) ? Rebuilds.Pending(a).Count : 0); } internal static bool InArea(List<Antenna> network, Vector3 at) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return network.Any((Antenna a) => (Object)(object)a != (Object)null && Utils.DistanceXZ(((Component)a).transform.position, at) <= Radius); } internal static void Register(ZNetScene scene) { if ((Object)(object)scene == (Object)null) { return; } if ((Object)(object)Prefab == (Object)null) { Prefab = Build(scene); } if (!((Object)(object)Prefab == (Object)null)) { GameObject prefab = scene.GetPrefab("Hammer"); PieceTable val = ((!((Object)(object)prefab != (Object)null)) ? null : prefab.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_buildPieces); if ((Object)(object)val != (Object)null) { _table = val; } PieceReload.ReplacePrefab(scene, Prefab, ((Object)(object)val != (Object)null) ? val : _table); int num = PieceReload.Reattach(scene, Prefab); if (num > 0) { Plugin.Log.LogInfo((object)$"Gave {num} standing antenna(s) this copy's code"); } ApplyCost(); if (Prefab.GetComponent<Piece>().m_resources.Length == 0 && (Object)(object)_table != (Object)null) { _table.m_pieces.Remove(Prefab); Plugin.Log.LogWarning((object)"The Cogling antenna has no cost (see its Cost setting): it isn't in the build menu"); } Plugin.Synced.NeedsServer(Prefab); } } internal static void ApplyCost() { Piece val = (((Object)(object)Prefab != (Object)null) ? Prefab.GetComponent<Piece>() : null); if (!((Object)(object)val == (Object)null)) { Costs.Apply(val, Plugin.AntennaCost.Value, Plugin.Log); Costs.ApplyStation(val, Plugin.AntennaStation.Value, Plugin.Log); } } internal static void Unregister() { PieceReload.UnloadPiece(Prefab, _table); _holder = (Prefab = null); _table = null; All.Clear(); _post = (_dish = null); } private static GameObject Build(ZNetScene scene) { //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: 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_009c: Expected O, but got Unknown //IL_0163: 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) //IL_025c: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = scene.GetPrefab("dverger_demister"); GameObject prefab2 = scene.GetPrefab("piece_dvergr_lantern_pole"); Piece val = ((prefab2 != null) ? prefab2.GetComponent<Piece>() : null); GameObject prefab3 = scene.GetPrefab("wood_beam"); object obj; if (prefab3 == null) { obj = null; } else { Transform obj2 = prefab3.transform.Find("new"); if (obj2 == null) { obj = null; } else { MeshRenderer component = ((Component)obj2).GetComponent<MeshRenderer>(); obj = ((component != null) ? ((Renderer)component).sharedMaterial : null); } } Material val2 = (Material)obj; GameObject prefab4 = scene.GetPrefab("guard_stone"); if ((Object)(object)prefab == (Object)null || (Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"The game has no Dvergr wisp light or lantern post to copy: no Cogling antenna this session"); return null; } _holder = new GameObject("cogling_prefabs_antenna"); _holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_holder); GameObject val3 = Object.Instantiate<GameObject>(prefab, _holder.transform); ((Object)val3).name = "cogling_antenna"; val3.layer = ((Component)val).gameObject.layer; ZNetView component2 = val3.GetComponent<ZNetView>(); if (component2 != null) { component2.m_persistent = true; } Piece val4 = val3.GetComponent<Piece>() ?? val3.AddComponent<Piece>(); FieldInfo[] fields = typeof(Piece).GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { fieldInfo.SetValue(val4, fieldInfo.GetValue(val)); } val4.m_name = "$cogling_antenna"; val4.m_description = "$cogling_antenna_desc"; val4.m_category = (PieceCategory)0; val4.m_usage = (UsageTagFlags)1; val4.m_icon = val.m_icon; val4.m_resources = (Requirement[])(object)new Requirement[0]; try { Renderer[] componentsInChildren = val3.GetComponentsInChildren<Renderer>(true); foreach (Renderer val5 in componentsInChildren) { Material[] sharedMaterials = val5.sharedMaterials; for (int k = 0; k < sharedMaterials.Length; k++) { if ((Object)(object)sharedMaterials[k] != (Object)null && ((Object)sharedMaterials[k]).name.StartsWith("torch") && (Object)(object)val2 != (Object)null) { sharedMaterials[k] = val2; } } val5.sharedMaterials = sharedMaterials; } Shape(val3); Transform val6 = (((Object)(object)prefab4 != (Object)null) ? prefab4.transform.Find("AreaMarker") : null); if ((Object)(object)val6 != (Object)null) { GameObject val7 = Object.Instantiate<GameObject>(((Component)val6).gameObject, val3.transform); ((Object)val7).name = "AreaMarker"; val7.transform.localPosition = Vector3.zero; val7.SetActive(false); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Cogling antenna look: " + ex.Message)); } val3.transform.localScale = Vector3.one * Plugin.AntennaSize.Value; val3.AddComponent<Antenna>(); try { val4.m_icon = Icon.Make(val3, null, null, null) ?? val4.m_icon; } catch (Exception ex2) { Plugin.Log.LogWarning((object)("Cogling antenna icon: " + ex2.Message)); } return val3; } private static void Shape(GameObject antenna) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0133: 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_019a: 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_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) Transform val = antenna.transform.Find("_enabled"); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(false); Scene scene = antenna.scene; if (((Scene)(ref scene)).IsValid()) { Object.Destroy((Object)(object)((Component)val).gameObject); } else { Object.DestroyImmediate((Object)(object)((Component)val).gameObject, true); } } Transform val2 = antenna.transform.Find("New"); if ((Object)(object)val2 == (Object)null) { return; } Transform val3 = val2.Find("cogling_turn"); if ((Object)(object)val3 == (Object)null) { val3 = new GameObject("cogling_turn") { layer = ((Component)val2).gameObject.layer }.transform; val3.SetParent(val2, false); } string[] array = new string[2] { "cogling_dish", "cogling_hinge" }; foreach (string text in array) { Transform val4 = val2.Find(text); if (val4 != null) { val4.SetParent(val3, false); } } Transform val5 = val3.Find("cogling_dish"); if ((Object)(object)val5 == (Object)null) { MeshFilter component = ((Component)val2).GetComponent<MeshFilter>(); if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null || !Split(component.sharedMesh, val2.localScale)) { return; } BoxCollider component2 = ((Component)val2).GetComponent<BoxCollider>(); if (component2 != null) { component2.center = Vector3.Scale(component2.center, val2.localScale); component2.size = Vector3.Scale(component2.size, val2.localScale); } val2.localScale = Vector3.one; component.sharedMesh = _post; val5 = new GameObject("cogling_dish") { layer = ((Component)val2).gameObject.layer }.transform; val5.SetParent(val3, false); val5.localPosition = _pivot; ((Component)val5).gameObject.AddComponent<MeshFilter>().sharedMesh = _dish; ((Renderer)((Component)val5).gameObject.AddComponent<MeshRenderer>()).sharedMaterials = ((Renderer)((Component)val2).GetComponent<MeshRenderer>()).sharedMaterials; } else if ((Object)(object)_post != (Object)null && (Object)(object)_dish != (Object)null) { MeshFilter component3 = ((Component)val2).GetComponent<MeshFilter>(); if (component3 != null) { component3.sharedMesh = _post; } MeshFilter component4 = ((Component)val5).GetComponent<MeshFilter>(); if (component4 != null) { component4.sharedMesh = _dish; } } BoxCollider component5 = ((Component)val2).GetComponent<BoxCollider>(); if (component5 != null) { component5.size = new Vector3(0.3f, component5.size.y, 0.3f); } val5.localRotation = Quaternion.Euler(Plugin.DishTilt.Value, 0f, 0f); Transform val6 = val3.Find("cogling_hinge"); if ((Object)(object)val6 != (Object)null && val6.childCount != 4) { ((Component)val6).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)val6).gameObject); val6 = null; } if ((Object)(object)val6 == (Object)null) { Hinge(val3, ((Renderer)((Component)val2).GetComponent<MeshRenderer>()).sharedMaterials); } Transform val7 = val5.Find("cogling_lamp"); if (val7 != null) { val7.localPosition = LampAt(val5); Transform val8 = val7.Find("bulb"); if (val8 != null) { CentreBulb(val8); } } else { Lamp(val5); } antenna.GetComponent<AntennaLife>()?.Find(); } private static void Lamp(Transform dish) { //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: Expected O, but got Unknown //IL_0094: 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) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Expected O, but got Unknown ZNetScene instance = ZNetScene.instance; GameObject val = ((instance != null) ? instance.GetPrefab("dverger_demister") : null); Transform val2 = (((Object)(object)val != (Object)null) ? val.transform.Find("New") : null); Transform val3 = (((Object)(object)val != (Object)null) ? val.transform.Find("_enabled/demister_ball (1)") : null); if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null)) { GameObject val4 = new GameObject("cogling_lamp") { layer = ((Component)dish).gameObject.layer }; val4.transform.SetParent(dish, false); val4.transform.localPosition = LampAt(dish); val4.transform.localScale = Vector3.one * Plugin.AntennaLightSize.Value; Light val5 = val4.AddComponent<Light>(); val5.type = (LightType)2; val5.shadows = (LightShadows)0; val5.range = Plugin.AntennaLightRange.Value; val5.intensity = Plugin.AntennaLightBrightness.Value; val5.color = Plugin.EyeColor.Value; GameObject val6 = new GameObject("bulb") { layer = ((Component)dish).gameObject.layer }; val6.transform.SetParent(val4.transform, false); val6.transform.localScale = val3.lossyScale; val6.AddComponent<MeshFilter>().sharedMesh = ((Component)val3).GetComponent<MeshFilter>().sharedMesh; CentreBulb(val6.transform); MeshRenderer val7 = val6.AddComponent<MeshRenderer>(); if ((Object)(object)_bulbMaterial == (Object)null) { _bulbMaterial = new Material(((Renderer)((Component)val3).GetComponent<MeshRenderer>()).sharedMaterial) { name = "cogling_bulb" }; _bulbMaterial.EnableKeyword("_EMISSION"); } ((Renderer)val7).sharedMaterial = _bulbMaterial; ((Renderer)val7).shadowCastingMode = (ShadowCastingMode)0; } } private static Vector3 LampAt(Transform dish) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!_lampCentre.HasValue) { MeshFilter component = ((Component)dish).GetComponent<MeshFilter>(); _lampCentre = BowlCentre((component != null) ? component.sharedMesh : null); } return _lampCentre.Value + new Vector3(Plugin.AntennaLightSide.Value, Plugin.AntennaLightHeight.Value, Plugin.AntennaLightForward.Value); } private static void CentreBulb(Transform bulb) { //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) //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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) MeshFilter component = ((Component)bulb).GetComponent<MeshFilter>(); Mesh val = ((component != null) ? component.sharedMesh : null); if (!((Object)(object)val == (Object)null)) { Bounds bounds = val.bounds; bulb.localPosition = -Vector3.Scale(((Bounds)(ref bounds)).center, bulb.localScale); } } private static Vector3 BowlCentre(Mesh bowl) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bowl == (Object)null || !bowl.isReadable) { return Vector3.zero; } Vector3[] vertices = bowl.vertices; float top = vertices.Max((Vector3 p) => p.y); float bottom = vertices.Min((Vector3 p) => p.y); List<Vector3> source = vertices.Where((Vector3 p) => p.y > top - (top - bottom) * 0.1f).ToList(); float x = source.Average((Vector3 p) => p.x); float z = source.Average((Vector3 p) => p.z); float width = source.Max((Vector3 p) => Mathf.Sqrt((p.x - x) * (p.x - x) + (p.z - z) * (p.z - z))); x = 0.005f; z = 0.025f; List<Vector3> list = vertices.Where((Vector3 p) => Mathf.Sqrt((p.x - x) * (p.x - x) + (p.z - z) * (p.z - z)) < width * 0.15f).ToList(); float num = ((list.Count > 0) ? list.Max((Vector3 p) => p.y) : ((top + bottom) / 2f)); float num2 = 0.03f; Vector3 result = default(Vector3); ((Vector3)(ref result))..ctor(x, num + num2, z); return result; } internal static void ApplyLamp() { foreach (Transform item in from t in (from a in All where (Object)(object)a != (Object)null select ((Component)a).transform).Concat((IEnumerable<Transform>)(object)((!((Object)(object)Prefab != (Object)null)) ? new Transform[0] : new Transform[1] { Prefab.transform })) select t.Find("New/cogling_turn/cogling_dish") into d where (Object)(object)d != (Object)null select d) { Transform val = item.Find("cogling_lamp"); if (!((Object)(object)val == (Object)null)) { ((Component)val).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)val).gameObject); ((Object)val).name = "cogling_lamp_old"; Lamp(item); ((Component)item).GetComponentInParent<AntennaLife>()?.Find(); } } } private static void Hinge(Transform stand, Material[] wood) { //IL_0041: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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_0132: 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_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_cylinder == (Object)null) { GameObject val = GameObject.CreatePrimitive((PrimitiveType)2); _cylinder = val.GetComponent<MeshFilter>().sharedMesh; Object.DestroyImmediate((Object)(object)val); } Transform hinge = new GameObject("cogling_hinge") { layer = ((Component)stand).gameObject.layer }.transform; hinge.SetParent(stand, false); float num = 0.49f; float y = _pivot.y; Part("neck", new Vector3(0f, (num + y) / 2f, 0f), new Vector3(0.13f, y - num + 0.05f, 0.13f), Quaternion.identity); Part("pin", new Vector3(0f, y, 0f), new Vector3(0.08f, 0.34f, 0.08f), Quaternion.Euler(0f, 0f, 90f)); Part("knob_l", new Vector3(-0.17f, y, 0f), new Vector3(0.11f, 0.04f, 0.11f), Quaternion.Euler(0f, 0f, 90f)); Part("knob_r", new Vector3(0.17f, y, 0f), new Vector3(0.11f, 0.04f, 0.11f), Quaternion.Euler(0f, 0f, 90f)); void Part(string name, Vector3 at, Vector3 size, Quaternion turn) { //IL_0001: 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_001e: Expected O, but got Unknown //IL_0037: 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_004f: Unknown result type (might be due to invalid IL or missing references) //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_0067: Unknown result type (might be due to invalid IL or missing references) GameObject val2 = new GameObject(name) { layer = ((Component)stand).gameObject.layer }; val2.transform.SetParent(hinge, false); val2.transform.localPosition = at; val2.transform.localRotation = turn; val2.transform.localScale = new Vector3(size.x, size.y / 2f, size.z); val2.AddComponent<MeshFilter>().sharedMesh = _cylinder; ((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterials = wood; } } private static bool Split(Mesh source, Vector3 scale) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_0158: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_post != (Object)null) { return true; } if (!source.isReadable) { Plugin.Log.LogWarning((object)"The wisp light's mesh can't be read: its dish stays upright"); return false; } Vector3[] v = source.vertices; Vector3[] n = source.normals; Vector2[] uv = source.uv; int[] triangles = source.triangles; _pivot = Vector3.Scale(new Vector3(0f, 1.16f, 0f), scale); List<int> list = new List<int>(); List<int> list2 = new List<int>(); int num = 0; for (int i = 0; i < triangles.Length; i += 3) { float num2 = (v[triangles[i]].y + v[triangles[i + 1]].y + v[triangles[i + 2]].y) / 3f; if (num2 > 1.06f && num2 <= 1.16f) { num++; } ((num2 > 1.06f) ? list2 : list).AddRange(new int[3] { triangles[i], triangles[i + 1], triangles[i + 2] }); } Plugin.Log.LogInfo((object)$"Antenna: {num} triangle(s) of the dish's hub now turn with the dish (they stayed on the post before)"); _post = Part(list, Vector3.zero, "cogling_antenna_post"); _dish = Part(list2, _pivot, "cogling_antenna_dish"); return true; Mesh Part(List<int> part, Vector3 origin, string name) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) Dictionary<int, int> map = new Dictionary<int, int>(); List<Vector3> list3 = new List<Vector3>(); List<Vector3> list4 = new List<Vector3>(); List<Vector2> list5 = new List<Vector2>(); foreach (int item in part) { if (!map.ContainsKey(item)) { map[item] = list3.Count; list3.Add(Vector3.Scale(v[item], scale) - origin); if (n.Length == v.Length) { Vector3 val = new Vector3(n[item].x / scale.x, n[item].y / scale.y, n[item].z / scale.z); list4.Add(((Vector3)(ref val)).normalized); } if (uv.Length == v.Length) { list5.Add(uv[item]); } } } Mesh val2 = new Mesh { name = name }; val2.SetVertices(list3); if (list4.Count == list3.Count) { val2.SetNormals(list4); } if (list5.Count == list3.Count) { val2.SetUVs(0, list5); } val2.SetTriangles(part.Select((int key) => map[key]).ToList(), 0); if (list4.Count != list3.Count) { val2.RecalculateNormals(); } val2.RecalculateBounds(); ((Object)val2).hideFlags = (HideFlags)32; return val2; } } internal static void ApplyTilt() { if ((Object)(object)Prefab != (Object)null) { Shape(Prefab); } foreach (Antenna item in All) { if ((Object)(object)item != (Object)null) { Shape(((Component)item).gameObject); } } } } [HarmonyPatch] internal static class AntennaRule { private static readonly FieldRef<Player, GameObject> Ghost = AccessTools.FieldRefAccess<Player, GameObject>("m_placementGhost"); private static readonly FieldRef<Player, PlacementStatus> Status = AccessTools.FieldRefAccess<Player, PlacementStatus>("m_placementStatus"); private static string Problem(Player player, out GameObject ghost) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) ghost = Ghost.Invoke(player); if ((Object)(object)ghost == (Object)null || !ghost.activeSelf || Utils.GetPrefabName(ghost) != "cogling") { return null; } List<Antenna> list = Antenna.NetworkAt(ghost.transform.position); if (list.Count == 0) { return "$cogling_needs_antenna"; } int num = Antenna.CoglingsIn(list); int num2 = list.Count * Plugin.CoglingsPerAntenna.Value; if (num < num2) { return null; } return Translations.T("cogling_network_full", num, num2); } [HarmonyPostfix] [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] private static void Ghost_Postfix(Player __instance) { if ((int)Status.Invoke(__instance) == 0 && Problem(__instance, out var ghost) != null) { Status.Invoke(__instance) = (PlacementStatus)1; Piece component = ghost.GetComponent<Piece>(); if (component != null) { component.SetInvalidPlacementHeightlight(true); } } } [HarmonyPrefix] [HarmonyPatch(typeof(Player), "TryPlacePiece")] private static bool TryPlace_Prefix(Player __instance, Piece piece, ref bool __result) { if ((Object)(object)piece == (Object)null || ((Object)((Component)piece).gameObject).name != "cogling") { return true; } GameObject ghost; string text = Problem(__instance, out ghost); if (text == null) { return true; } ((Character)__instance).Message((MessageType)2, text, 0, (Sprite)null, false); __result = false; return false; } } internal sealed class AntennaLife : MonoBehaviour { private ZNetView _view; private Transform _turn; private Transform _dish; private Light _light; private Renderer _bulb; private MaterialPropertyBlock _block; private AudioSource _sound; private long _soundSlot = long.MinValue; private float _level = 1f; private float _nextLook; private Color _colour; private bool _near; private static AudioClip[] _creaks; private static AudioMixerGroup _mixer; private float _nextTwitch; private float _twitchYaw; private float _twitchTip; private float _toYaw; private float _toTip; private float _target = 1f; private void Start() { //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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Invalid comparison between Unknown and I4 //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown _view = ((Component)this).GetComponent<ZNetView>(); if ((Object)(object)_view == (Object)null || _view.GetZDO() == null) { ((Behaviour)this).enabled = false; return; } Find(); _colour = Plugin.EyeColor.Value; if ((int)SystemInfo.graphicsDeviceType != 4) { Creaks(); GameObject val = new GameObject("cogling_antenna_sound"); val.transform.SetParent(((Object)(object)_dish != (Object)null) ? _dish : ((Component)this).transform, false); _sound = val.AddComponent<AudioSource>(); _sound.outputAudioMixerGroup = _mixer; _sound.spatialBlend = 1f; _sound.rolloffMode = (AudioRolloffMode)1; _sound.minDistance = 1.5f; _sound.maxDistance = 18f; _sound.playOnAwake = false; } } private void OnDestroy() { if ((Object)(object)_sound != (Object)null) { Object.Destroy((Object)(object)((Component)_sound).gameObject); } } internal void Find() { _turn = ((Component)this).transform.Find("New/cogling_turn"); _dish = (((Object)(object)_turn != (Object)null) ? _turn.Find("cogling_dish") : null); Transform val = (((Object)(object)_dish != (Object)null) ? _dish.Find("cogling_lamp") : null); _light = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Light>() : null); _bulb = (Renderer)(object)(((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInChildren<MeshRenderer>(true) : null); } private static void Creaks() { if (_creaks != null) { return; } _creaks = (AudioClip[])(object)new AudioClip[0]; string[] array = new string[2] { "ashwood_door", "wood_door" }; foreach (string text in array) { ZNetScene instance = ZNetScene.instance; object obj; if (instance == null) { obj = null; } else { GameObject prefab = instance.GetPrefab(text); obj = ((prefab != null) ? prefab.GetComponent<Door>() : null); } Door val = (Door)obj; if (val?.m_openEffects?.m_effectPrefabs == null) { continue; } EffectData[] effectPrefabs = val.m_openEffects.m_effectPrefabs; foreach (EffectData val2 in effectPrefabs) { ZSFX val3 = (((Object)(object)val2?.m_prefab != (Object)null) ? val2.m_prefab.GetComponent<ZSFX>() : null); if (!((Object)(object)val3 == (Object)null) && val3.m_audioClips != null && val3.m_audioClips.Length != 0) { _creaks = val3.m_audioClips; AudioSource component = ((Component)val3).GetComponent<AudioSource>(); _mixer = ((component != null) ? component.outputAudioMixerGroup : null); return; } } } Plugin.Log.LogWarning((object)"No door sound to borrow: the antenna moves quietly"); } private void Update() { if ((Object)(object)_turn == (Object)null || (Object)(object)_dish == (Object)null) { Find(); if ((Object)(object)_turn == (Object)null || (Object)(object)_dish == (Object)null) { return; } } Move(); Twitch(); Lamp(); } private void Slot(long k, float every, out double start, out float yaw, out float tip) { //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) ZDOID uid = _view.GetZDO().m_uid; Random random = new Random((int)(((long)((ZDOID)(ref uid)).ID * 73856093L) ^ (((ZDOID)(ref uid)).UserID * 83492791) ^ (k * 19349663))); start = (double)k * (double)every + random.NextDouble() * (double)every * 0.6; float value = Plugin.AntennaTurn.Value; yaw = (float)(random.NextDouble() * 2.0 - 1.0) * value; tip = (float)(random.NextDouble() * 2.0 - 1.0) * Plugin.AntennaTip.Value; } private float MoveSeconds() { float num = Mathf.Max(0.3f, Plugin.AntennaSoundPitch.Value); float num2 = ((_creaks != null && _creaks.Length != 0) ? (_creaks[0].length / num) : 0.9f); return Mathf.Clamp(num2, 0.4f, 1.6f); } private void Move() { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) float num = 0f; float num2 = 0f; if (Plugin.AntennaMoves.Value && (Object)(object)ZNet.instance != (Object)null && _view.IsValid()) { float num3 = Mathf.Max(3f, Plugin.AntennaMoveEvery.Value); double timeSeconds = ZNet.instance.GetTimeSeconds(); long num4 = (long)Math.Floor(timeSeconds / (double)num3); Slot(num4, num3, out var start, out var yaw, out var tip); Slot(num4 - 1, num3, out var _, out var yaw2, out var tip2); float num5 = (float)((timeSeconds - start) / (double)MoveSeconds()); if (num5 >= 0f && num5 < 1f && _soundSlot != num4) { _soundSlot = num4; Creak(); } float num6 = Ease(Mathf.Clamp01(num5 * 1.4f)); float num7 = Ease(Mathf.Clamp01(num5 * 1.6f - 0.6f)); num = Mathf.LerpAngle(yaw2, yaw, num6); num2 = Mathf.Lerp(tip2, tip, num7); } _turn.localRotation = Quaternion.Euler(0f, num, 0f); _dish.localRotation = Quaternion.Euler(Plugin.DishTilt.Value + num2, 0f, 0f); } private void Twitch() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_010f: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) if (Time.time >= _nextTwitch) { _nextTwitch = Time.time + Random.Range(0.5f, 0.9f); bool flag = CoglingBody.FiddlingNear(((Component)this).transform.position, 2.2f); _toYaw = (flag ? Random.Range(-6f, 6f) : 0f); _toTip = (flag ? Random.Range(-4f, 4f) : 0f); if (flag && Random.value < 0.3f) { Creak(); } } _twitchYaw = Mathf.MoveTowards(_twitchYaw, _toYaw, Time.deltaTime * 60f); _twitchTip = Mathf.MoveTowards(_twitchTip, _toTip, Time.deltaTime * 40f); if (_twitchYaw != 0f || _twitchTip != 0f) { Transform turn = _turn; turn.localRotation *= Quaternion.Euler(0f, _twitchYaw, 0f); Transform dish = _dish; dish.localRotation *= Quaternion.Euler(_twitchTip, 0f, 0f); } } private static float Ease(float x) { if (!(x < 0.5f)) { return 1f - Mathf.Pow(-2f * x + 2f, 3f) / 2f; } return 4f * x * x * x; } private void Creak() { if (!((Object)(object)_sound == (Object)null) && _creaks != null && _creaks.Length != 0 && !(Plugin.AntennaSoundVolume.Value <= 0f)) { _sound.pitch = Plugin.AntennaSoundPitch.Value; _sound.volume = Plugin.AntennaSoundVolume.Value; _sound.PlayOneShot(_creaks[Random.Range(0, _creaks.Length)]); } } private void Lamp() { //IL_0087: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0191: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) bool value = Plugin.AntennaLight.Value; if ((Object)(object)_light == (Object)null || (Object)(object)_bulb == (Object)null) { return; } if (((Component)_light).gameObject.activeSelf != value) { ((Component)_light).gameObject.SetActive(value); } if (!value) { return; } if (Time.time >= _nextLook) { _nextLook = Time.time + 0.5f; Camera mainCamera = Utils.GetMainCamera(); _near = (Object)(object)mainCamera != (Object)null && Vector3.Distance(((Component)mainCamera).transform.position, ((Component)this).transform.position) < 45f; if (CoglingBody.EyesNear(((Component)this).transform.position, Antenna.Radius, out var colour, out var level)) { _colour = colour; _target = Mathf.Max(0.2f, level); } else { _colour = Plugin.EyeColor.Value; _target = 1f; } } _level = Mathf.MoveTowards(_level, _target, Time.deltaTime * 1.5f); ((Behaviour)_light).enabled = _near && Plugin.AntennaLightBrightness.Value > 0f; _light.color = _colour; _light.intensity = Plugin.AntennaLightBrightness.Value * _level; _light.range = Plugin.AntennaLightRange.Value; ((Component)_light).transform.localScale = Vector3.one * Plugin.AntennaLightSize.Value; if (_block == null) { _block = new MaterialPropertyBlock(); } _bulb.GetPropertyBlock(_block); _block.SetColor("_Color", _colour); _block.SetColor("_EmissionColor", _colour * Mathf.Max(0.5f, Plugin.EyeGlow.Value) * _level); _bulb.SetPropertyBlock(_block); } } [HarmonyPatch(typeof(Piece), "SetCreator")] internal static class BuiltHook { private static void Postfix(Piece __instance) { CoglingSlack.Built(__instance); } } [HarmonyPatch(typeof(Container), "Awake")] internal static class Chests { private static readonly List<Container> All = new List<Container>(); private static void Postfix(Container __instance) { All.Add(__instance); } internal static void FindLoaded() { All.Clear(); All.AddRange(Object.FindObjectsByType<Container>((FindObjectsSortMode)0)); } internal static void Forget() { All.Clear(); } internal static List<Container> Stored(List<Antenna> network) { All.RemoveAll((Container c) => (Object)(object)c == (Object)null); return All.Where((Container c) => Antenna.InArea(network, ((Component)c).transform.position) && ContainerAccess.IsStorage(c)).ToList(); } internal static List<Container> Usable(List<Antenna> network) { All.RemoveAll((Container c) => (Object)(object)c == (Object)null); return All.Where((Container c) => Antenna.InArea(network, ((Component)c).transform.position) && ContainerAccess.IsStorage(c) && !ContainerAccess.InUse(c) && ContainerAccess.MayUse(c)).ToList(); } } internal static class FloorItems { private static readonly FieldRef<List<ItemDrop>> Instances = AccessTools.StaticFieldRefAccess<List<ItemDrop>>(AccessTools.Field(typeof(ItemDrop), "s_instances")); private static readonly MethodInfo EggCanGrow = AccessTools.Method(typeof(EggGrow), "CanGrow", (Type[])null, (Type[])null); private static readonly Dictionary<ZDOID, float> FirstSeen = new Dictionary<ZDOID, float>(); private static readonly Dictionary<ZDOID, float> ColdSince = new Dictionary<ZDOID, float>(); private static readonly Dictionary<ZDOID, float> NoHomeUntil = new Dictionary<ZDOID, float>(); internal static readonly HashSet<ZDOID> Claimed = new HashSet<ZDOID>(); private static readonly int Below = LayerMask.GetMask(new string[5] { "piece", "Default", "static_solid", "Default_small", "terrain" }); private static readonly Dictionary<ZDOID, int> NoWayCount = new Dictionary<ZDOID, int>(); private static List<Character> Enemies() { Character me = (Character)(object)Player.m_localPlayer; return (from c in Character.GetAllCharacters() where (Object)(object)c != (Object)null && !c.IsDead() && !c.IsPlayer() && (int)c.GetFaction() != 1 && !CoglingStance.IsCogling(c) && !CoglingDanger.Built(c) && ((!((Object)(object)me != (Object)null)) ? ((int)c.GetFaction() > 0) : BaseAI.IsEnemy(me, c)) select c).ToList(); } private static string FightNear(ItemDrop d, List<Character> enemies) { return ((IEnumerable<Character>)enemies).FirstOrDefault((Func<Character, bool>)delegate(Character e) { //IL_0006: 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) float num = Vector3.Distance(((Component)e).transform.position, ((Component)d).transform.position); return num < 8f || (num < 20f && (Object)(object)e.GetBaseAI() != (Object)null && e.GetBaseAI().IsAlerted()); })?.m_name; } private static float Age(ItemDrop d, ZDOID id) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) ZNetView component = ((Component)d).GetComponent<ZNetView>(); ZDO val = ((component != null) ? component.GetZDO() : null); long num = ((val != null) ? val.GetLong(ZDOVars.s_spawnTime, 0L) : 0); if (num > 0 && (Object)(object)ZNet.instance != (Object)null) { return (float)(ZNet.instance.GetTime() - new DateTime(num)).TotalSeconds; } if (!FirstSeen.TryGetValue(id, out var value)) { value = (FirstSeen[id] = Time.time); } return Time.time - value; } internal static int Load(ItemData item) { float weight = item.m_shared.m_weight; if (weight <= 0.0001f) { return item.m_stack; } return Mathf.Clamp(Mathf.FloorToInt(Plugin.MaxCarryWeight.Value / weight), 1, item.m_stack); } internal static ZDOID Id(ItemDrop d) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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) ZNetView component = ((Component)d).GetComponent<ZNetView>(); return (ZDOID)(((??)((component == null) ? ((ZDOID?)null) : component.GetZDO()?.m_uid)) ?? ZDOID.None); } internal static void NoHome(ItemDrop d, float seconds = 90f) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) NoHomeUntil[Id(d)] = Time.time + seconds; } internal static float NoWay(ItemDrop d) { //IL_0001: 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: 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) ZDOID key = Id(d); NoWayCount.TryGetValue(key, out var value); float num = (NoWayCount[key] = value + 1) switch { 2 => 30f, 1 => 10f, _ => 120f, }; NoHome(d, num); return num; } internal static List<ItemDrop> Candidates(List<Antenna> network, Vector3 from) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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) float time = Time.time; List<ItemDrop> list = new List<ItemDrop>(); List<Character> enemies = Enemies(); foreach (ItemDrop item in Instances.Invoke()) { if (!((Object)(object)item == (Object)null) && Antenna.InArea(network, ((Component)item).transform.position)) { ZDOID val = Id(item); if (!(val == ZDOID.None) && !Claimed.Contains(val) && Allowed(item, val, Age(item, val)) && FightNear(item, enemies) == null) { list.Add(item); } } } if (FirstSeen.Count > 2000) { Prune(); } return list.OrderBy((ItemDrop d) => Vector3.Distance(((Component)d).transform.position, from)).ToList(); } private static bool Allowed(ItemDrop d, ZDOID id, float age) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return WhyNot(d, id, age) == null; } private static string WhyNot(ItemDrop d, ZDOID id, float age) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) if (NoHomeUntil.TryGetValue(id, out var value) && Time.time < value) { return $"no chest for it or out of reach (tries again in {value - Time.time:F0} s)"; } if (age < Plugin.DropWait.Value) { return $"freshly dropped ({Plugin.DropWait.Value - age:F0} s to wait)"; } if (d.IsPiece()) { return "placed with the build menu"; } ItemData itemData = d.m_itemData; if (itemData == null || itemData.m_shared.m_weight > Plugin.MaxCarryWeight.Value) { return $"too heavy (one weighs {itemData?.m_shared.m_weight:F0}: the dragon egg)"; } Vector3 at = ((Component)d).transform.position; if (Floating.GetLiquidLevel(at, 1f, (LiquidType)0) > at.y + 0.05f) { return "in water"; } if (Player.GetAllPlayers().Any((Player p) => Vector3.Distance(((Component)p).transform.position, at) < 2f)) { return "a player is next to it"; } if (!PrivateArea.CheckAccess(at, 0f, false, false)) { return "inside a ward you can't use"; } if (OnFurniture(d)) { return "on furniture (a decoration)"; } EggGrow component = ((Component)d).GetComponent<EggGrow>(); if (component != null && !ColdEggReady(component, id)) { return "an egg: warm, or not cold for long enough yet"; } return null; } internal static List<ItemDrop> Near(Vector3 at, float within, ItemData like) { //IL_0041: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) List<ItemDrop> list = new List<ItemDrop>(); foreach (ItemDrop item in Instances.Invoke()) { if (!((Object)(object)item == (Object)null) && item.m_itemData != null && !(Vector3.Distance(((Component)item).transform.position, at) > within) && !(item.m_itemData.m_shared.m_name != like.m_shared.m_name) && item.m_itemData.m_quality == like.m_quality) { ZDOID val = Id(item); if (!(val == ZDOID.None) && !Claimed.Contains(val) && WhyNot(item, val, Age(item, val)) == null) { list.Add(item); } } } return list; } private static bool OnFurniture(ItemDrop d) { //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_0015: 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_001f: 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) //IL_0056: Invalid comparison between Unknown and I4 //IL_0059: 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_0065: Invalid comparison between Unknown and I4 RaycastHit val = default(RaycastHit); if (!Physics.Raycast(((Component)d).transform.position + Vector3.up * 0.2f, Vector3.down, ref val, 1.5f, Below)) { return false; } Piece componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Piece>(); if ((Object)(object)componentInParent != (Object)null) { if ((int)componentInParent.m_category != 4) { return (componentInParent.m_usage & 0x80) > 0; } return true; } return false; } private static bool ColdEggReady(EggGrow egg, ZDOID id) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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 ((EggCanGrow != null && (bool)EggCanGrow.Invoke(egg, null)) || !Plugin.CollectColdEggs.Value) { ColdSince.Remove(id); return false; } if (!ColdSince.TryGetValue(id, out var value)) { ColdSince[id] = Time.time; return false; } return Time.time - value >= Plugin.ColdEggWait.Value * 60f; } private static void Prune() { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) HashSet<ZDOID> live = new HashSet<ZDOID>((from d in Instances.Invoke() where (Object)(object)d != (Object)null select d).Select(Id)); Dictionary<ZDOID, float>[] array = new Dictionary<ZDOID, float>[3] { FirstSeen, ColdSince, NoHomeUntil }; foreach (Dictionary<ZDOID, float> dictionary in array) { foreach (ZDOID item in dictionary.Keys.Where((ZDOID k) => !live.Contains(k)).ToList()) { dictionary.Remove(item); } } } internal static void Forget() { FirstSeen.Clear(); ColdSince.Clear(); NoHomeUntil.Clear(); NoWayCount.Clear(); Claimed.Clear(); } } internal sealed class CoglingAI : BaseAI { private enum Mode { Resting, Strolling, GoingHome, Working, Returning, Slacking } private float _nextReturnPlan; private CoglingNavigator _nav; private CoglingJob _job; private CoglingDanger _danger; private CoglingSlack _slack; internal bool Running; internal float WalkScale = 1f; internal float RunScale = 1f; private float _nextJobLook; private float _nextTidy; private Mode _mode = Mode.GoingHome; private float _nextStroll; private Vector3 _home; private bool _haveHome; private static readonly string[] Rpcs = new string[5] { "Alert", "OnNearProjectileHit", "SetAggravated", "RPC_Wakeup", "RPC_Sleep" }; private static readonly MethodInfo BaseOnDestroy = AccessTools.Method(typeof(BaseAI), "OnDestroy", (Type[])null, (Type[])null); private static readonly FieldRef<Character, BaseAI> CharacterAI = AccessTools.FieldRefAccess<Character, BaseAI>("m_baseAI"); private bool _duplicate; private float _nextHomeCheck; private float _nextNetwork; private List<Antenna> _network = new List<Antenna>(); private float _lastUpdate; private float _deadSince = -1f; private readonly Dictionary<CoglingVoice.Line, float> _saidAt = new Dictionary<CoglingVoice.Line, float>(); private float _holdUntil; private float _lastSaid; private float _nextPlayerLook; private float _waveAt = -1f; private float _faceWaverUntil; private float _waveGiveUp; private Vector3 _waver; private float _calledUntil; private Vector3 _callSpot; private Vector3 _caller; private bool _gathered; private const string SeenKey = "cogling_seen"; private bool _welcomeAfterBoot; private float _nextSeenWrite; private float _restingSince; private float _bootUntil; internal Character Going; private bool _homeAfterFright; private float _greetUntil; priva