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 Good Tidings v1.0.0
plugins/GoodTidings.dll
Decompiled 2 weeks 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.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using HeaveHo.Shared; using Microsoft.CodeAnalysis; using Newtonsoft.Json.Linq; using Nick.Shared; using Splatform; using TMPro; using UnityEngine; using UnityEngine.Animations; using UnityEngine.Audio; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.Playables; using UnityEngine.Rendering; using UnityEngine.UI; [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", "menu")] [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; } } } internal sealed class ConfigurationManagerAttributes { public bool? IsAdvanced; public int? Order; public Action<ConfigEntryBase> CustomDrawer; public bool? HideDefaultButton; public bool? HideSettingName; public bool? ReadOnly; public bool? Browsable; public string Category; public string DispName; public string Description; } 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 GoodTidings { internal sealed class BountifulSeason : Visit { internal const float Radius = 96f; private const float Rescan = 5f; private const float EffectSpacing = 3f; private const float ParticleSpeed = 0.35f; private static bool _running; private static bool _stop; private static readonly Color Wisp = new Color(0.45f, 1f, 0.5f); public override string Id => "bountiful"; public override bool Enabled => Plugin.BountifulEnabled.Value; internal static bool Running => _running; public override bool Start(Vector3 basePoint) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (_running) { return false; } ZPackage val = new ZPackage(); val.Write(basePoint); val.Write(Plugin.BountifulMinutes.Value * 60f); val.Write(Plugin.BountifulSpeed.Value); val.Write(Plugin.BountifulHeadStart.Value * 60f); val.Write(Plugin.BountifulGrowSpeed.Value); ZRoutedRpc.instance.InvokeRoutedRPC(0L, "GoodTidings_Bountiful", new object[1] { val }); Plugin.Log.LogInfo((object)$"Bountiful season at {basePoint} for {Plugin.BountifulMinutes.Value} minutes at {Plugin.BountifulSpeed.Value}x"); return true; } internal static void OnRpc(long sender, ZPackage pkg) { //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_004f: Unknown result type (might be due to invalid IL or missing references) Vector3 center = pkg.ReadVector3(); float seconds = pkg.ReadSingle(); float num = pkg.ReadSingle(); float headStart = ((pkg.GetPos() < pkg.Size()) ? pkg.ReadSingle() : 0f); float growSpeed = ((pkg.GetPos() < pkg.Size()) ? pkg.ReadSingle() : num); ((MonoBehaviour)Plugin.Instance).StartCoroutine(Run(center, seconds, num, headStart, growSpeed)); } internal static void Stop() { _stop = true; } private static IEnumerator Run(Vector3 center, float seconds, float speed, float headStart, float growSpeed) { //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) _running = true; _stop = false; Dictionary<Component, GameObject> effects = new Dictionary<Component, GameObject>(); List<Vector3> spots = new List<Vector3>(); bool near = (Object)(object)Player.m_localPlayer != (Object)null && Utils.DistanceXZ(((Component)Player.m_localPlayer).transform.position, center) < 176f; if (near) { MessageHud.instance.ShowMessage((MessageType)2, Lines.Pick("goodtidings_bountiful"), 0, (Sprite)null, false, true); Effect("sfx_staff_elder_grow", center); } MapPins pins = new MapPins(); float end = Time.time + seconds; float nextScan = 0f; float last = Time.time; List<Component> targets = new List<Component>(); HashSet<Component> started = new HashSet<Component>(); while (Time.time < end && !_stop) { if (Time.time >= nextScan) { nextScan = Time.time + 5f; targets = Find(center); if (near) { foreach (Component item in targets) { if (Object.op_Implicit((Object)(object)item) && !effects.ContainsKey(item)) { Vector3 at = item.transform.position; bool flag = spots.Any((Vector3 s) => Vector3.Distance(s, at) < 3f); effects[item] = (flag ? null : Glow(at, end - Time.time)); if (!flag) { spots.Add(at); } } } } } float num = Time.time - last; last = Time.time; float num2 = num * (speed - 1f); float num3 = num * (growSpeed - 1f); foreach (Component item2 in targets) { if (!((Object)(object)item2 == (Object)null)) { bool flag2 = item2 is Plant || item2 is Beehive; float num4 = ((flag2 && started.Add(item2)) ? headStart : 0f); try { Boost(item2, (flag2 ? num3 : num2) + num4); } catch (Exception ex) { Plugin.Debug("Bountiful season on " + ((Object)item2).name + ": " + ex.Message); } } } pins.Update(center, center, "", withIcon: false); yield return (object)new WaitForSeconds(1f); } pins.Remove(); foreach (GameObject value in effects.Values) { if (Object.op_Implicit((Object)(object)value)) { Fade(value); } } if (near && !_stop) { MessageHud.instance.ShowMessage((MessageType)1, "$goodtidings_bountiful_end", 0, (Sprite)null, false, true); } _running = false; } private static List<Component> Find(Vector3 center) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) HashSet<Component> hashSet = new HashSet<Component>(); Collider[] array = Physics.OverlapSphere(center, 96f, -1, (QueryTriggerInteraction)2); foreach (Collider val in array) { Component val2 = (Component)(((Component)val).GetComponentInParent<Plant>() ?? ((Component)val).GetComponentInParent<Beehive>() ?? ((Component)val).GetComponentInParent<Fermenter>() ?? ((object)((Component)val).GetComponentInParent<Smelter>()) ?? ((object)((Component)val).GetComponentInParent<CookingStation>())); if ((Object)(object)val2 != (Object)null) { hashSet.Add(val2); } } return hashSet.ToList(); } private static void Boost(Component t, float extra) { ZNetView componentInParent = t.GetComponentInParent<ZNetView>(); if ((Object)(object)componentInParent == (Object)null || !componentInParent.IsValid() || !componentInParent.IsOwner()) { return; } ZDO zDO = componentInParent.GetZDO(); long ticks = TimeSpan.FromSeconds(extra).Ticks; long ticks2 = ZNet.instance.GetTime().Ticks; if (!(t is Plant)) { if (!(t is Beehive)) { if (!(t is Fermenter)) { if (!(t is Smelter)) { CookingStation val = (CookingStation)(object)((t is CookingStation) ? t : null); if (val == null) { return; } for (int i = 0; i < val.m_slots.Length; i++) { string item = zDO.GetString("slot" + i, ""); ItemConversion val2 = ((item == "") ? null : ((IEnumerable<ItemConversion>)val.m_conversion).FirstOrDefault((Func<ItemConversion, bool>)((ItemConversion x) => Object.op_Implicit((Object)(object)x.m_from) && ((Object)x.m_from).name == item))); if (val2 != null) { float num = zDO.GetFloat("slot" + i, 0f); if (num < val2.m_cookTime - 0.05f) { zDO.Set("slot" + i, Mathf.Min(num + extra, val2.m_cookTime - 0.05f)); } } } } else { zDO.Set(ZDOVars.s_startTime, zDO.GetLong(ZDOVars.s_startTime, ticks2) - ticks); } } else { long num2 = zDO.GetLong(ZDOVars.s_startTime, 0L); if (num2 != 0L) { zDO.Set(ZDOVars.s_startTime, num2 - ticks); } } } else { zDO.Set(ZDOVars.s_lastTime, zDO.GetLong(ZDOVars.s_lastTime, ticks2) - ticks); } } else { zDO.Set(ZDOVars.s_plantTime, zDO.GetLong(ZDOVars.s_plantTime, ticks2) - ticks); } } private static GameObject Glow(Vector3 at, float seconds) { //IL_0005: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) GameObject val = LocalFx.Spawn("vfx_prespawn", at, Quaternion.identity, null, 0f); if ((Object)(object)val == (Object)null) { return null; } ParticleSystem[] componentsInChildren = val.GetComponentsInChildren<ParticleSystem>(); foreach (ParticleSystem val2 in componentsInChildren) { MainModule main = val2.main; ((MainModule)(ref main)).simulationSpeed = 0.35f; ((MainModule)(ref main)).loop = true; ((MainModule)(ref main)).startColor = Blue(((MainModule)(ref main)).startColor); ColorOverLifetimeModule colorOverLifetime = val2.colorOverLifetime; if (((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled) { ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = Blue(((ColorOverLifetimeModule)(ref colorOverLifetime)).color); } } Light[] componentsInChildren2 = val.GetComponentsInChildren<Light>(); foreach (Light val3 in componentsInChildren2) { val3.color = Wisp; } AudioSource[] componentsInChildren3 = val.GetComponentsInChildren<AudioSource>(); foreach (AudioSource val4 in componentsInChildren3) { ((Behaviour)val4).enabled = false; } Object.Destroy((Object)(object)val, seconds + 10f); return val; } private static MinMaxGradient Blue(MinMaxGradient g) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected I4, but got Unknown //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) ParticleSystemGradientMode mode = ((MinMaxGradient)(ref g)).mode; return (MinMaxGradient)((int)mode switch { 0 => new MinMaxGradient(Blue(((MinMaxGradient)(ref g)).color)), 2 => new MinMaxGradient(Blue(((MinMaxGradient)(ref g)).colorMin), Blue(((MinMaxGradient)(ref g)).colorMax)), 1 => new MinMaxGradient(Blue(((MinMaxGradient)(ref g)).gradient)), 3 => new MinMaxGradient(Blue(((MinMaxGradient)(ref g)).gradientMin), Blue(((MinMaxGradient)(ref g)).gradientMax)), _ => g, }); } private static Gradient Blue(Gradient g) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown if (g == null) { return null; } GradientColorKey[] array = ((IEnumerable<GradientColorKey>)g.colorKeys).Select((Func<GradientColorKey, GradientColorKey>)((GradientColorKey k) => new GradientColorKey(Blue(k.color), k.time))).ToArray(); Gradient val = new Gradient(); val.SetKeys(array, g.alphaKeys); return val; } private static Color Blue(Color c) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(new float[3] { c.r, c.g, c.b }); return new Color(Wisp.r * num, Wisp.g * num, Wisp.b * num, c.a); } private static void Fade(GameObject g) { ParticleSystem[] componentsInChildren = g.GetComponentsInChildren<ParticleSystem>(); foreach (ParticleSystem val in componentsInChildren) { val.Stop(true, (ParticleSystemStopBehavior)1); } Object.Destroy((Object)(object)g, 6f); } private static void Effect(string prefab, Vector3 at) { //IL_0015: 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) GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab); if (Object.op_Implicit((Object)(object)prefab2)) { Object.Instantiate<GameObject>(prefab2, at, Quaternion.identity); } } } internal static class Commands { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__3_0; public static Func<Visit, string> <>9__5_1; internal void <Register>b__3_0(ConsoleEventArgs args) { Run(args.Context, args.Args); } internal string <Run>b__5_1(Visit v) { return v.Id; } } private const string Command = "goodtidings"; private const string Usage = "goodtidings visit [trader|bountiful|muninn|dverger|skald] | goodtidings found"; private static readonly FieldRef<Dictionary<string, ConsoleCommand>> TerminalCommands = AccessTools.StaticFieldRefAccess<Dictionary<string, ConsoleCommand>>(AccessTools.Field(typeof(Terminal), "commands")); internal static void Register() { //IL_0033: 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) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown object obj = <>c.<>9__3_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { Run(args.Context, args.Args); }; <>c.<>9__3_0 = val; obj = (object)val; } new ConsoleCommand("goodtidings", "Good Tidings: goodtidings visit [trader|bountiful|muninn|dverger|skald] | goodtidings found", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } internal static void Unregister() { TerminalCommands.Invoke().Remove("goodtidings"); } private static void Run(Terminal t, string[] a) { string text = ((a.Length > 1) ? a[1].ToLowerInvariant() : ""); Player localPlayer = Player.m_localPlayer; if (!(text == "visit")) { if (text == "found") { Stock.Rebuild(); List<StockDiscovery.Found> list = Stock.FoundNow(); t.AddString("Stock file: " + StockFile.FilePath + (Plugin.Synced.TextFromServer("Stock") ? " (the server's applies)" : "") + "; " + string.Format("{0} added, {1} removed, finding other mods' items {2}.", StockFile.Adds.Count, StockFile.Removed.Count, StockFile.FindOtherMods ? "on" : "off")); t.AddString("Always: " + string.Join(", ", Stock.AlwaysNames())); t.AddString((list.Count == 0) ? "No other mods' items found." : $"{list.Count} other mods' items found:"); { foreach (StockDiscovery.Found item in list) { string[] obj = new string[6] { " ", item.Item, " (", null, null, null }; Localization instance = Localization.instance; GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item.Item); obj[3] = instance.Localize(((itemPrefab == null) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_name) ?? "?"); obj[4] = "): "; obj[5] = $"{item.Slot} of the {Stock.LandNames[item.Land]}, {item.Stack} for {item.Price}, {item.From}"; t.AddString(string.Concat(obj)); } return; } } t.AddString("goodtidings visit [trader|bountiful|muninn|dverger|skald] | goodtidings found"); return; } if ((Object)(object)ZNet.instance == (Object)null || (!ZNet.instance.IsServer() && !((Terminal)Console.instance).IsCheatsEnabled())) { t.AddString("Host or devcommands only."); return; } string only = ((a.Length > 2) ? a[2].ToLowerInvariant() : null); if (only != null && !Visits.All.Any((Visit v) => v.Id == only)) { t.AddString("No visit called " + only + ": " + string.Join(", ", Visits.All.Select((Visit v) => v.Id)) + "."); } else if (Visits.TryStart(only)) { t.AddString("Visit started."); } else if ((Object)(object)localPlayer != (Object)null && localPlayer.GetBaseValue() < 3) { t.AddString($"Not at a base here (base value {localPlayer.GetBaseValue()}, visits need 3): go home first."); } else if (TraderVisitor.Count > 0 && (only == null || only == "trader")) { t.AddString("Dagny is still here: one at a time."); } else if (MuninnVisitor.Count > 0 && (only == null || only == "muninn")) { t.AddString("Muninn is still here (he leaves a few seconds after an answer): try again in a moment."); } else if (SkaldVisitor.Count > 0 && (only == null || only == "skald")) { t.AddString("The skald is still playing here."); } else if (DvergerVisitor.Count > 0 && (only == null || only == "dverger")) { t.AddString("The wounded Dvergr is still here."); } else if (BountifulSeason.Running && (only == null || only == "bountiful")) { t.AddString("A bountiful season is already going on."); } else if (only != null && !Visits.All.First((Visit v) => v.Id == only).Enabled) { t.AddString(only + " is switched off in the settings."); } else { t.AddString("No visit could start here (no open ground near the base?)."); } } } internal static class Cuts { internal sealed class Tint { public float Hue; public float Saturation; public float Value = 1f; public bool Grey; public List<RectInt> Keep = new List<RectInt>(); public List<RectInt> Black = new List<RectInt>(); public List<RectInt> Cut = new List<RectInt>(); public override string ToString() { return string.Format("{0:0.00},{1:0.00},{2:0.00},{3},{4},{5},{6}", Hue, Saturation, Value, Grey, string.Join("/", Keep), string.Join("/", Black), string.Join("/", Cut)); } } internal static readonly Dictionary<string, List<RectInt>> BySuit = new Dictionary<string, List<RectInt>>(); internal static int Grid; private static readonly Dictionary<string, Material> Made = new Dictionary<string, Material>(); internal static readonly Color[] GridColours = (Color[])(object)new Color[16] { Color.red, Color.green, Color.blue, Color.yellow, Color.cyan, Color.magenta, Color.white, Color.black, new Color(1f, 0.5f, 0f), new Color(0.5f, 0f, 1f), new Color(1f, 0.6f, 0.8f), new Color(0.45f, 0.25f, 0.1f), Color.grey, new Color(0.6f, 1f, 0.2f), new Color(0f, 0f, 0.4f), new Color(0f, 0.5f, 0.5f) }; internal static Material MaterialFor(Material source, string suit, Tint tint = null) { //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030a: 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_015a: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) BySuit.TryGetValue(suit, out var value); if (Grid == 0 && (value == null || value.Count == 0) && tint == null) { return source; } string key = suit + "|" + Grid + "|" + string.Join(";", value ?? new List<RectInt>()) + "|" + tint; if (Made.TryGetValue(key, out var value2) && Object.op_Implicit((Object)(object)value2)) { return value2; } Texture2D val = Readable(source.mainTexture); if ((Object)(object)val == (Object)null) { return source; } Color32[] pixels = val.GetPixels32(); int width = ((Texture)val).width; int height = ((Texture)val).height; if (tint != null) { float num = default(float); float num2 = default(float); float num3 = default(float); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { Vector2Int at = new Vector2Int(j, i); Color32 val2 = pixels[i * width + j]; if (tint.Cut.Exists((RectInt r) => ((RectInt)(ref r)).Contains(at))) { pixels[i * width + j].a = 0; } else if (!tint.Keep.Exists((RectInt r) => ((RectInt)(ref r)).Contains(at))) { Color.RGBToHSV(Color32.op_Implicit(val2), ref num, ref num2, ref num3); Color val3 = (tint.Black.Exists((RectInt r) => ((RectInt)(ref r)).Contains(at)) ? Color.HSVToRGB(0f, 0f, num3 * 0.3f) : (tint.Grey ? Color.HSVToRGB(0f, 0f, Mathf.Clamp01(num3 * tint.Value)) : Color.HSVToRGB(tint.Hue, Mathf.Max(num2, tint.Saturation), Mathf.Clamp01(num3 * tint.Value)))); pixels[i * width + j] = new Color32((byte)(val3.r * 255f), (byte)(val3.g * 255f), (byte)(val3.b * 255f), val2.a); } } } } if (Grid > 0) { for (int num4 = 0; num4 < height; num4++) { for (int num5 = 0; num5 < width; num5++) { int num6 = num4 * Grid / height * Grid + num5 * Grid / width; Color val4 = Color.Lerp(Color32.op_Implicit(pixels[num4 * width + num5]), GridColours[num6 % GridColours.Length], 0.75f); pixels[num4 * width + num5] = new Color32((byte)(val4.r * 255f), (byte)(val4.g * 255f), (byte)(val4.b * 255f), pixels[num4 * width + num5].a); } } } if (value != null) { foreach (RectInt item in value) { RectInt current = item; for (int num7 = Mathf.Max(0, ((RectInt)(ref current)).yMin); num7 < Mathf.Min(height, ((RectInt)(ref current)).yMax); num7++) { for (int num8 = Mathf.Max(0, ((RectInt)(ref current)).xMin); num8 < Mathf.Min(width, ((RectInt)(ref current)).xMax); num8++) { pixels[num7 * width + num8].a = 0; } } } } val.SetPixels32(pixels); val.Apply(); value2 = new Material(source) { name = ((Object)source).name + "_goodtidings", mainTexture = (Texture)(object)val }; return Made[key] = value2; } internal static void Clear() { foreach (Material value in Made.Values) { if (Object.op_Implicit((Object)(object)value)) { Object.Destroy((Object)(object)value.mainTexture); Object.Destroy((Object)(object)value); } } Made.Clear(); } internal static Texture2D Readable(Texture source) { //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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); Graphics.Blit(source, temporary); RenderTexture active = RenderTexture.active; RenderTexture.active = temporary; Texture2D val = new Texture2D(source.width, source.height, (TextureFormat)4, false) { filterMode = source.filterMode, wrapMode = source.wrapMode }; val.ReadPixels(new Rect(0f, 0f, (float)source.width, (float)source.height), 0, 0); val.Apply(); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); return val; } } internal sealed class DvergerVisit : Visit { private static int _blockMask; public override string Id => "dverger"; public override bool Enabled => Plugin.DvergerEnabled.Value; public override bool Start(Vector3 basePoint) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) if (DvergerVisitor.Count > 0) { Plugin.Debug("A wounded Dvergr is already here"); return false; } GameObject prefab = ZNetScene.instance.GetPrefab("goodtidings_dverger"); if ((Object)(object)prefab == (Object)null || !FindGround(basePoint, 10f, 18f, out var at) || !FindGround(basePoint, 35f, 45f, out var at2)) { return false; } Vector3 val = at - at2; val.y = 0f; GameObject val2 = Object.Instantiate<GameObject>(prefab, at2, (((Vector3)(ref val)).sqrMagnitude > 0.01f) ? Quaternion.LookRotation(val) : Quaternion.identity); ZDO zDO = val2.GetComponent<ZNetView>().GetZDO(); zDO.Set("GoodTidings.LeaveAt", ZNet.instance.GetTime().Ticks + TimeSpan.FromMinutes(Plugin.DvergerMinutes.Value).Ticks); zDO.Set("GoodTidings.KneelAt", at); val2.GetComponent<DvergerAI>().SetHome(basePoint); Net.MessageAll((MessageType)2, "$goodtidings_dverger_arrives"); Plugin.Log.LogInfo((object)$"A wounded Dvergr staggers in from {at2} to {at}, by the base at {basePoint}"); return true; } private static bool FindGround(Vector3 home, float min, float max, out Vector3 at) { //IL_004e: 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) //IL_0057: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) if (_blockMask == 0) { _blockMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "vehicle", "character" }); } float num = default(float); for (int i = 0; i < 60; i++) { Vector2 insideUnitCircle = Random.insideUnitCircle; Vector2 val = ((Vector2)(ref insideUnitCircle)).normalized * Random.Range(min, max); Vector3 val2 = home + new Vector3(val.x, 0f, val.y); if (ZoneSystem.instance.GetSolidHeight(val2, ref num, 1000) && !(num < ZoneSystem.instance.m_waterLevel + 0.3f) && !(Mathf.Abs(num - ZoneSystem.instance.GetGroundHeight(val2)) > 0.3f)) { val2.y = num; if (!Physics.CheckSphere(val2 + Vector3.up * 1.2f, 1f, _blockMask, (QueryTriggerInteraction)1)) { at = val2 + Vector3.up * 0.2f; return true; } } } at = Vector3.zero; return false; } } internal static class DvergerPrefab { [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetScene_Awake { private static void Postfix(ZNetScene __instance) { Register(__instance); } } internal const string Name = "goodtidings_dverger"; private static GameObject _holder; private static GameObject _prefab; private static readonly FieldRef<ZNetScene, Dictionary<int, GameObject>> NamedPrefabs = AccessTools.FieldRefAccess<ZNetScene, Dictionary<int, GameObject>>("m_namedPrefabs"); internal static void Register(ZNetScene scene) { if ((Object)(object)scene == (Object)null) { return; } if ((Object)(object)_prefab == (Object)null) { Build(scene); } if (!((Object)(object)_prefab == (Object)null)) { scene.m_prefabs.RemoveAll((GameObject p) => (Object)(object)p == (Object)null || (((Object)p).name == "goodtidings_dverger" && (Object)(object)p != (Object)(object)_prefab)); if (!scene.m_prefabs.Contains(_prefab)) { scene.m_prefabs.Add(_prefab); } NamedPrefabs.Invoke(scene)[StringExtensionMethods.GetStableHashCode("goodtidings_dverger")] = _prefab; } } internal static void Unregister() { ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance != (Object)null && (Object)(object)_prefab != (Object)null) { instance.m_prefabs.Remove(_prefab); Dictionary<int, GameObject> dictionary = NamedPrefabs.Invoke(instance); if (dictionary.TryGetValue(StringExtensionMethods.GetStableHashCode("goodtidings_dverger"), out var value) && (Object)(object)value == (Object)(object)_prefab) { dictionary.Remove(StringExtensionMethods.GetStableHashCode("goodtidings_dverger")); } } if (Object.op_Implicit((Object)(object)_holder)) { Object.Destroy((Object)(object)_holder); } _holder = (_prefab = null); } private static void Build(ZNetScene scene) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown GameObject prefab = scene.GetPrefab("Dverger"); if ((Object)(object)prefab == (Object)null) { Plugin.Log.LogError((object)"No Dverger prefab: the wounded Dvergr can't be made"); return; } _holder = new GameObject("goodtidings_prefabs_dverger"); _holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_holder); GameObject val = Object.Instantiate<GameObject>(prefab, _holder.transform, false); ((Object)val).name = "goodtidings_dverger"; MonsterAI component = val.GetComponent<MonsterAI>(); DvergerAI dvergerAI = val.AddComponent<DvergerAI>(); FieldInfo[] fields = typeof(BaseAI).GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { fieldInfo.SetValue(dvergerAI, fieldInfo.GetValue(component)); } ((BaseAI)dvergerAI).m_aggravatable = false; ((BaseAI)dvergerAI).m_randomMoveRange = 12f; ((BaseAI)dvergerAI).m_randomMoveInterval = 6f; ((BaseAI)dvergerAI).m_spawnMessage = ""; Object.DestroyImmediate((Object)(object)component); Type[] array = new Type[2] { typeof(CharacterDrop), typeof(NpcTalk) }; foreach (Type type in array) { Component component2 = val.GetComponent(type); if (component2 != null) { Object.DestroyImmediate((Object)(object)component2); } } Humanoid component3 = val.GetComponent<Humanoid>(); ((Character)component3).m_name = "$goodtidings_dverger"; component3.m_defaultItems = (GameObject[])(object)new GameObject[0]; component3.m_randomWeapon = (GameObject[])(object)new GameObject[0]; component3.m_randomShield = ((IEnumerable<GameObject>)(object)new GameObject[1] { Item("DvergerHairMale_Redbeard") }).Where((GameObject x) => Object.op_Implicit((Object)(object)x)).ToArray(); component3.m_randomSets = (ItemSet[])(object)new ItemSet[0]; ((Character)component3).m_walkSpeed = 1.1f; ((Character)component3).m_speed = 1.1f; ((Character)component3).m_runSpeed = 1.4f; val.AddComponent<DvergerVisitor>(); _prefab = val; GameObject Item(string name) { return scene.GetPrefab(name); } } } internal sealed class DvergerAI : BaseAI { internal const string HomeKey = "GoodTidings.Home"; internal const string LeaveAtKey = "GoodTidings.LeaveAt"; internal const string StageKey = "GoodTidings.Stage"; internal const string SpotKey = "GoodTidings.Spot"; internal const string SpotRotKey = "GoodTidings.SpotRot"; internal const string ApproachKey = "GoodTidings.Approach"; internal const string PoseKey = "GoodTidings.Pose"; internal const string NoFireKey = "GoodTidings.NoFire"; internal const string MealsKey = "GoodTidings.Meals"; internal const string StageAtKey = "GoodTidings.StageAt"; internal const string BandAtKey = "GoodTidings.BandAt"; internal const string BandSentKey = "GoodTidings.BandSent"; internal const string KneelAtKey = "GoodTidings.KneelAt"; internal const string TargetKey = "GoodTidings.Target"; internal const string RetriedKey = "GoodTidings.Retried"; internal const int Arriving = 0; internal const int Slumped = 1; internal const int Walking = 2; internal const int Resting = 3; internal const int Healing = 4; internal const int Tempering = 5; internal const int Crafting = 6; internal const int Thankful = 7; internal const int Neglected = 8; internal const string GroundPose = "Sitting idle"; internal const string BedPose = "Laying Sleeping"; private static readonly long LeaveGrace = TimeSpan.FromSeconds(150.0).Ticks; private static readonly long WalkGiveUp = TimeSpan.FromSeconds(60.0).Ticks; private static readonly long ArriveGiveUp = TimeSpan.FromSeconds(90.0).Ticks; private static readonly long TemperWalk = TimeSpan.FromSeconds(25.0).Ticks; private static readonly long CraftTime = TimeSpan.FromSeconds(4.5).Ticks; private static readonly long HealTime = TimeSpan.FromSeconds(8.0).Ticks; private static readonly long BandDelay = TimeSpan.FromSeconds(45.0).Ticks; private float _fireSearch; private float _progressTimer; private float _lastDistance = float.MaxValue; private long Now => ZNet.instance.GetTime().Ticks; internal void SetHome(Vector3 point) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) base.m_spawnPoint = point; ZDO zDO = base.m_nview.GetZDO(); zDO.Set("GoodTidings.Home", point); zDO.Set(ZDOVars.s_spawnPoint, point); } private void SetStage(ZDO zdo, int stage) { zdo.Set("GoodTidings.Stage", stage); zdo.Set("GoodTidings.StageAt", Now); } public override bool UpdateAI(float dt) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_010a: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_0454: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_0443: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) if (!((BaseAI)this).UpdateAI(dt)) { return false; } ZDO zDO = base.m_nview.GetZDO(); long now = Now; base.m_spawnPoint = zDO.GetVec3(ZDOVars.s_spawnPoint, base.m_spawnPoint); long num = zDO.GetLong("GoodTidings.LeaveAt", 0L); if (num == 0L) { num = now + TimeSpan.FromMinutes(Plugin.DvergerMinutes.Value).Ticks; zDO.Set("GoodTidings.LeaveAt", num); } int num2 = zDO.GetInt("GoodTidings.Stage", 0); if (num2 <= 3 && now >= num) { StandUp(zDO); SetStage(zDO, 8); zDO.Set("GoodTidings.BandAt", now + BandDelay); HeadAway(zDO); Plugin.Log.LogInfo((object)"The wounded Dvergr was left: he limps off, and his kin will come"); return true; } switch (num2) { case 0: { if (zDO.GetLong("GoodTidings.StageAt", 0L) == 0L) { zDO.Set("GoodTidings.StageAt", now); } Vector3 vec2 = zDO.GetVec3("GoodTidings.KneelAt", ((Component)this).transform.position); if (((BaseAI)this).MoveTo(dt, vec2, 0.8f, false) || now - zDO.GetLong("GoodTidings.StageAt", now) > ArriveGiveUp) { ((BaseAI)this).StopMoving(); SetStage(zDO, 1); } else { Unstick(dt, vec2); } return true; } case 1: ((BaseAI)this).StopMoving(); return true; case 2: { Vector3 vec = zDO.GetVec3("GoodTidings.Approach", ((Component)this).transform.position); if (((BaseAI)this).MoveTo(dt, vec, 0.7f, false)) { SetStage(zDO, 3); return true; } if (now - zDO.GetLong("GoodTidings.StageAt", now) > WalkGiveUp) { if (Vector3.Distance(((Component)this).transform.position, vec) < 1.5f) { SetStage(zDO, 3); return true; } if (!zDO.GetBool("GoodTidings.Retried", false)) { zDO.Set("GoodTidings.Retried", true); Rest.Find(((Component)this).transform.position, ((Component)this).transform.rotation, base.m_pathAgentType, out var place, furniture: false); GoTo(zDO, place); Plugin.Log.LogInfo((object)$"The wounded Dvergr can't get there: he goes to {place.What} at {place.Spot}"); return true; } zDO.Set("GoodTidings.Spot", ((Component)this).transform.position); zDO.Set("GoodTidings.SpotRot", ((Component)this).transform.rotation); zDO.Set("GoodTidings.Approach", ((Component)this).transform.position); zDO.Set("GoodTidings.Pose", "Sitting idle"); SetStage(zDO, 3); return true; } Unstick(dt, vec); return true; } case 3: case 4: ((BaseAI)this).StopMoving(); Hold(zDO); if (num2 == 3 && zDO.GetBool("GoodTidings.NoFire", false)) { LookForFire(zDO, dt); } if (num2 == 4 && now - zDO.GetLong("GoodTidings.StageAt", now) > HealTime) { StandUp(zDO); Player closestPlayer = Player.GetClosestPlayer(((Component)this).transform.position, 30f); if ((Object)(object)closestPlayer == (Object)null) { Finish(zDO); return true; } zDO.Set("GoodTidings.Target", closestPlayer.GetPlayerID()); SetStage(zDO, 5); Plugin.Log.LogInfo((object)("The wounded Dvergr is healed: he goes over to " + closestPlayer.GetPlayerName())); } return true; case 5: { Player val = Target(zDO); if ((Object)(object)val == (Object)null) { Finish(zDO); return true; } if (((BaseAI)this).MoveTo(dt, ((Component)val).transform.position, 1.6f, false) || now - zDO.GetLong("GoodTidings.StageAt", now) > TemperWalk) { ((BaseAI)this).StopMoving(); SetStage(zDO, 6); } else { Unstick(dt, ((Component)val).transform.position); } return true; } case 6: { ((BaseAI)this).StopMoving(); Player val2 = Target(zDO); if (Object.op_Implicit((Object)(object)val2)) { ((BaseAI)this).LookAt(((Component)val2).transform.position); } if (now - zDO.GetLong("GoodTidings.StageAt", now) > CraftTime) { Finish(zDO); } return true; } case 8: if (!zDO.GetBool("GoodTidings.BandSent", false) && now >= zDO.GetLong("GoodTidings.BandAt", now)) { zDO.Set("GoodTidings.BandSent", true); DvergerBand.Call(zDO.GetVec3("GoodTidings.Home", ((Component)this).transform.position)); } break; } Vector3 vec3 = zDO.GetVec3("GoodTidings.Home", base.m_spawnPoint); if ((num2 != 8 || zDO.GetBool("GoodTidings.BandSent", false)) && (Utils.DistanceXZ(((Component)this).transform.position, vec3) > 60f || now > zDO.GetLong("GoodTidings.StageAt", now) + LeaveGrace)) { ZNetScene.instance.Destroy(((Component)this).gameObject); return true; } ((BaseAI)this).IdleMovement(dt); return true; } private Player Target(ZDO zdo) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) long id = zdo.GetLong("GoodTidings.Target", 0L); Player val = ((IEnumerable<Player>)Player.GetAllPlayers()).FirstOrDefault((Func<Player, bool>)((Player x) => Object.op_Implicit((Object)(object)x) && x.GetPlayerID() == id)); if (!Object.op_Implicit((Object)(object)val) || !(Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position) < 40f)) { return null; } return val; } private void Finish(ZDO zdo) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) SetStage(zdo, 7); Tempered.SendTemper(((Component)this).transform.position); HeadAway(zdo); Plugin.Log.LogInfo((object)"The wounded Dvergr has tempered the gear of those near: he goes"); } private void Unstick(float dt, Vector3 target) { //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) _progressTimer += dt; if (!(_progressTimer < 2f)) { _progressTimer = 0f; float num = Vector3.Distance(((Component)this).transform.position, target); if (_lastDistance - num < 0.3f) { OpenDoors(); } _lastDistance = num; } } private void OpenDoors() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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) Vector3 val = ((Component)this).transform.position + Vector3.up; foreach (Door item in (from c in Physics.OverlapSphere(val, 3f, -1, (QueryTriggerInteraction)2) select ((Component)c).GetComponentInParent<Door>() into x where (Object)(object)x != (Object)null select x).Distinct()) { ZNetView component = ((Component)item).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid() && !((Object)(object)item.m_keyItem != (Object)null) && component.GetZDO().GetInt(ZDOVars.s_state, 0) == 0) { Vector3 forward = ((Component)item).transform.forward; Vector3 val2 = ((Component)this).transform.position - ((Component)item).transform.position; bool flag = Vector3.Dot(forward, ((Vector3)(ref val2)).normalized) < 0f; component.InvokeRPC("UseDoor", new object[1] { flag }); Plugin.Debug("The wounded Dvergr opens " + ((Object)item).name); } } } private void LookForFire(ZDO zdo, float dt) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) _fireSearch -= dt; if (!(_fireSearch > 0f)) { _fireSearch = 4f; Rest.Find(((Component)this).transform.position, ((Component)this).transform.rotation, base.m_pathAgentType, out var place); if (place.ByFire) { StandUp(zdo); GoTo(zdo, place); Plugin.Log.LogInfo((object)$"The wounded Dvergr sees a fire: he goes to {place.What} at {place.Spot}"); } } } private void GoTo(ZDO zdo, Rest.Place place) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) zdo.Set("GoodTidings.Spot", place.Spot); zdo.Set("GoodTidings.SpotRot", place.Rotation); zdo.Set("GoodTidings.Approach", place.Approach); zdo.Set("GoodTidings.Pose", place.Pose); zdo.Set("GoodTidings.NoFire", !place.ByFire); SetStage(zdo, 2); } private void Hold(ZDO zdo) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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_00d0: Unknown result type (might be due to invalid IL or missing references) Vector3 vec = zdo.GetVec3("GoodTidings.Spot", ((Component)this).transform.position); Quaternion quaternion = zdo.GetQuaternion("GoodTidings.SpotRot", ((Component)this).transform.rotation); Vector3 val = Vector3.ProjectOnPlane(quaternion * Vector3.forward, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude > 0.01f) { base.m_character.SetLookDir(val, 0f); } Vector3 val2 = ((Component)this).transform.position - vec; if (((Vector3)(ref val2)).sqrMagnitude > 0.0004f || Quaternion.Angle(((Component)this).transform.rotation, quaternion) > 1f) { Rigidbody component = ((Component)base.m_character).GetComponent<Rigidbody>(); ((Component)this).transform.SetPositionAndRotation(vec, quaternion); if (Object.op_Implicit((Object)(object)component)) { component.position = vec; component.rotation = quaternion; component.velocity = Vector3.zero; } } } private void StandUp(ZDO zdo) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) int num = zdo.GetInt("GoodTidings.Stage", 0); if (num == 3 || num == 4) { Vector3 position = zdo.GetVec3("GoodTidings.Approach", ((Component)this).transform.position) + Vector3.up * 0.1f; ((Component)this).transform.position = position; Rigidbody component = ((Component)base.m_character).GetComponent<Rigidbody>(); if (Object.op_Implicit((Object)(object)component)) { component.position = position; component.velocity = Vector3.zero; } } } private void HeadAway(ZDO zdo) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_0049: 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) Vector3 vec = zdo.GetVec3("GoodTidings.Home", ((Component)this).transform.position); Vector3 val = ((Component)this).transform.position - vec; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 1f) { val = ((Component)this).transform.forward; } base.m_spawnPoint = vec + ((Vector3)(ref val)).normalized * 90f; zdo.Set(ZDOVars.s_spawnPoint, base.m_spawnPoint); } internal void Help() { //IL_0022: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = base.m_nview.GetZDO(); if (zDO.GetInt("GoodTidings.Stage", 0) == 1) { Rest.Find(((Component)this).transform.position, ((Component)this).transform.rotation, base.m_pathAgentType, out var place); GoTo(zDO, place); Plugin.Log.LogInfo((object)$"The wounded Dvergr was helped up: he goes to {place.What} at {place.Spot}"); } } internal void Fed() { ZDO zDO = base.m_nview.GetZDO(); if (zDO.GetInt("GoodTidings.Stage", 0) == 3 && !zDO.GetBool("GoodTidings.NoFire", false)) { int num = zDO.GetInt("GoodTidings.Meals", 0) + 1; zDO.Set("GoodTidings.Meals", num); if (num >= Plugin.DvergerMeals.Value) { SetStage(zDO, 4); } } } } internal static class Rest { internal struct Place { public Vector3 Spot; public Vector3 Approach; public Quaternion Rotation; public string Pose; public string What; public bool ByFire; } internal const float FireSearch = 60f; internal const float NearFire = 6f; private static readonly FieldInfo AllAreasField = AccessTools.Field(typeof(EffectArea), "s_allAreas"); private static int _solidMask; private static readonly List<Vector3> Path = new List<Vector3>(); private static int SolidMask { get { if (_solidMask == 0) { return _solidMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "vehicle" }); } return _solidMask; } } private static List<EffectArea> AllAreas() { return AllAreasField?.GetValue(null) as List<EffectArea>; } internal static IEnumerable<Fireplace> Fires(Vector3 near, float range) { //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 e in AllAreas() ?? new List<EffectArea>() where Object.op_Implicit((Object)(object)e) && ((Behaviour)e).isActiveAndEnabled && (e.m_type & 1) > 0 select ((Component)e).GetComponentInParent<Fireplace>() into f where (Object)(object)f != (Object)null && f.IsBurning() && Vector3.Distance(((Component)f).transform.position, near) < range select f).Distinct(); } internal static void Find(Vector3 from, Quaternion facing, AgentType agent, out Place place, bool furniture = true) { //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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Unknown result type (might be due to invalid IL or missing references) //IL_0486: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_048e: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_042d: U