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 Wisplight Arrows v1.0.0
plugins/WisplightArrows.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using HeaveHo.Shared; using Microsoft.CodeAnalysis; using Nick.Shared; using UnityEngine; using UnityEngine.Rendering; [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: 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; } 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 WisplightArrows { internal static class ArrowIcon { private const float Shrink = 0.9f; private const float OrbRadius = 0.075f; private const float HeadLength = 0.18f; private const float ShaftHalf = 0.022f; private const float CorePart = 0.45f; private const float HazeRadius = 0.24f; private const float HazeStrength = 0.85f; private const float EdgeFade = 0.08f; private static readonly Color GlassTint = new Color(0.62f, 0.8f, 0.95f); private static readonly Color CoreColour = new Color(0.55f, 0.95f, 1f); private static readonly Color HazeColour = new Color(0.45f, 0.75f, 1f); private static readonly string[] Bases = new string[3] { "ArrowSilver", "ArrowFlint", "ArrowWood" }; public static Sprite FromGame(ZNetScene scene) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) Sprite val = null; string[] bases = Bases; foreach (string text in bases) { GameObject prefab = scene.GetPrefab(text); object obj; if (!((Object)(object)prefab != (Object)null)) { obj = null; } else { ItemDrop component = prefab.GetComponent<ItemDrop>(); obj = ((component != null) ? component.m_itemData.GetIcon() : null); } val = (Sprite)obj; if ((Object)(object)val != (Object)null) { break; } } Texture2D val2 = Copy(val); if ((Object)(object)val2 == (Object)null) { return null; } Paint(val2, orb: true); return Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f), 100f); } public static void AddHaze(Sprite drawn) { Texture2D val = (((Object)(object)drawn != (Object)null) ? drawn.texture : null); if ((Object)(object)val != (Object)null && ((Texture)val).isReadable) { Paint(val, orb: false); } } private static Texture2D Copy(Sprite sprite) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_0024: 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) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)sprite == (Object)null || (Object)(object)sprite.texture == (Object)null) { return null; } if ((int)SystemInfo.graphicsDeviceType == 4) { return null; } Rect textureRect = sprite.textureRect; RenderTexture temporary = RenderTexture.GetTemporary(((Texture)sprite.texture).width, ((Texture)sprite.texture).height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); RenderTexture active = RenderTexture.active; try { Graphics.Blit((Texture)(object)sprite.texture, temporary); RenderTexture.active = temporary; Texture2D val = new Texture2D(Mathf.RoundToInt(((Rect)(ref textureRect)).width), Mathf.RoundToInt(((Rect)(ref textureRect)).height), (TextureFormat)4, false); val.ReadPixels(new Rect(((Rect)(ref textureRect)).x, ((Rect)(ref textureRect)).y, (float)((Texture)val).width, (float)((Texture)val).height), 0, 0); val.Apply(); return val; } catch (Exception ex) { Plugin.Log.LogInfo((object)("Could not copy the arrow icon (" + ex.Message + "): the icon is drawn from the model")); return null; } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } } private static void Paint(Texture2D tex, bool orb) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: 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_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_0366: 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_0380: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: 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) int width = ((Texture)tex).width; int height = ((Texture)tex).height; Color[] array = (Color[])(object)new Color[width * height]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { float num = ((float)j + 0.5f) / ((float)width * 0.9f); float num2 = 0.5f + (((float)i + 0.5f) / (float)height - 0.5f) / 0.9f; array[i * width + j] = ((num > 1f || num2 < 0f || num2 > 1f) ? Color.clear : tex.GetPixelBilinear(num, num2)); } } int num3 = -1; int num4 = width - 1; while (num4 >= 0 && num3 < 0) { for (int k = 0; k < height; k++) { if (array[k * width + num4].a > 0.3f) { num3 = num4; break; } } num4--; } if (num3 < 0) { return; } int num5 = num3 - Mathf.RoundToInt((float)width * (orb ? 0.05f : 0.14f)); float num6 = 0f; float num7 = 0f; int num8 = 0; for (int l = 0; l < height; l++) { for (int m = Mathf.Max(0, num5); m <= num3; m++) { if (array[l * width + m].a > 0.3f) { num6 += (float)m; num7 += (float)l; num8++; } } } if (num8 == 0) { return; } num6 /= (float)num8; num7 /= (float)num8; float num9 = (float)width * 0.075f; if (orb) { int num10 = num3 - Mathf.RoundToInt((float)width * 0.18f); float num11 = (float)height * 0.022f; for (int n = 0; n < height; n++) { if (Mathf.Abs((float)n - num7) > num11) { for (int num12 = Mathf.Max(0, num10); num12 <= num3; num12++) { array[n * width + num12] = Color.clear; } } } num6 = (float)num3 - num9 * 0.6f; } float num13 = (float)width * 0.24f; float num14 = (float)width * 0.08f; for (int num15 = 0; num15 < height; num15++) { for (int num16 = 0; num16 < width; num16++) { float num17 = (float)num16 - num6; float num18 = (float)num15 - num7; float num19 = Mathf.Sqrt(num17 * num17 + num18 * num18); Color val = array[num15 * width + num16]; if (num19 < num13) { float num20 = num19 / num13; float num21 = Mathf.Clamp01((float)Mathf.Min(Mathf.Min(num16, width - 1 - num16), Mathf.Min(num15, height - 1 - num15)) / num14); val = Under(val, HazeColour, 0.85f * (1f - num20) * (1f - num20) * num21 * num21); } if (orb && num19 < num9 + 1f) { float num22 = num19 / num9; float num23 = Mathf.Clamp01(num9 + 0.5f - num19); float a = Mathf.Lerp(0.35f, 0.85f, num22 * num22 * num22) * num23; val = Over(val, GlassTint, a); float num24 = Mathf.Clamp01(1f - num22 / 0.45f); val = Over(val, CoreColour, Mathf.Clamp01(num24 * 2.2f)); val = Over(val, Color.white, Mathf.Clamp01(num24 * num24 * 1.5f)); float num25 = Mathf.Clamp01(1f - Vector2.Distance(new Vector2(num17, num18), new Vector2(-0.38f, 0.42f) * num9) / (num9 * 0.28f)); val = Over(val, Color.white, num25 * num25 * 0.9f); } array[num15 * width + num16] = val; } } tex.SetPixels(array); tex.Apply(); } private static Color Over(Color under, Color colour, float a) { //IL_000b: 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_0029: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_0023: Unknown result type (might be due to invalid IL or missing references) if (a <= 0f) { return under; } float num = a + under.a * (1f - a); if (num <= 0f) { return Color.clear; } Color val = (colour * a + under * under.a * (1f - a)) / num; return new Color(val.r, val.g, val.b, num); } private static Color Under(Color over, Color colour, float a) { //IL_000a: 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_0008: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_004d: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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) if (a <= 0f) { return over; } float num = over.a + a * (1f - over.a); if (num <= 0f) { return Color.clear; } Color val = (over * over.a + colour * a * (1f - over.a)) / num; return new Color(val.r, val.g, val.b, num); } } internal static class ArrowItem { [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetScene_Awake { private static void Postfix(ZNetScene __instance) { Guarded(delegate { Register(__instance, ObjectDB.instance); }); } } [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDB_Awake { private static void Postfix(ObjectDB __instance) { Guarded(delegate { Register(ZNetScene.instance, __instance); }); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class ObjectDB_CopyOtherDB { private static void Postfix(ObjectDB __instance) { Guarded(delegate { Register(ZNetScene.instance, __instance); }); } } public const string PrefabName = "nick_wisparrow"; public const string ProjectileName = "nick_wisparrow_projectile"; public const string GlowName = "nick_wisparrow_glow"; internal static GameObject Prefab; private static GameObject _projectile; private static GameObject _glow; internal static GameObject NockTemplate; internal static GameObject TrailPoint; private static Recipe _recipe; internal static GameObject Glow => _glow; public static void Register(ZNetScene scene, ObjectDB db) { if ((Object)(object)scene == (Object)null && (Object)(object)db == (Object)null) { return; } scene = (((Object)(object)scene != (Object)null) ? scene : ZNetScene.instance); if ((Object)(object)Prefab == (Object)null && (Object)(object)scene != (Object)null) { Build(scene); } if (!((Object)(object)Prefab == (Object)null)) { ItemReload.Replace(scene, db, (IEnumerable<GameObject>)(object)new GameObject[1] { Prefab }); ItemReload.Replace(scene, null, (IEnumerable<GameObject>)(object)new GameObject[2] { _projectile, _glow }); Content.ItemExtras((IEnumerable<GameObject>)(object)new GameObject[1] { Prefab }, db); if (!((Object)(object)db == (Object)null) && !((Object)(object)scene == (Object)null)) { GameObject prefab = scene.GetPrefab("piece_workbench"); CraftingStation station = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<CraftingStation>() : null); _recipe = Content.Recipe(Prefab, station, 1, Plugin.PerCraft.Value, null, Plugin.Cost.Value, Plugin.Log, null, upgradeOnly: false, null, db); ApplyRecipeSettings(); Plugin.Synced.NeedsServer(_recipe); } } } public static void ApplyRecipeSettings() { if (!((Object)(object)_recipe == (Object)null)) { Costs.Apply(_recipe, Plugin.Cost.Value, Plugin.Log); Costs.ApplyStation(_recipe, Plugin.Station.Value, Plugin.Log); _recipe.m_amount = Plugin.PerCraft.Value; } } public static void ApplyDamage() { //IL_0034: 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_004c: 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) ItemDrop val = (((Object)(object)Prefab != (Object)null) ? Prefab.GetComponent<ItemDrop>() : null); if (!((Object)(object)val == (Object)null)) { SharedData shared = val.m_itemData.m_shared; shared.m_damages = new DamageTypes { m_pierce = Plugin.Damage.Value }; shared.m_damagesPerLevel = default(DamageTypes); } } public static void ApplyMist() { SetRadius(_projectile, Plugin.FlightRadius.Value); SetRadius(_glow, Plugin.LandingRadius.Value); TimedDestruction val = (((Object)(object)_glow != (Object)null) ? _glow.GetComponent<TimedDestruction>() : null); if ((Object)(object)val != (Object)null) { val.m_timeout = Plugin.LandingSeconds.Value; } } public static void Forget() { Prefab = null; _projectile = (_glow = (TrailPoint = (NockTemplate = null))); _recipe = null; ArrowModel.Forget(); } private static void Guarded(Action register) { try { register(); } catch (Exception ex) { Plugin.Log.LogError((object)("Registering the wisplight arrow failed: " + ex)); } } private static void Build(ZNetScene scene) { //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: 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_0070: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_016d: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = scene.GetPrefab("ArrowWood"); GameObject val = WispBall(scene); GameObject val2 = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_attack.m_attackProjectile : null); if ((Object)(object)prefab == (Object)null || (Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { Plugin.Log.LogWarning((object)"The game has no wooden arrow or Wisplight to copy: no wisplight arrows this session"); return; } GameObject val3 = new GameObject("nick_wisparrow_holder"); val3.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val3); _glow = new GameObject("nick_wisparrow_glow"); _glow.transform.SetParent(val3.transform, false); _glow.AddComponent<ZNetView>(); TimedDestruction val4 = _glow.AddComponent<TimedDestruction>(); val4.m_triggerOnAwake = true; _glow.AddComponent<GlowFollow>(); _glow.AddComponent<GlowFade>(); AddWisp(val, _glow.transform, Vector3.zero); _projectile = Object.Instantiate<GameObject>(val2, val3.transform); ((Object)_projectile).name = "nick_wisparrow_projectile"; AddWisp(val, _projectile.transform, Vector3.zero); _projectile.AddComponent<MistTrail>(); TrailPoint = BareField(val, val3.transform); NockTemplate = new GameObject("nick_wisparrow_nock"); NockTemplate.transform.SetParent(val3.transform, false); AddWisp(val, NockTemplate.transform, Vector3.zero); Projectile component = _projectile.GetComponent<Projectile>(); component.m_spawnOnHit = _glow; component.m_spawnOnHitChance = 1f; component.m_spawnCount = 1; component.m_spawnOnTtl = true; component.m_spawnOnCharacters = false; component.m_copyProjectileRotation = false; component.m_randomSpawnOnHit.Clear(); component.m_spawnItem = null; Prefab = Object.Instantiate<GameObject>(prefab, val3.transform); ((Object)Prefab).name = "nick_wisparrow"; ItemDrop component2 = Prefab.GetComponent<ItemDrop>(); SharedData shared = component2.m_itemData.m_shared; shared.m_name = "$nick_wisparrow"; shared.m_description = "$nick_wisparrow_desc"; shared.m_value = 0; shared.m_attack.m_attackProjectile = _projectile; component2.m_itemData.m_dropPrefab = Prefab; ApplyDamage(); ApplyMist(); try { ArrowModel.Dress(Prefab, val, scene, glow: true); ArrowModel.Dress(_projectile, val, scene, glow: false); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not put the orb on the arrow: " + ex)); } Sprite val5 = null; try { val5 = ArrowIcon.FromGame(scene); } catch (Exception ex2) { Plugin.Log.LogInfo((object)("Could not paint the icon from the game's: " + ex2.Message)); } if ((Object)(object)val5 != (Object)null) { SetIcon(component2, val5); return; } try { ArrowModel.IconLook(Prefab, on: true); ArrowIcon.AddHaze(Icon.MakeItem(Prefab, setIcon: true, null, Quaternion.LookRotation(Vector3.right, Vector3.up))); } catch (Exception ex3) { Plugin.Log.LogWarning((object)("Could not draw the wisplight arrow icon: " + ex3.Message)); } finally { ArrowModel.IconLook(Prefab, on: false); } } private static void SetIcon(ItemDrop drop, Sprite icon) { SharedData shared = drop.m_itemData.m_shared; Sprite[] array = (Sprite[])((shared.m_icons != null && shared.m_icons.Length > 1) ? ((Array)(Sprite[])shared.m_icons.Clone()) : ((Array)new Sprite[1])); array[0] = icon; shared.m_icons = array; } private static GameObject WispBall(ZNetScene scene) { GameObject prefab = scene.GetPrefab("Demister"); ItemDrop val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ItemDrop>() : null); return ((SE_Demister)((((Object)(object)val != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null)?)).m_ballPrefab; } private static void AddWisp(GameObject ball, Transform parent, Vector3 at) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(ball, parent, false); ((Object)val).name = "wisp"; val.transform.localPosition = at; val.transform.localRotation = Quaternion.identity; ZSyncTransform[] componentsInChildren = val.GetComponentsInChildren<ZSyncTransform>(true); foreach (ZSyncTransform val2 in componentsInChildren) { Object.DestroyImmediate((Object)(object)val2); } ZNetView[] componentsInChildren2 = val.GetComponentsInChildren<ZNetView>(true); foreach (ZNetView val3 in componentsInChildren2) { Object.DestroyImmediate((Object)(object)val3); } Rigidbody[] componentsInChildren3 = val.GetComponentsInChildren<Rigidbody>(true); foreach (Rigidbody val4 in componentsInChildren3) { Object.DestroyImmediate((Object)(object)val4); } Collider[] componentsInChildren4 = val.GetComponentsInChildren<Collider>(true); foreach (Collider val5 in componentsInChildren4) { Object.DestroyImmediate((Object)(object)val5); } Demister[] componentsInChildren5 = val.GetComponentsInChildren<Demister>(true); foreach (Demister val6 in componentsInChildren5) { if (val6.m_disableForcefieldDelay > 0f) { Plugin.Log.LogInfo((object)$"The wisp ball's force field switched itself off after {val6.m_disableForcefieldDelay} s: kept on"); } val6.m_disableForcefieldDelay = 0f; } } private static GameObject BareField(GameObject ball, Transform holder) { Demister componentInChildren = ball.GetComponentInChildren<Demister>(true); if ((Object)(object)componentInChildren == (Object)null) { return null; } GameObject val = Object.Instantiate<GameObject>(((Component)componentInChildren).gameObject, holder, false); ((Object)val).name = "nick_wisparrow_trail"; for (int num = val.transform.childCount - 1; num >= 0; num--) { Object.DestroyImmediate((Object)(object)((Component)val.transform.GetChild(num)).gameObject); } Component[] components = val.GetComponents<Component>(); foreach (Component val2 in components) { if (!(val2 is Transform) && !(val2 is Demister) && !(val2 is ParticleSystemForceField)) { Object.DestroyImmediate((Object)(object)val2); } } val.GetComponent<Demister>().m_disableForcefieldDelay = 0f; val.AddComponent<TrailPoint>(); return val; } private static void SetRadius(GameObject prefab, float radius) { if (!((Object)(object)prefab == (Object)null)) { ParticleSystemForceField[] componentsInChildren = prefab.GetComponentsInChildren<ParticleSystemForceField>(true); foreach (ParticleSystemForceField val in componentsInChildren) { val.endRange = radius; } } } } internal static class ArrowModel { private const float GlassSize = 0.095f; private const float PullBack = 0.03f; private const float CoreSize = 0.04f; private const float LightRange = 1.2f; private const float LightIntensity = 0.6f; private const float FlareScale = 0.3f; private const float SparkScale = 0.35f; private const float SparkRate = 0.25f; private static readonly Color GlassColour = new Color(0.78f, 0.9f, 1f, 0.3f); private static readonly Color IconGlassColour = new Color(0.6f, 0.8f, 1f, 0.6f); private static readonly Color WispColour = new Color(0.7f, 0.85f, 1f); private static Material _glass; private const float IconOrbScale = 3.5f; public static void Dress(GameObject root, GameObject ball, ZNetScene scene, bool glow) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011a: 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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0157: 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_0174: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Expected O, but got Unknown //IL_0214: Unknown result type (might be due to invalid IL or missing references) MeshFilter val = null; MeshFilter[] componentsInChildren = root.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val2 in componentsInChildren) { if ((Object)(object)val2.sharedMesh != (Object)null && (Object)(object)((Component)val2).transform.parent == (Object)(object)root.transform) { val = val2; break; } } Transform val3 = ball.transform.Find("demister_ball"); MeshFilter val4 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent<MeshFilter>() : null); MeshRenderer val5 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent<MeshRenderer>() : null); if ((Object)(object)val == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null) { Plugin.Log.LogWarning((object)"Could not find the arrow's or the wisp's model: the arrow keeps the wooden one's look"); return; } GameObject val6 = new GameObject("orb") { layer = ((Component)val).gameObject.layer }; val6.transform.SetParent(((Component)val).transform, false); Vector3 localScale = ((Component)val).transform.localScale; val6.transform.localPosition = Tip(val.sharedMesh) + new Vector3(0f, 0f, 0.03f / localScale.z); val6.transform.localScale = new Vector3(1f / localScale.x, 1f / localScale.y, 1f / localScale.z); Mesh sharedMesh = val4.sharedMesh; Bounds bounds = sharedMesh.bounds; float num = Mathf.Max(((Bounds)(ref bounds)).size.x, 0.0001f); Material val7 = GlassMat(scene); if ((Object)(object)val7 != (Object)null) { Part(val6, "glass", sharedMesh, val7, 0.095f / num); } Part(val6, "core", sharedMesh, ((Renderer)val5).sharedMaterial, 0.04f / num); if (glow) { GameObject val8 = new GameObject("light") { layer = val6.layer }; val8.transform.SetParent(val6.transform, false); Light val9 = val8.AddComponent<Light>(); val9.type = (LightType)2; val9.color = WispColour; val9.range = 1.2f; val9.intensity = 0.6f; val9.shadows = (LightShadows)0; Effect(ball, "effects/flame/flare", val6.transform, 0.3f, 1f); Effect(ball, "effects/flame/embers", val6.transform, 0.35f, 0.25f); } } public static void Forget() { _glass = null; } public static void IconLook(GameObject root, bool on) { //IL_001c: 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_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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_0081: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_glass != (Object)null) { _glass.color = (on ? IconGlassColour : GlassColour); } Transform[] componentsInChildren = root.GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if (((Object)val).name == "orb") { Vector3 localScale = val.parent.localScale; float num = (on ? 3.5f : 1f); val.localScale = new Vector3(num / localScale.x, num / localScale.y, num / localScale.z); } } } private static Vector3 Tip(Mesh mesh) { //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) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0042: 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_006a: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = mesh.bounds; if (!mesh.isReadable) { Plugin.Log.LogInfo((object)"The arrow's mesh can't be read: the orb goes at the middle of its tip end"); return new Vector3(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).center.y, ((Bounds)(ref bounds)).min.z); } Vector3[] vertices = mesh.vertices; Vector3 val = Vector3.zero; int num = 0; Vector3[] array = vertices; foreach (Vector3 val2 in array) { if (val2.z < ((Bounds)(ref bounds)).min.z + 0.02f) { val += val2; num++; } } if (num <= 0) { return new Vector3(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).center.y, ((Bounds)(ref bounds)).min.z); } return new Vector3(val.x / (float)num, val.y / (float)num, ((Bounds)(ref bounds)).min.z); } private static void Part(GameObject orb, string name, Mesh mesh, Material material, float scale) { //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_0013: Expected O, but got Unknown //IL_002b: 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) GameObject val = new GameObject(name) { layer = orb.layer }; val.transform.SetParent(orb.transform, false); val.transform.localScale = Vector3.one * scale; val.AddComponent<MeshFilter>().sharedMesh = mesh; MeshRenderer val2 = val.AddComponent<MeshRenderer>(); ((Renderer)val2).sharedMaterial = material; ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; } private static void Effect(GameObject ball, string path, Transform at, float size, float rate) { //IL_0051: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_00b3: Unknown result type (might be due to invalid IL or missing references) Transform val = ball.transform.Find(path); if ((Object)(object)val == (Object)null) { Plugin.Log.LogInfo((object)("The wisp ball has no " + path + ": the dropped arrow goes without it")); return; } GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, at, false); ((Object)val2).name = ((Object)val).name; val2.transform.localPosition = Vector3.zero; ParticleSystem[] componentsInChildren = val2.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val3 in componentsInChildren) { MainModule main = val3.main; ((MainModule)(ref main)).startSizeMultiplier = ((MainModule)(ref main)).startSizeMultiplier * size; ((MainModule)(ref main)).startSpeedMultiplier = ((MainModule)(ref main)).startSpeedMultiplier * size; EmissionModule emission = val3.emission; ((EmissionModule)(ref emission)).rateOverTimeMultiplier = ((EmissionModule)(ref emission)).rateOverTimeMultiplier * rate; ShapeModule shape = val3.shape; if (((ShapeModule)(ref shape)).enabled) { ((ShapeModule)(ref shape)).radius = ((ShapeModule)(ref shape)).radius * size; } } } private static Material GlassMat(ZNetScene scene) { //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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown if ((Object)(object)_glass != (Object)null) { return _glass; } Material val = null; GameObject prefab = scene.GetPrefab("crystal_wall_1x1"); if ((Object)(object)prefab != (Object)null) { MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val2 in componentsInChildren) { if ((Object)(object)((Renderer)val2).sharedMaterial != (Object)null && ((Object)((Renderer)val2).sharedMaterial).name.StartsWith("crystal_window", StringComparison.Ordinal)) { val = ((Renderer)val2).sharedMaterial; break; } } } if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"The game has no crystal window glass: the orb goes without its glass"); return null; } Material val3 = new Material(val) { name = "nick_wisparrow_glass", color = GlassColour }; string[] array = new string[7] { "_MainTex", "_BumpMap", "_MetallicGlossMap", "_OcclusionMap", "_EmissionMap", "_DetailAlbedoMap", "_DetailNormalMap" }; foreach (string text in array) { if (val3.HasProperty(text)) { val3.SetTexture(text, (Texture)null); } } val3.DisableKeyword("_NORMALMAP"); val3.DisableKeyword("_METALLICGLOSSMAP"); val3.DisableKeyword("_EMISSION"); if (val3.HasProperty("_Metallic")) { val3.SetFloat("_Metallic", 0f); } if (val3.HasProperty("_Glossiness")) { val3.SetFloat("_Glossiness", 0.95f); } _glass = val3; return val3; } } internal static class Content { private class Sale { public string Trader; public TradeItem Item; public Func<bool> When; } private static readonly FieldInfo NamedField = AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs"); private static readonly MethodInfo UpdateRegisters = AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null); private static readonly List<GameObject> OurItems = new List<GameObject>(); private static readonly List<StatusEffect> OurEffects = new List<StatusEffect>(); private static readonly Dictionary<string, Recipe> OurRecipes = new Dictionary<string, Recipe>(); private static readonly List<(GameObject Station, string From, string To)> OurConversions = new List<(GameObject, string, string)>(); private static readonly List<(GameObject Creature, string Item)> OurDrops = new List<(GameObject, string)>(); private static readonly List<Sale> OurSales = new List<Sale>(); private static Dictionary<int, GameObject> Named(ZNetScene scene) { return (Dictionary<int, GameObject>)NamedField.GetValue(scene); } private static bool Destroyed(Object o) { if (o != null) { return o == (Object)null; } return false; } public static void Item(GameObject prefab, ObjectDB db = null) { Items((IEnumerable<GameObject>)(object)new GameObject[1] { prefab }, db); } public static void Items(IEnumerable<GameObject> prefabs, ObjectDB db = null) { db = (((Object)(object)db != (Object)null) ? db : ObjectDB.instance); ZNetScene instance = ZNetScene.instance; bool flag = false; foreach (GameObject prefab in prefabs) { if ((Object)(object)prefab == (Object)null || (Object)(object)prefab.GetComponent<ItemDrop>() == (Object)null) { continue; } if ((Object)(object)instance != (Object)null) { if (!instance.m_prefabs.Contains(prefab)) { instance.m_prefabs.RemoveAll((GameObject p) => (Object)(object)p == (Object)null || ((Object)p).name == ((Object)prefab).name); instance.m_prefabs.Add(prefab); } Named(instance)[StringExtensionMethods.GetStableHashCode(((Object)prefab).name)] = prefab; } if ((Object)(object)db != (Object)null && !db.m_items.Contains(prefab)) { db.m_items.RemoveAll((GameObject i) => (Object)(object)i == (Object)null || ((Object)i).name == ((Object)prefab).name); db.m_items.Add(prefab); flag = true; } if (!OurItems.Contains(prefab)) { OurItems.Add(prefab); } } ItemExtras(prefabs, db); if (flag) { UpdateRegisters?.Invoke(db, null); } } public static void ItemExtras(IEnumerable<GameObject> prefabs, ObjectDB db = null) { db = (((Object)(object)db != (Object)null) ? db : ObjectDB.instance); foreach (GameObject prefab in prefabs) { ItemDrop val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val == (Object)null) { continue; } val.m_itemData.m_dropPrefab = prefab; if ((Object)(object)db == (Object)null) { continue; } SharedData shared = val.m_itemData.m_shared; StatusEffect[] array = (StatusEffect[])(object)new StatusEffect[4] { shared.m_consumeStatusEffect, shared.m_equipStatusEffect, shared.m_attackStatusEffect, shared.m_setStatusEffect }; foreach (StatusEffect effect in array) { if ((Object)(object)effect == (Object)null) { continue; } if (!db.m_StatusEffects.Contains(effect)) { db.m_StatusEffects.RemoveAll((StatusEffect e) => (Object)(object)e == (Object)null || ((Object)e).name == ((Object)effect).name); db.m_StatusEffects.Add(effect); } if (!OurEffects.Contains(effect)) { OurEffects.Add(effect); } } } } public static void RemoveItems(IEnumerable<GameObject> prefabs) { ZNetScene instance = ZNetScene.instance; ObjectDB instance2 = ObjectDB.instance; HashSet<GameObject> gone = new HashSet<GameObject>(prefabs.Where((GameObject p) => p != null)); foreach (GameObject item in gone) { OurItems.Remove(item); if ((Object)(object)instance != (Object)null) { instance.m_prefabs.Remove(item); } if ((Object)(object)item == (Object)null) { continue; } if ((Object)(object)instance != (Object)null) { Dictionary<int, GameObject> dictionary = Named(instance); int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)item).name); if (dictionary.TryGetValue(stableHashCode, out var value) && (Object)(object)value == (Object)(object)item) { dictionary.Remove(stableHashCode); } } ItemDrop component = item.GetComponent<ItemDrop>(); if (!((Object)(object)component != (Object)null) || !((Object)(object)instance2 != (Object)null)) { continue; } SharedData shared = component.m_itemData.m_shared; StatusEffect[] array = (StatusEffect[])(object)new StatusEffect[4] { shared.m_consumeStatusEffect, shared.m_equipStatusEffect, shared.m_attackStatusEffect, shared.m_setStatusEffect }; foreach (StatusEffect val in array) { if ((Object)(object)val != (Object)null && OurEffects.Remove(val)) { instance2.m_StatusEffects.Remove(val); } } } if ((Object)(object)instance2 != (Object)null) { instance2.m_items.RemoveAll((GameObject i) => (Object)(object)i == (Object)null || gone.Contains(i)); instance2.m_StatusEffects.RemoveAll((StatusEffect e) => (Object)(object)e == (Object)null); UpdateRegisters?.Invoke(instance2, null); } } public static Recipe Recipe(GameObject item, CraftingStation station, int level = 1, int amount = 1, Requirement[] cost = null, string costText = null, ManualLogSource log = null, string way = null, bool upgradeOnly = false, CraftingStation repairStation = null, ObjectDB db = null) { ItemDrop val = (((Object)(object)item != (Object)null) ? item.GetComponent<ItemDrop>() : null); if ((Object)(object)val == (Object)null) { return null; } string name = "Recipe_" + ((Object)item).name + (string.IsNullOrEmpty(way) ? "" : ("_" + way)); if (!OurRecipes.TryGetValue(name, out var value) || (Object)(object)value == (Object)null) { value = ScriptableObject.CreateInstance<Recipe>(); ((Object)value).name = name; value.m_item = val; value.m_amount = Mathf.Max(1, amount); value.m_craftingStation = station; value.m_repairStation = repairStation; value.m_minStationLevel = Mathf.Max(1, level); value.m_noCraftOnlyUpgrade = upgradeOnly; value.m_resources = (Requirement[])(((object)cost) ?? ((object)new Requirement[0])); if (costText != null) { Costs.Apply(value, costText, log); } OurRecipes[name] = value; } db = (((Object)(object)db != (Object)null) ? db : ObjectDB.instance); if ((Object)(object)db != (Object)null && !db.m_recipes.Contains(value)) { db.m_recipes.RemoveAll((Recipe r) => (Object)(object)r == (Object)null || ((Object)r).name == name); db.m_recipes.Add(value); } return value; } public static void RemoveRecipe(Recipe recipe) { if (recipe == null) { return; } ObjectDB.instance?.m_recipes.RemoveAll((Recipe r) => (Object)(object)r == (Object)null || (Object)(object)r == (Object)(object)recipe); foreach (string item in (from kv in OurRecipes where (Object)(object)kv.Value == (Object)(object)recipe select kv.Key).ToList()) { OurRecipes.Remove(item); } if ((Object)(object)recipe != (Object)null) { Object.Destroy((Object)(object)recipe); } } public static bool Conversion(GameObject stationPrefab, GameObject from, GameObject to, float cookSeconds = 10f, int makes = 4) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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_00f3: Expected O, but got Unknown ItemDrop val = (((Object)(object)from != (Object)null) ? from.GetComponent<ItemDrop>() : null); ItemDrop val2 = (((Object)(object)to != (Object)null) ? to.GetComponent<ItemDrop>() : null); if ((Object)(object)stationPrefab == (Object)null || (Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return false; } RemoveConversion(stationPrefab, ((Object)from).name, ((Object)to).name, forget: false); bool flag = false; Smelter component = stationPrefab.GetComponent<Smelter>(); if (component != null) { component.m_conversion.Add(new ItemConversion { m_from = val, m_to = val2 }); flag = true; } else { CookingStation component2 = stationPrefab.GetComponent<CookingStation>(); if (component2 != null) { component2.m_conversion.Add(new ItemConversion { m_from = val, m_to = val2, m_cookTime = cookSeconds }); flag = true; } else { Fermenter component3 = stationPrefab.GetComponent<Fermenter>(); if (component3 != null) { component3.m_conversion.Add(new ItemConversion { m_from = val, m_to = val2, m_producedItems = Mathf.Max(1, makes) }); flag = true; } } } if (flag && !OurConversions.Contains((stationPrefab, ((Object)from).name, ((Object)to).name))) { OurConversions.Add((stationPrefab, ((Object)from).name, ((Object)to).name)); } return flag; } public static void RemoveConversion(GameObject stationPrefab, string from, string to) { RemoveConversion(stationPrefab, from, to, forget: true); } private static void RemoveConversion(GameObject stationPrefab, string from, string to, bool forget) { if (!((Object)(object)stationPrefab == (Object)null)) { stationPrefab.GetComponent<Smelter>()?.m_conversion.RemoveAll((ItemConversion c) => c == null || Match(c.m_from, c.m_to)); stationPrefab.GetComponent<CookingStation>()?.m_conversion.RemoveAll((ItemConversion c) => c == null || Match(c.m_from, c.m_to)); stationPrefab.GetComponent<Fermenter>()?.m_conversion.RemoveAll((ItemConversion c) => c == null || Match(c.m_from, c.m_to)); if (forget) { OurConversions.Remove((stationPrefab, from, to)); } } bool Match(ItemDrop f, ItemDrop t) { if (!Destroyed((Object)(object)f) && !Destroyed((Object)(object)t)) { if ((Object)(object)f != (Object)null && (Object)(object)t != (Object)null && ((Object)f).name == from) { return ((Object)t).name == to; } return false; } return true; } } public static Drop Drop(GameObject creaturePrefab, GameObject item, float chance = 1f, int min = 1, int max = 1, bool perLevel = true) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown if ((Object)(object)creaturePrefab == (Object)null || (Object)(object)item == (Object)null) { return null; } CharacterDrop val = creaturePrefab.GetComponent<CharacterDrop>(); if ((Object)(object)val == (Object)null) { val = creaturePrefab.AddComponent<CharacterDrop>(); } val.m_drops.RemoveAll((Drop d) => d == null || Destroyed((Object)(object)d.m_prefab) || ((Object)(object)d.m_prefab != (Object)null && ((Object)d.m_prefab).name == ((Object)item).name)); min = Mathf.Max(0, min); Drop val2 = new Drop { m_prefab = item, m_chance = Mathf.Clamp01(chance), m_amountMin = min, m_amountMax = Mathf.Max(min, max) + 1, m_levelMultiplier = perLevel }; val.m_drops.Add(val2); if (!OurDrops.Contains((creaturePrefab, ((Object)item).name))) { OurDrops.Add((creaturePrefab, ((Object)item).name)); } return val2; } public static void RemoveDrop(GameObject creaturePrefab, string item) { if (!((Object)(object)creaturePrefab == (Object)null)) { creaturePrefab.GetComponent<CharacterDrop>()?.m_drops.RemoveAll((Drop d) => d == null || Destroyed((Object)(object)d.m_prefab) || ((Object)(object)d.m_prefab != (Object)null && ((Object)d.m_prefab).name == item)); OurDrops.Remove((creaturePrefab, item)); } } public static TradeItem Sell(Harmony harmony, string trader, GameObject item, int price, int stack = 1, string globalKey = null, Func<bool> when = null) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Expected O, but got Unknown ItemDrop val = (((Object)(object)item != (Object)null) ? item.GetComponent<ItemDrop>() : null); if (harmony == null || string.IsNullOrEmpty(trader) || (Object)(object)val == (Object)null) { return null; } Sale sale = OurSales.Find((Sale s) => s.Trader == trader && (Object)(object)s.Item.m_prefab != (Object)null && ((Object)s.Item.m_prefab).name == ((Object)item).name); if (sale == null) { List<Sale> ourSales = OurSales; Sale obj = new Sale { Trader = trader, Item = new TradeItem() }; sale = obj; ourSales.Add(obj); } sale.Item.m_prefab = val; sale.Item.m_price = Mathf.Max(0, price); sale.Item.m_stack = Mathf.Max(1, stack); sale.Item.m_requiredGlobalKey = globalKey ?? ""; sale.When = when; MethodInfo methodInfo = AccessTools.Method(typeof(Trader), "GetAvailableItems", (Type[])null, (Type[])null); MethodInfo postfix = AccessTools.Method(typeof(Content), "AddSales", (Type[])null, (Type[])null); Patches patchInfo = Harmony.GetPatchInfo((MethodBase)methodInfo); if (patchInfo == null || !patchInfo.Postfixes.Any((Patch p) => p.owner == harmony.Id && p.PatchMethod == postfix)) { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(postfix), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } return sale.Item; } public static void RemoveSale(string trader, string item) { OurSales.RemoveAll((Sale s) => s.Trader == trader && ((Object)(object)s.Item.m_prefab == (Object)null || ((Object)s.Item.m_prefab).name == item)); } private static void AddSales(Trader __instance, List<TradeItem> __result) { if (__result == null || OurSales.Count == 0) { return; } string prefabName = Utils.GetPrefabName(((Component)__instance).gameObject); foreach (Sale ourSale in OurSales) { if (!(ourSale.Trader != prefabName) && !((Object)(object)ourSale.Item.m_prefab == (Object)null) && !__result.Contains(ourSale.Item) && (string.IsNullOrEmpty(ourSale.Item.m_requiredGlobalKey) || (!((Object)(object)ZoneSystem.instance == (Object)null) && ZoneSystem.instance.GetGlobalKey(ourSale.Item.m_requiredGlobalKey)))) { bool flag; try { flag = ourSale.When == null || ourSale.When(); } catch { flag = false; } if (flag) { __result.Add(ourSale.Item); } } } } public static void RemoveAll(bool keepItems = false) { if (!keepItems) { if (OurItems.Count > 0) { RemoveItems(OurItems.ToList()); } ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance != (Object)null) { foreach (StatusEffect ourEffect in OurEffects) { instance.m_StatusEffects.Remove(ourEffect); } } } OurItems.Clear(); OurEffects.Clear(); foreach (Recipe item in OurRecipes.Values.ToList()) { RemoveRecipe(item); } OurRecipes.Clear(); foreach (var item2 in OurConversions.ToList()) { RemoveConversion(item2.Station, item2.From, item2.To); } OurConversions.Clear(); foreach (var item3 in OurDrops.ToList()) { RemoveDrop(item3.Creature, item3.Item); } OurDrops.Clear(); OurSales.Clear(); } } internal static class Costs { public const string Help = "Item prefab names and amounts, separated by commas, like FineWood:12, BronzeNails:30 (Claude Tools' `prefabs <text>` shows exact names). A cost with a mistake in it keeps the last good one."; public const string StationHelp = "The crafting station's prefab name (piece_workbench, forge, piece_stonecutter, piece_artisanstation, blackforge, piece_magetable), or none."; public static Requirement[] Parse(string text, List<string> problems, bool forRecipe) { //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Expected O, but got Unknown problems = problems ?? new List<string>(); int count = problems.Count; List<Requirement> list = new List<Requirement>(); string[] array = (text ?? "").Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text2 in array) { string text3 = text2.Trim(); if (text3.Length == 0) { continue; } string[] array2 = (from b in text3.Split(new char[1] { ':' }) select b.Trim()).ToArray(); if (array2.Length < 2 || array2.Length > 3 || !Whole(array2[1], out var value) || value < 1) { problems.Add("\"" + text3 + "\" isn't Name:amount"); continue; } int value2 = 0; bool result = true; if (array2.Length == 3) { bool num; if (!forRecipe) { num = bool.TryParse(array2[2], out result); } else { if (!Whole(array2[2], out value2)) { goto IL_0116; } num = value2 >= 0; } if (!num) { goto IL_0116; } } ItemDrop item = FindItem(array2[0]); if ((Object)(object)item == (Object)null) { problems.Add("no item called \"" + array2[0] + "\""); continue; } if (list.Any((Requirement r) => (Object)(object)r.m_resItem == (Object)(object)item)) { problems.Add(array2[0] + " is listed twice"); continue; } list.Add(new Requirement { m_resItem = item, m_amount = value, m_amountPerLevel = value2, m_recover = result }); continue; IL_0116: problems.Add(forRecipe ? ("\"" + text3 + "\": the upgrade amount isn't a number") : ("\"" + text3 + "\": the last part isn't true or false")); } if (list.Count == 0 && problems.Count == count) { problems.Add("it's empty (nothing would be free: write at least one item)"); } if (problems.Count != count) { return null; } return list.ToArray(); } private static bool Whole(string text, out int value) { return int.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture, out value); } public static string Write(IEnumerable<Requirement> cost, bool forRecipe) { return string.Join(", ", (from r in cost ?? Enumerable.Empty<Requirement>() where (Object)(object)r?.m_resItem != (Object)null select ((Object)r.m_resItem).name + ":" + r.m_amount + ((!forRecipe) ? (r.m_recover ? "" : ":false") : ((r.m_amountPerLevel > 0) ? (":" + r.m_amountPerLevel) : ""))).ToArray()); } public static ItemDrop FindItem(string name) { GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(name) : null); if ((Object)(object)val == (Object)null && (Object)(object)ObjectDB.instance != (Object)null) { val = ObjectDB.instance.GetItemPrefab(name); } if (!((Object)(object)val != (Object)null)) { return null; } return val.GetComponent<ItemDrop>(); } public static CraftingStation FindStation(string name, out bool found) { name = (name ?? "").Trim(); found = true; if (name.Length == 0 || name.Equals("none", StringComparison.OrdinalIgnoreCase)) { return null; } GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(name) : null); CraftingStation val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<CraftingStation>() : null); found = (Object)(object)val2 != (Object)null; return val2; } public static bool Apply(Piece piece, string text, ManualLogSource log) { if ((Object)(object)piece == (Object)null) { return false; } List<string> problems = new List<string>(); Requirement[] array = Parse(text, problems, forRecipe: false); Report(log, ((Object)piece).name, problems); if (array == null) { return false; } piece.m_resources = array; return true; } public static bool Apply(Recipe recipe, string text, ManualLogSource log) { if ((Object)(object)recipe == (Object)null) { return false; } List<string> problems = new List<string>(); Requirement[] array = Parse(text, problems, forRecipe: true); Report(log, ((Object)recipe).name, problems); if (array == null) { return false; } recipe.m_resources = array; return true; } public static bool ApplyStation(Piece piece, string text, ManualLogSource log) { if ((Object)(object)piece == (Object)null) { return false; } bool found; CraftingStation craftingStation = FindStation((text ?? "").Split(new char[1] { ':' })[0], out found); if (!found) { if (log != null) { log.LogWarning((object)(((Object)piece).name + ": no crafting station called \"" + text + "\", it keeps its station")); } return false; } piece.m_craftingStation = craftingStation; return true; } public static bool ApplyStation(Recipe recipe, string text, ManualLogSource log) { if ((Object)(object)recipe == (Object)null) { return false; } string[] array = (text ?? "").Split(new char[1] { ':' }); bool found; CraftingStation craftingStation = FindStation(array[0], out found); int value = 1; if (!found || (array.Length > 1 && (!Whole(array[1].Trim(), out value) || value < 1))) { if (log != null) { log.LogWarning((object)(((Object)recipe).name + ": \"" + text + "\" isn't a crafting station (and level), it keeps its station")); } return false; } recipe.m_craftingStation = craftingStation; recipe.m_minStationLevel = value; return true; } private static void Report(ManualLogSource log, string what, List<string> problems) { if (problems.Count > 0 && log != null) { log.LogWarning((object)(what + "'s cost setting has a mistake, so it keeps its last cost: " + string.Join("; ", problems.ToArray()))); } } } internal class GlowFade : MonoBehaviour { private const string BornKey = "nick_wisparrow_born"; private const string LastsKey = "nick_wisparrow_lasts"; private const float FadeSeconds = 5f; private ZNetView _nview; private double _born; private float _lasts; private bool _ready; private float _shown = 1f; private readonly List<ParticleSystemForceField> _fields = new List<ParticleSystemForceField>(); private readonly List<float> _ranges = new List<float>(); private readonly List<Light> _lights = new List<Light>(); private readonly List<float> _intensities = new List<float>(); private readonly List<ParticleSystem> _particles = new List<ParticleSystem>(); private readonly List<float> _rates = new List<float>(); private readonly List<Transform> _cores = new List<Transform>(); private readonly List<Vector3> _coreScales = new List<Vector3>(); private void Awake() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) _nview = ((Component)this).GetComponent<ZNetView>(); ParticleSystemForceField[] componentsInChildren = ((Component)th