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 Wanted v1.0.0
plugins/Wanted.dll
Decompiled 6 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using HeaveHo.Shared; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; 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: AssemblyMetadata("ClaudeTools.Reload", "world")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace HeaveHo.Shared { internal sealed class ServerSettings : IDisposable { public enum ServerMod { NotConnected, Checking, Installed, Missing } private sealed class ConfigurationManagerAttributes { public bool? ReadOnly; } private sealed class SyncedText { public string Key; public Func<string> Own; public Action<string> Use; public string Given; public bool FromServer; public bool Pending; public byte[] Packed; public bool TooBig; public MemoryStream Incoming; public int NextPart; } private sealed class Sending { public ZRpc Rpc; public string Key; public byte[] Data; public int Next; public int Parts; } private const int Protocol = 2; private const float ChangeSendGap = 0.5f; private const float AnswerWait = 20f; private const float FileWait = 1f; private const int PartSize = 65536; private const int CompressFrom = 1024; private const int WarnBytes = 262144; private const int MaxBytes = 8388608; private const int PaceBelow = 10240; private readonly string _send; private readonly string _ask; private readonly string _dAsk; private readonly string _dHello; private readonly string _dSend; private readonly string _edit; private readonly string _dTextAsk; private readonly string _dText; private readonly string _dAgain; private readonly ConfigFile _config; private readonly ManualLogSource _log; private readonly string _name; private readonly List<ConfigEntryBase> _entries = new List<ConfigEntryBase>(); private readonly Dictionary<ConfigEntryBase, object> _own = new Dictionary<ConfigEntryBase, object>(); private readonly Dictionary<ConfigEntryBase, object> _server = new Dictionary<ConfigEntryBase, object>(); private readonly List<GameObject> _guardedPieces = new List<GameObject>(); private readonly List<Recipe> _guardedRecipes = new List<Recipe>(); private ZRoutedRpc _registeredOn; private bool _applying; private bool _reloading; private bool _changePending; private float _nextChangeSend; private float _askedAt = -1f; private int _serverProtocol; private bool _directSeen; private readonly HashSet<ZRpc> _directPeers = new HashSet<ZRpc>(); private readonly List<SyncedText> _texts = new List<SyncedText>(); private readonly Dictionary<ZRpc, HashSet<string>> _textPeers = new Dictionary<ZRpc, HashSet<string>>(); private bool _textPending; private float _nextTextSend; private bool _readOnlyShown; private float _nextAdminCheck; private FileSystemWatcher _watcher; private volatile bool _fileTouched; private float _reloadAt = -1f; private string _fileText; private readonly List<Sending> _outbox = new List<Sending>(); private static readonly MethodInfo UpdateAvailablePieces = AccessTools.Method(typeof(Player), "UpdateAvailablePiecesList", (Type[])null, (Type[])null); private static readonly List<ServerSettings> Live = new List<ServerSettings>(); private static Harmony _saveHarmony; public string Version { get; } public bool FromServer => _server.Count > 0; public ServerMod Server { get; private set; } public string ServerVersion { get; private set; } public bool CanEditServer { get { if (!IsServer) { if (Server == ServerMod.Installed && _serverProtocol >= 1 && (Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.LocalPlayerIsAdminOrHost(); } return false; } return true; } } private static bool IsServer { get { if ((Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.IsServer(); } return false; } } public event Action ServerChanged; public ServerSettings(string guid, ConfigFile config, ManualLogSource log) { _send = guid + ".settings"; _ask = guid + ".settings.ask"; _dAsk = guid + ".settings.d.ask"; _dHello = guid + ".settings.d.hello"; _dSend = guid + ".settings.d.values"; _edit = guid + ".settings.d.edit"; _dTextAsk = guid + ".settings.d.textask"; _dAgain = guid + ".settings.d.again"; _dText = guid + ".settings.d.text"; _config = config; _log = log; BepInPlugin val = PluginOf(guid); _name = ((val != null) ? val.Name : null) ?? guid; Version = ((val == null) ? null : val.Version?.ToString()) ?? ""; Live.Add(this); if (Live.Count == 1) { PatchSave(); } WatchFile(); } public ConfigEntry<T> Add<T>(ConfigEntry<T> entry) { if (entry == null || _entries.Contains((ConfigEntryBase)(object)entry)) { return entry; } _entries.Add((ConfigEntryBase)(object)entry); entry.SettingChanged += OnChanged; GiveManagerAttributes((ConfigEntryBase)(object)entry); return entry; } private static void GiveManagerAttributes(ConfigEntryBase entry) { ConfigDescription description = entry.Description; if (description == null || description == ConfigDescription.Empty || (description.Tags ?? new object[0]).Any(IsManagerAttributes)) { return; } try { object[] value = new object[1] { new ConfigurationManagerAttributes() }.Concat(description.Tags ?? new object[0]).ToArray(); AccessTools.Field(typeof(ConfigDescription), "<Tags>k__BackingField")?.SetValue(description, value); } catch (Exception) { } } public ConfigEntry<T> Bind<T>(string section, string key, T value, string description, AcceptableValueBase range = null, params object[] tags) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown if (!description.Contains("[Synced with Server]")) { description += " [Synced with Server]"; } return Add<T>(_config.Bind<T>(section, key, value, new ConfigDescription(description, range, tags ?? new object[0]))); } public void NeedsServer(GameObject piecePrefab) { if (!((Object)(object)piecePrefab == (Object)null)) { _guardedPieces.RemoveAll((GameObject p) => (Object)(object)p == (Object)null || ((Object)p).name == ((Object)piecePrefab).name); _guardedPieces.Add(piecePrefab); Guard(); } } public void NeedsServer(Recipe recipe) { if (!((Object)(object)recipe == (Object)null)) { _guardedRecipes.RemoveAll((Recipe r) => (Object)(object)r == (Object)null || (Object)(object)r == (Object)(object)recipe || (!string.IsNullOrEmpty(((Object)recipe).name) && ((Object)r).name == ((Object)recipe).name)); _guardedRecipes.Add(recipe); Guard(); } } public void AddText(string key, Func<string> own, Action<string> use) { if (string.IsNullOrEmpty(key) || own == null || use == null) { ManualLogSource log = _log; if (log != null) { log.LogError((object)"AddText needs a key, own and use"); } return; } _texts.RemoveAll((SyncedText x) => x.Key == key); SyncedText syncedText = new SyncedText { Key = key, Own = own, Use = use }; _texts.Add(syncedText); Give(syncedText, OwnText(syncedText)); ZRpc val = ((!((Object)(object)ZNet.instance != (Object)null) || IsServer) ? null : ZNet.instance.GetServerPeer()?.m_rpc); if (_registeredOn != null && val != null) { val.Register<ZPackage>(_dText, (Action<ZRpc, ZPackage>)OnText); AskTexts(val); } } public void TextChanged(string key) { SyncedText syncedText = _texts.FirstOrDefault((SyncedText x) => x.Key == key); if (syncedText != null) { syncedText.Packed = null; if (!syncedText.FromServer) { Give(syncedText, OwnText(syncedText)); } if (IsServer) { syncedText.Pending = true; _textPending = true; } } } public bool TextFromServer(string key) { return _texts.Any((SyncedText x) => x.Key == key && x.FromServer); } public void Update() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != _registeredOn) { Unregister(); Restore(); RestoreTexts(give: true); _changePending = false; _textPending = false; SetServer(ServerMod.NotConnected, null, 0); if (instance != null) { Register(instance); } } float unscaledTime = Time.unscaledTime; if (_changePending && unscaledTime >= _nextChangeSend) { SendChange(); } if (_textPending && unscaledTime >= _nextTextSend) { SendTexts(); } if (_outbox.Count > 0) { Pump(); } if (Server == ServerMod.Checking && _askedAt >= 0f && unscaledTime - _askedAt > 20f) { if (_guardedPieces.Count + _guardedRecipes.Count > 0) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("The server didn't answer: " + _name + " isn't installed there (or its copy is older than 2026-10-11), so its pieces and items can't be made on this server.")); } } else { ManualLogSource log2 = _log; if (log2 != null) { log2.LogInfo((object)("The server didn't answer: " + _name + " isn't installed there, or its copy is older" + (FromServer ? " (its settings apply)." : " (your own settings apply)."))); } } SetServer(ServerMod.Missing, null, 0); } if (_fileTouched) { _fileTouched = false; _reloadAt = unscaledTime + 1f; } if (_reloadAt >= 0f && unscaledTime >= _reloadAt) { _reloadAt = -1f; ReloadFile(); } if (FromServer && unscaledTime >= _nextAdminCheck) { _nextAdminCheck = unscaledTime + 1f; ShowReadOnly(); } } public void Dispose() { Unregister(); Restore(); RestoreTexts(give: false); SetServer(ServerMod.NotConnected, null, 0); foreach (ConfigEntryBase entry in _entries) { Unsubscribe(entry); } _entries.Clear(); _texts.Clear(); try { _watcher?.Dispose(); } catch (Exception) { } _watcher = null; Live.Remove(this); if (Live.Count == 0) { UnpatchSave(); } } private void Register(ZRoutedRpc rpc) { Forget(rpc, _send); Forget(rpc, _ask); rpc.Register<ZPackage>(_send, (Action<long, ZPackage>)OnRoutedValues); rpc.Register(_ask, (Action<long>)OnRoutedAsk); rpc.m_onNewPeer = (Action<long>)Delegate.Combine(rpc.m_onNewPeer, new Action<long>(OnNewPeer)); _registeredOn = rpc; if (IsServer) { foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { ListenTo(peer); if (peer != null) { ZRpc rpc2 = peer.m_rpc; if (rpc2 != null) { rpc2.Invoke(_dAgain, Array.Empty<object>()); } } } return; } if ((Object)(object)ZNet.instance != (Object)null) { SetServer(ServerMod.Checking, null, 0); if (ZNet.instance.GetServerPeer() != null) { AskServer(); } } } private void Unregister() { if (_registeredOn == null) { return; } ZRoutedRpc registeredOn = _registeredOn; registeredOn.m_onNewPeer = (Action<long>)Delegate.Remove(registeredOn.m_onNewPeer, new Action<long>(OnNewPeer)); Forget(_registeredOn, _send); Forget(_registeredOn, _ask); if ((Object)(object)ZNet.instance != (Object)null) { foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (peer?.m_rpc != null) { string[] array = new string[7] { _dAsk, _dHello, _dSend, _edit, _dTextAsk, _dText, _dAgain }; foreach (string name in array) { ForgetDirect(peer.m_rpc, name); } } } } _directPeers.Clear(); _textPeers.Clear(); _outbox.Clear(); _directSeen = false; _registeredOn = null; } private static void Forget(ZRoutedRpc rpc, string name) { if (AccessTools.Field(typeof(ZRoutedRpc), "m_functions")?.GetValue(rpc) is IDictionary dictionary) { dictionary.Remove(StringExtensionMethods.GetStableHashCode(name)); } } private static void ForgetDirect(ZRpc rpc, string name) { if (AccessTools.Field(typeof(ZRpc), "m_functions")?.GetValue(rpc) is IDictionary dictionary) { dictionary.Remove(StringExtensionMethods.GetStableHashCode(name)); } } private void OnNewPeer(long uid) { if (IsServer) { ZNetPeer peer = ZNet.instance.GetPeer(uid); ListenTo(peer); if (peer?.m_rpc != null) { SendDirect(peer.m_rpc); } SendRouted(uid); } else if ((Object)(object)ZNet.instance != (Object)null) { ZNetPeer serverPeer = ZNet.instance.GetServerPeer(); if (serverPeer != null && serverPeer.m_uid == uid) { AskServer(); } } } private void ListenTo(ZNetPeer peer) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown if (peer?.m_rpc != null) { peer.m_rpc.Register(_dAsk, new Method(OnDirectAsk)); peer.m_rpc.Register<ZPackage>(_edit, (Action<ZRpc, ZPackage>)OnEdit); peer.m_rpc.Register<ZPackage>(_dTextAsk, (Action<ZRpc, ZPackage>)OnTextAsk); } } private void OnDirectAsk(ZRpc rpc) { if (IsServer) { _directPeers.Add(rpc); SendDirect(rpc); } } private void OnRoutedAsk(long sender) { if (IsServer) { SendRouted(sender); } } private void SendDirect(ZRpc rpc) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(2); val.Write(Version); rpc.Invoke(_dHello, new object[1] { val }); if (_entries.Count > 0) { rpc.Invoke(_dSend, new object[1] { Values() }); } } private void SendRouted(long target) { if (ZRoutedRpc.instance != null && _entries.Count > 0) { ZRoutedRpc.instance.InvokeRoutedRPC(target, _send, new object[1] { Values() }); } } private ZPackage Values() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(_entries.Count); foreach (ConfigEntryBase entry in _entries) { val.Write(entry.Definition.Section); val.Write(entry.Definition.Key); val.Write(TomlTypeConverter.ConvertToString(entry.BoxedValue, entry.SettingType)); } return val; } private void AskServer() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown ZNetPeer val = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetServerPeer() : null); if (val?.m_rpc == null) { return; } _askedAt = Time.unscaledTime; val.m_rpc.Register<ZPackage>(_dHello, (Action<ZRpc, ZPackage>)OnDirectHello); val.m_rpc.Register<ZPackage>(_dSend, (Action<ZRpc, ZPackage>)OnDirectValues); val.m_rpc.Register<ZPackage>(_dText, (Action<ZRpc, ZPackage>)OnText); val.m_rpc.Register(_dAgain, new Method(OnAskAgain)); val.m_rpc.Invoke(_dAsk, Array.Empty<object>()); AskTexts(val.m_rpc); try { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(val.m_uid, _ask, Array.Empty<object>()); } } catch (Exception) { } } private static bool IsServerConnection(ZRpc rpc) { if (!IsServer) { ZNet instance = ZNet.instance; return ((instance == null) ? null : instance.GetServerPeer()?.m_rpc) == rpc; } return false; } private void OnAskAgain(ZRpc rpc) { if (IsServerConnection(rpc)) { rpc.Invoke(_dAsk, Array.Empty<object>()); AskTexts(rpc); } } private void OnDirectHello(ZRpc rpc, ZPackage pkg) { if (!IsServerConnection(rpc)) { return; } try { int protocol = pkg.ReadInt(); string text = pkg.ReadString(); if (text != Version && text != ServerVersion) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("The server has " + _name + " " + text + ", you have " + Version + ": some things may not match. Use the same version as the server.")); } } _directSeen = true; SetServer(ServerMod.Installed, text, protocol); } catch (Exception ex) { ManualLogSource log2 = _log; if (log2 != null) { log2.LogWarning((object)("Could not read the server's hello: " + ex.Message)); } } } private void OnDirectValues(ZRpc rpc, ZPackage pkg) { if (IsServerConnection(rpc)) { TakeValues(pkg); } } private void OnRoutedValues(long sender, ZPackage pkg) { if (!_directSeen && !IsServer) { ZNetPeer val = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetServerPeer() : null); if (val != null && val.m_uid == sender) { TakeValues(pkg); } } } private void TakeValues(ZPackage pkg) { try { int num = pkg.ReadInt(); List<string> list = new List<string>(); for (int i = 0; i < num; i++) { string section = pkg.ReadString(); string key = pkg.ReadString(); string text = pkg.ReadString(); ConfigEntryBase val = ((IEnumerable<ConfigEntryBase>)_entries).FirstOrDefault((Func<ConfigEntryBase, bool>)((ConfigEntryBase x) => x.Definition.Section == section && x.Definition.Key == key)); if (val != null) { object obj; try { obj = TomlTypeConverter.ConvertToValue(text, val.SettingType); } catch (Exception) { continue; } if (!_own.ContainsKey(val)) { _own[val] = val.BoxedValue; } _server[val] = obj; if (!object.Equals(val.BoxedValue, obj)) { Apply(val, obj); list.Add(section + "/" + key + " = " + text); } } } ManualLogSource log = _log; if (log != null) { log.LogInfo((object)($"Settings from the server apply while you play here ({_server.Count})" + ((list.Count > 0) ? (": " + string.Join(", ", list.ToArray())) : ""))); } ShowReadOnly(); } catch (Exception ex2) { ManualLogSource log2 = _log; if (log2 != null) { log2.LogWarning((object)("Could not read the server's settings: " + ex2.Message)); } } } private void Apply(ConfigEntryBase e, object value) { bool saveOnConfigSet = _config.SaveOnConfigSet; _applying = true; try { _config.SaveOnConfigSet = false; e.BoxedValue = value; } finally { _config.SaveOnConfigSet = saveOnConfigSet; _applying = false; } } private void Restore() { if (_server.Count == 0) { return; } foreach (KeyValuePair<ConfigEntryBase, object> item in _own) { Apply(item.Key, item.Value); } _own.Clear(); _server.Clear(); ShowReadOnly(); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)"Your own settings apply again"); } } private void OnChanged(object sender, EventArgs args) { if (_applying) { return; } ConfigEntryBase val = (ConfigEntryBase)((sender is ConfigEntryBase) ? sender : null); if (val == null) { return; } if (_server.TryGetValue(val, out var value)) { if (!_reloading && CanEditServer) { SendEdit(val); } else { _own[val] = val.BoxedValue; } Apply(val, value); } else if (IsServer) { _changePending = true; if (Time.unscaledTime >= _nextChangeSend) { SendChange(); } } } private void SendChange() { _changePending = false; _nextChangeSend = Time.unscaledTime + 0.5f; if (!IsServer) { return; } foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (peer?.m_rpc == null) { continue; } if (_directPeers.Contains(peer.m_rpc)) { if (_entries.Count > 0) { peer.m_rpc.Invoke(_dSend, new object[1] { Values() }); } } else { SendRouted(peer.m_uid); } } } private void SendEdit(ConfigEntryBase e) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown ZNet instance = ZNet.instance; ZNetPeer val = ((instance != null) ? instance.GetServerPeer() : null); if (val?.m_rpc != null) { ZPackage val2 = new ZPackage(); val2.Write(e.Definition.Section); val2.Write(e.Definition.Key); val2.Write(TomlTypeConverter.ConvertToString(e.BoxedValue, e.SettingType)); val.m_rpc.Invoke(_edit, new object[1] { val2 }); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("Asked the server to set " + e.Definition.Section + "/" + e.Definition.Key)); } } } private void OnEdit(ZRpc rpc, ZPackage pkg) { try { if (!IsServer) { return; } ISocket socket = rpc.GetSocket(); string text = ((socket != null) ? socket.GetHostName() : null) ?? ""; ZNetPeer val = ((IEnumerable<ZNetPeer>)ZNet.instance.GetPeers()).FirstOrDefault((Func<ZNetPeer, bool>)((ZNetPeer p) => p.m_rpc == rpc)); string section = pkg.ReadString(); string key = pkg.ReadString(); string text2 = pkg.ReadString(); if (!ZNet.instance.IsAdmin(text)) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)((val?.m_playerName ?? text) + " tried to change " + section + "/" + key + " but isn't on the admin list")); } if (_entries.Count > 0) { rpc.Invoke(_dSend, new object[1] { Values() }); } return; } ConfigEntryBase val2 = ((IEnumerable<ConfigEntryBase>)_entries).FirstOrDefault((Func<ConfigEntryBase, bool>)((ConfigEntryBase x) => x.Definition.Section == section && x.Definition.Key == key)); if (val2 != null) { val2.BoxedValue = TomlTypeConverter.ConvertToValue(text2, val2.SettingType); ManualLogSource log2 = _log; if (log2 != null) { log2.LogInfo((object)("Admin " + (val?.m_playerName ?? text) + " set " + section + "/" + key + " = " + text2)); } } } catch (Exception ex) { ManualLogSource log3 = _log; if (log3 != null) { log3.LogWarning((object)("Could not take an admin's change: " + ex.Message)); } } } private void ShowReadOnly() { bool flag = FromServer && !CanEditServer; if (flag == _readOnlyShown) { return; } _readOnlyShown = flag; foreach (ConfigEntryBase entry in _entries) { ConfigDescription description = entry.Description; object[] array = ((description != null) ? description.Tags : null) ?? new object[0]; foreach (object obj in array) { if (IsManagerAttributes(obj)) { try { AccessTools.Field(obj.GetType(), "ReadOnly")?.SetValue(obj, flag ? ((object)true) : null); } catch (Exception) { } } } } } private static bool IsManagerAttributes(object tag) { if (tag != null) { return tag.GetType().Name == "ConfigurationManagerAttributes"; } return false; } private string OwnText(SyncedText t) { try { return t.Own() ?? ""; } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("Could not read " + t.Key + ": " + ex.Message)); } return t.Given ?? ""; } } private void Give(SyncedText t, string text) { if (t.Given != null && t.Given == text) { return; } t.Given = text; try { t.Use(text); } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("Could not use " + t.Key + ": " + ex)); } } } private void RestoreTexts(bool give) { foreach (SyncedText text in _texts) { text.Incoming = null; if (!text.FromServer) { continue; } text.FromServer = false; if (give) { Give(text, OwnText(text)); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("Your own " + text.Key + " applies again")); } } } } private void AskTexts(ZRpc server) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown if (_texts.Count == 0 || server == null) { return; } ZPackage val = new ZPackage(); val.Write(_texts.Count); foreach (SyncedText text in _texts) { val.Write(text.Key); } server.Invoke(_dTextAsk, new object[1] { val }); } private void OnTextAsk(ZRpc rpc, ZPackage pkg) { try { if (!IsServer) { return; } int num = pkg.ReadInt(); HashSet<string> hashSet = new HashSet<string>(); for (int i = 0; i < num && i < 1000; i++) { string key = pkg.ReadString(); if (_texts.Any((SyncedText x) => x.Key == key)) { hashSet.Add(key); } } if (_textPeers.TryGetValue(rpc, out var value)) { hashSet.UnionWith(value); } foreach (ZRpc item in _textPeers.Keys.Where((ZRpc r) => !r.IsConnected()).ToList()) { _textPeers.Remove(item); } _textPeers[rpc] = hashSet; foreach (SyncedText text in _texts) { if (hashSet.Contains(text.Key)) { SendText(rpc, text); } } } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("Could not answer a player's ask for server data: " + ex.Message)); } } } private void SendTexts() { _textPending = false; _nextTextSend = Time.unscaledTime + 0.5f; if (!IsServer) { return; } foreach (SyncedText text in _texts) { if (!text.Pending) { continue; } text.Pending = false; foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (peer?.m_rpc != null && _textPeers.TryGetValue(peer.m_rpc, out var value) && value.Contains(text.Key)) { SendText(peer.m_rpc, text); } } } } private void SendText(ZRpc rpc, SyncedText t) { byte[] array = Packed(t); if (array != null) { _outbox.RemoveAll((Sending s) => s.Rpc == rpc && s.Key == t.Key); _outbox.Add(new Sending { Rpc = rpc, Key = t.Key, Data = array, Parts = Math.Max(1, (array.Length + 65536 - 1) / 65536) }); Pump(); } } private void Pump() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown for (int num = _outbox.Count - 1; num >= 0; num--) { Sending sending = _outbox[num]; try { while (sending.Next < sending.Parts && sending.Rpc.IsConnected() && sending.Rpc.GetSocket().GetSendQueueSize() < 10240) { int num2 = sending.Next * 65536; int num3 = Math.Min(65536, sending.Data.Length - num2); byte[] array = new byte[num3]; Buffer.BlockCopy(sending.Data, num2, array, 0, num3); ZPackage val = new ZPackage(); val.Write(sending.Key); val.Write(sending.Next); val.Write(sending.Parts); val.Write(array); sending.Rpc.Invoke(_dText, new object[1] { val }); sending.Next++; } if (sending.Next >= sending.Parts || !sending.Rpc.IsConnected()) { _outbox.RemoveAt(num); } } catch (Exception ex) { _outbox.RemoveAt(num); ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("Could not send " + sending.Key + " to a player: " + ex.Message)); } } } } private byte[] Packed(SyncedText t) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown if (t.Packed == null) { string text = OwnText(t); ZPackage val = new ZPackage(); val.Write(text); ZPackage val2 = new ZPackage(); bool flag = text.Length > 1024; val2.Write(flag); if (flag) { val2.WriteCompressed(val); } else { val2.Write(val); } t.Packed = val2.GetArray(); t.TooBig = t.Packed.Length > 8388608; string arg = $"{t.Packed.Length / 1024} KB" + (flag ? $" gzipped ({text.Length / 1024} KB of text)" : ""); if (t.TooBig) { ManualLogSource log = _log; if (log != null) { log.LogError((object)$"{t.Key} is too big to send to players ({arg}, at most {8} MB): they keep their own."); } } else if (t.Packed.Length > 262144) { ManualLogSource log2 = _log; if (log2 != null) { log2.LogWarning((object)$"{t.Key} is big to send to every player who joins ({arg}): it takes about {(float)t.Packed.Length / 153600f:0} s of their connection, and their world loads slower meanwhile."); } } } if (!t.TooBig) { return t.Packed; } return null; } private void OnText(ZRpc rpc, ZPackage pkg) { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown if (!IsServerConnection(rpc)) { return; } SyncedText syncedText = null; try { string key = pkg.ReadString(); int num = pkg.ReadInt(); int num2 = pkg.ReadInt(); byte[] array = pkg.ReadByteArray(); syncedText = _texts.FirstOrDefault((SyncedText x) => x.Key == key); if (syncedText == null) { return; } if (num2 < 1 || num2 > 129 || num < 0 || num >= num2) { throw new InvalidDataException($"part {num} of {num2}"); } if (num == 0) { syncedText.Incoming = new MemoryStream(); syncedText.NextPart = 0; } if (syncedText.Incoming == null || num != syncedText.NextPart) { throw new InvalidDataException($"part {num} came out of order"); } syncedText.Incoming.Write(array, 0, array.Length); syncedText.NextPart = num + 1; if (num >= num2 - 1) { ZPackage val = new ZPackage(syncedText.Incoming.ToArray()); syncedText.Incoming = null; ZPackage val2 = (val.ReadBool() ? val.ReadCompressedPackage() : val.ReadPackage()); string text = val2.ReadString(); syncedText.FromServer = true; Give(syncedText, text); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)$"The server's {key} applies while you play here ({text.Length / 1024} KB)"); } } } catch (Exception ex) { if (syncedText != null) { syncedText.Incoming = null; } ManualLogSource log2 = _log; if (log2 != null) { log2.LogWarning((object)("Could not read the server's data" + ((syncedText != null) ? (" for " + syncedText.Key) : "") + ": " + ex.Message)); } } } private void SetServer(ServerMod state, string version, int protocol) { if (state != ServerMod.Checking) { _askedAt = -1f; } bool flag = state != Server || version != ServerVersion; Server = state; ServerVersion = version; _serverProtocol = protocol; if (!flag) { return; } Guard(); try { this.ServerChanged?.Invoke(); } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("ServerChanged: " + ex)); } } } private void Guard() { bool flag = Server == ServerMod.NotConnected || Server == ServerMod.Installed; bool flag2 = false; foreach (GameObject guardedPiece in _guardedPieces) { Piece val = (((Object)(object)guardedPiece != (Object)null) ? guardedPiece.GetComponent<Piece>() : null); if ((Object)(object)val != (Object)null && val.m_enabled != flag) { val.m_enabled = flag; flag2 = true; } } foreach (Recipe guardedRecipe in _guardedRecipes) { if ((Object)(object)guardedRecipe != (Object)null && guardedRecipe.m_enabled != flag) { guardedRecipe.m_enabled = flag; flag2 = true; } } if (flag2 && (Object)(object)Player.m_localPlayer != (Object)null) { try { UpdateAvailablePieces?.Invoke(Player.m_localPlayer, null); } catch (Exception) { } } } private void WatchFile() { try { string configFilePath = _config.ConfigFilePath; _watcher = new FileSystemWatcher(Path.GetDirectoryName(configFilePath), Path.GetFileName(configFilePath)) { NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite) }; FileSystemEventHandler value = delegate { _fileTouched = true; }; _watcher.Changed += value; _watcher.Created += value; _watcher.Renamed += delegate { _fileTouched = true; }; _watcher.EnableRaisingEvents = true; } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("Edits to the config file apply after a restart (can't watch it: " + ex.Message + ")")); } } } private void ReloadFile() { string text = ReadFile(_config.ConfigFilePath); if (text == null) { if (File.Exists(_config.ConfigFilePath)) { _reloadAt = Time.unscaledTime + 1f; } } else { if (text == _fileText) { return; } _fileText = text; bool saveOnConfigSet = _config.SaveOnConfigSet; _reloading = true; try { _config.SaveOnConfigSet = false; _config.Reload(); } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("Could not read the edited config file (check the line you changed): " + ex.Message)); } } finally { _config.SaveOnConfigSet = saveOnConfigSet; _reloading = false; } } } private void PatchSave() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_0067: Expected O, but got Unknown try { _saveHarmony = new Harmony(_send + ".save"); _saveHarmony.Patch((MethodBase)AccessTools.Method(typeof(ConfigFile), "Save", (Type[])null, (Type[])null), new HarmonyMethod(typeof(ServerSettings), "BeforeSave", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(ServerSettings), "AfterSave", (Type[])null), (HarmonyMethod)null); } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("Could not keep the server's values out of your config file: " + ex.Message)); } } } private static void UnpatchSave() { try { Harmony saveHarmony = _saveHarmony; if (saveHarmony != null) { saveHarmony.UnpatchSelf(); } } catch (Exception) { } _saveHarmony = null; } private static void BeforeSave(ConfigFile __instance) { foreach (ServerSettings item in Live) { if (item._config != __instance) { continue; } foreach (KeyValuePair<ConfigEntryBase, object> item2 in item._own) { SetQuietly(item2.Key, item2.Value); } } } private static Exception AfterSave(ConfigFile __instance, Exception __exception) { foreach (ServerSettings item in Live) { if (item._config != __instance) { continue; } foreach (KeyValuePair<ConfigEntryBase, object> item2 in item._server) { SetQuietly(item2.Key, item2.Value); } item._fileText = ReadFile(__instance.ConfigFilePath); } return __exception; } private static string ReadFile(string path) { try { return File.Exists(path) ? File.ReadAllText(path) : null; } catch (Exception) { return null; } } private static void SetQuietly(ConfigEntryBase e, object value) { AccessTools.Field(((object)e).GetType(), "_typedValue")?.SetValue(e, value); } private static BepInPlugin PluginOf(string guid) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown Type[] array; try { array = typeof(ServerSettings).Assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { array = ex.Types.Where((Type t) => t != null).ToArray(); } Type[] array2 = array; foreach (Type type in array2) { object[] customAttributes = type.GetCustomAttributes(typeof(BepInPlugin), inherit: false); for (int num2 = 0; num2 < customAttributes.Length; num2++) { BepInPlugin val = (BepInPlugin)customAttributes[num2]; if (val.GUID == guid || guid.StartsWith(val.GUID + ".")) { return val; } } } return null; } private void Unsubscribe(ConfigEntryBase e) { ((object)e).GetType().GetEvent("SettingChanged")?.RemoveEventHandler(e, new EventHandler(OnChanged)); } } } namespace Wanted { internal static class Board { [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetScene_Awake { private static void Postfix(ZNetScene __instance) { try { Register(__instance); } catch (Exception ex) { Plugin.Log.LogError((object)("Registering the Wanted board failed: " + ex)); } } } public const string PrefabName = "nick_wanted_board"; public const string PieceName = "$wanted_board"; public const int Slots = 10; internal static GameObject Prefab; private static PieceTable _table; private static GameObject _holder; private static Material _flatPlanks; private const float PostX = 0.98f; private const float PostZ = 0.52f; private const float PostHeight = 3f; private const float PostRadius = 0.15f; private const float PostSink = 0.3f; private const float ChestScale = 1.1f; private const float ChestTurn = 22f; private static readonly Vector3 ChestAt = new Vector3(0.5f, 0f, 0.18f); private static Material _stain; private const float PanelBottom = 1f; private const float PanelTop = 2.2f; private const float PlankDepth = 0.05f; private static float PanelFront => 0.31999996f; public static void Register(ZNetScene scene) { if ((Object)(object)scene == (Object)null) { return; } if ((Object)(object)Prefab == (Object)null) { Prefab = Build(scene); } if (!((Object)(object)Prefab == (Object)null)) { GameObject prefab = scene.GetPrefab("Hammer"); PieceTable val = ((!((Object)(object)prefab != (Object)null)) ? null : prefab.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_buildPieces); if ((Object)(object)val != (Object)null) { _table = val; } PieceReload.ReplacePrefab(scene, Prefab, ((Object)(object)val != (Object)null) ? val : _table); int num = PieceReload.Reattach(scene, Prefab); if (num > 0) { Plugin.Log.LogInfo((object)$"Gave {num} standing board(s) this copy's components"); } ApplyCost(); Plugin.Synced.NeedsServer(Prefab); } } public static void ApplyCost() { Piece val = (((Object)(object)Prefab != (Object)null) ? Prefab.GetComponent<Piece>() : null); if (!((Object)(object)val == (Object)null)) { Costs.Apply(val, Plugin.BoardCost.Value, Plugin.Log); Costs.ApplyStation(val, Plugin.BoardStation.Value, Plugin.Log); } } public static void Unload() { PieceReload.UnloadPiece(Prefab, _table); } public static void Forget() { Prefab = null; _table = null; _holder = null; Paper.Forget(); _flatPlanks = null; } private static GameObject Build(ZNetScene scene) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = scene.GetPrefab("piece_chest_private"); if ((Object)(object)prefab == (Object)null) { Plugin.Log.LogWarning((object)"The game has no personal chest to copy: no Wanted board this session"); return null; } _holder = new GameObject("Wanted_prefabs"); _holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_holder); GameObject val = Object.Instantiate<GameObject>(prefab, _holder.transform); ((Object)val).name = "nick_wanted_board"; Piece component = val.GetComponent<Piece>(); component.m_name = "$wanted_board"; component.m_description = "$wanted_board_desc"; Container component2 = val.GetComponent<Container>(); if ((Object)(object)component2 != (Object)null) { component2.m_name = "$wanted_box"; component2.m_privacy = (PrivacySetting)2; component2.m_width = 5; component2.m_height = 2; } MoveChest(val); try { DressChest(val.transform.Find("wanted_chest"), scene); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Wanted box look: " + ex.Message)); } try { AddLook(val, scene); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("Wanted board look: " + ex2)); } val.AddComponent<NoticeBoard>(); try { component.m_icon = Icon.Make(val, null, null, null); } catch (Exception ex3) { Plugin.Log.LogWarning((object)("Wanted board icon: " + ex3.Message)); } if ((Object)(object)component.m_icon == (Object)null) { component.m_icon = prefab.GetComponent<Piece>().m_icon; } return val; } private static void MoveChest(GameObject board) { //IL_0005: 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_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_00b1: Unknown result type (might be due to invalid IL or missing references) Transform transform = new GameObject("wanted_chest").transform; transform.SetParent(board.transform, false); foreach (Transform item in ((IEnumerable)board.transform).Cast<Transform>().ToList()) { if (!((Object)(object)item == (Object)(object)transform)) { if (((Component)item).CompareTag("snappoint")) { Object.DestroyImmediate((Object)(object)((Component)item).gameObject); } else { item.SetParent(transform, false); } } } transform.localPosition = ChestAt; transform.localRotation = Quaternion.Euler(0f, 202f, 0f); transform.localScale = Vector3.one * 1.1f; } private static void DressChest(Transform chest, ZNetScene scene) { //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)chest == (Object)null) { return; } MeshRenderer[] componentsInChildren = ((Component)chest).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val in componentsInChildren) { if ((Object)(object)((Renderer)val).sharedMaterial == (Object)null || ((Object)((Renderer)val).sharedMaterial).name.StartsWith("snow", StringComparison.Ordinal)) { continue; } if ((Object)(object)_stain == (Object)null) { _stain = new Material(((Renderer)val).sharedMaterial) { name = "wanted_box_stain" }; Texture2D val2 = Recolour(((Renderer)val).sharedMaterial.mainTexture); if ((Object)(object)val2 != (Object)null) { _stain.mainTexture = (Texture)(object)val2; } else if (_stain.HasProperty("_Color")) { _stain.SetColor("_Color", new Color(0.72f, 0.64f, 0.58f)); } } ((Renderer)val).sharedMaterial = _stain; } Material val3 = Paper.Label(scene); if (!((Object)(object)val3 == (Object)null)) { GameObject val4 = new GameObject("wanted_label"); val4.transform.SetParent(chest, false); val4.transform.localPosition = new Vector3(0.115f, 0.44f, 0.262f); val4.transform.localRotation = Quaternion.Euler(-8f, 180f, 4f); val4.transform.localScale = new Vector3(0.1f, 0.13f, 1f); val4.AddComponent<MeshFilter>().sharedMesh = QuadMesh(); ((Renderer)val4.AddComponent<MeshRenderer>()).sharedMaterial = val3; } } private static Texture2D Recolour(Texture source) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_005d: Expected O, but got Unknown //IL_0076: 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_00af: 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_00ed: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0); RenderTexture active = RenderTexture.active; try { Graphics.Blit(source, temporary); RenderTexture.active = temporary; Texture2D val = new Texture2D(source.width, source.height, (TextureFormat)4, true) { name = "wanted_box", wrapMode = source.wrapMode }; val.ReadPixels(new Rect(0f, 0f, (float)source.width, (float)source.height), 0, 0); Color[] pixels = val.GetPixels(); Color val2 = default(Color); ((Color)(ref val2))..ctor(0.66f, 0.48f, 0.26f); float num = default(float); float num2 = default(float); float num3 = default(float); for (int i = 0; i < pixels.Length; i++) { Color val3 = pixels[i]; Color.RGBToHSV(val3, ref num, ref num2, ref num3); Color val4 = ((num2 < 0.22f) ? Color.Lerp(val3, val2 * Mathf.Clamp01(num3 * 1.25f), 0.6f) : Color.HSVToRGB(0.075f, Mathf.Clamp01(num2 * 0.72f), Mathf.Clamp01(num3 * 0.82f))); val4.a = val3.a; pixels[i] = val4; } val.SetPixels(pixels); val.Apply(true); return val; } catch (Exception ex) { Plugin.Log.LogInfo((object)("Could not recolour the box (" + ex.Message + "): it's only darkened")); return null; } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } } private static void AddLook(GameObject board, ZNetScene scene) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_013d: 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_015d: 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_0203: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = scene.GetPrefab("wood_pole_log"); Transform val = ((prefab != null) ? prefab.transform.Find("New/log (1)") : null); GameObject prefab2 = scene.GetPrefab("wood_beam"); Transform val2 = ((prefab2 != null) ? prefab2.transform.Find("new") : null); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { Plugin.Log.LogWarning((object)"The game's log pole or beam has changed: the board is only its box"); return; } Material iron = MaterialOf(scene, "Iron") ?? MaterialOf(scene, "Bronze"); Transform transform = new GameObject("wanted_look").transform; transform.SetParent(board.transform, false); Random rnd = new Random(7); for (int i = 0; i < 2; i++) { float num = ((i == 0) ? (-1f) : 1f); Transform val3 = Copy(transform, "post", val); val3.localPosition = new Vector3(num * 0.98f, 1.35f, 0.52f); val3.localRotation = Quaternion.Euler(R(-1.5f, 1.5f), R(0f, 360f), R(-1.5f, 1.5f)) * Quaternion.Euler(90f, 90f, 0f); val3.localScale = new Vector3(0.54545456f, 0.57692313f, 1.4864864f); } float num2 = 0.3f; for (int j = 0; j < 4; j++) { Transform val4 = Copy(transform, "plank", val2); Flatten(val4); val4.localPosition = new Vector3(R(-0.04f, 0.04f), 1f + num2 * ((float)j + 0.5f), PanelFront + 0.025f + R(-0.008f, 0.008f)); val4.localRotation = Quaternion.Euler(0f, 0f, R(-0.8f, 0.8f)); val4.localScale = new Vector3(1.96f + R(0.2f, 0.32f), num2 - R(0.015f, 0.03f), 0.05f); Fit(val4); } Flatten(Beam(transform, val2, new Vector3(0f, 2.25f, PanelFront + 0.02f), new Vector3(2.46f, 0.12f, 0.14f), R(-0.6f, 0.6f))); Flatten(Beam(transform, val2, new Vector3(0f, 0.95f, PanelFront + 0.03f), new Vector3(2.3200002f, 0.1f, 0.12f), R(-0.6f, 0.6f))); for (int k = 0; k < 2; k++) { float num3 = ((k == 0) ? (-1f) : 1f); for (int l = 0; l < 2; l++) { float num4 = 0.36f * ((float)l + 0.5f) - 0.02f; Transform val5 = Copy(transform, "roof", val2); val5.localPosition = new Vector3(R(-0.03f, 0.03f), 2.97f - num4 * Mathf.Sin((float)Math.PI * 19f / 90f) + (float)l * 0.025f, 0.52f + num3 * num4 * Mathf.Cos((float)Math.PI * 19f / 90f)); val5.localRotation = Quaternion.Euler(num3 * 38f + R(-1f, 1f), 0f, R(-0.6f, 0.6f)); val5.localScale = new Vector3(2.58f, 0.035f, 0.42000002f); Fit(val5); } } Beam(transform, val2, new Vector3(0f, 2.99f, 0.52f), new Vector3(2.66f, 0.1f, 0.1f), 0f); AddNotices(transform, scene, iron, rnd); AddPouch(transform, scene, iron); AddColliders(board); float R(float from, float to) { return from + (float)rnd.NextDouble() * (to - from); } } private static void AddNotices(Transform look, ZNetScene scene, Material iron, Random rnd) { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Expected O, but got Unknown //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) Mesh sharedMesh = QuadMesh(); GameObject prefab = scene.GetPrefab("ArrowWood"); Transform val = ((prefab != null) ? prefab.transform.Find("model") : null); GameObject prefab2 = scene.GetPrefab("KnifeCopper"); Transform val2 = ((prefab2 != null) ? prefab2.transform.Find("attach/knife") : null); Vector3 val5 = default(Vector3); for (int i = 0; i < 10; i++) { float num = -0.8f + 0.4f * (float)(i % 5) + R(-0.03f, 0.03f); float num2 = ((i < 5) ? 1.89f : 1.34f) + R(-0.04f, 0.04f); Transform transform = new GameObject("notice_" + i).transform; transform.SetParent(look, false); transform.localPosition = new Vector3(num, num2, PanelFront - 0.025f - 0.004f * (float)(i % 3)); transform.localRotation = Quaternion.Euler(0f, 0f, R(-7f, 7f)); ((Component)transform).gameObject.layer = ((Component)look.parent).gameObject.layer; BoxCollider val3 = ((Component)transform).gameObject.AddComponent<BoxCollider>(); val3.center = new Vector3(0f, 0f, -0.005f); val3.size = new Vector3(0.33f, 0.42f, 0.02f); ((Component)transform).gameObject.AddComponent<NoticePaper>(); GameObject val4 = new GameObject("paper"); val4.transform.SetParent(transform, false); val4.transform.localScale = new Vector3(0.33f, 0.42f, 1f); val4.AddComponent<MeshFilter>().sharedMesh = sharedMesh; ((Renderer)val4.AddComponent<MeshRenderer>()).sharedMaterial = Paper.For(i switch { 0 => Kind.Trophy, 2 => Kind.Kill, _ => (Kind)(i % 4), }, scene); ((Vector3)(ref val5))..ctor(0f, 0.16499999f, 0f); GameObject val6 = new GameObject("pin_nail"); val6.transform.SetParent(transform, false); if ((Object)(object)iron != (Object)null) { GameObject val7 = GameObject.CreatePrimitive((PrimitiveType)2); Object.DestroyImmediate((Object)(object)val7.GetComponent<Collider>()); ((Object)val7).name = "nail"; val7.transform.SetParent(val6.transform, false); val7.transform.localPosition = val5; val7.transform.localRotation = Quaternion.Euler(90f, 0f, 0f); val7.transform.localScale = new Vector3(0.022f, 0.012f, 0.022f); ((Renderer)val7.GetComponent<MeshRenderer>()).sharedMaterial = iron; } GameObject val8 = (((Object)(object)val != (Object)null) ? Stuck(transform, "pin_arrow", val, 2, pointHigh: false, 0.75f, 0.08f, val5, Quaternion.Euler(R(8f, 14f), R(-12f, 12f), 0f)) : null); GameObject val9 = (((Object)(object)val2 != (Object)null) ? Stuck(transform, "pin_knife", val2, 1, pointHigh: true, 0.32f, 0.13f, val5, Quaternion.Euler(R(-12f, -6f), R(-8f, 8f), R(0f, 360f))) : null); ((Component)transform).gameObject.SetActive(i % 2 == 0); Pin pin = i switch { 6 => Pin.Knife, 2 => Pin.Arrow, _ => Pin.Nail, }; val6.SetActive(pin == Pin.Nail); if ((Object)(object)val8 != (Object)null) { val8.SetActive(pin == Pin.Arrow); } if ((Object)(object)val9 != (Object)null) { val9.SetActive(pin == Pin.Knife); } } float R(float from, float to) { return from + (float)rnd.NextDouble() * (to - from); } } private static GameObject Stuck(Transform slot, string name, Transform source, int axis, bool pointHigh, float length, float buried, Vector3 at, Quaternion lean) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0057: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(slot, false); Transform val2 = Copy(val.transform, "model", source); Bounds bounds = ((Component)val2).GetComponent<MeshFilter>().sharedMesh.bounds; Vector3 zero = Vector3.zero; ((Vector3)(ref zero))[axis] = (pointHigh ? 1f : (-1f)); Vector3 val3 = ((Bounds)(ref bounds)).center + Vector3.Scale(zero, ((Bounds)(ref bounds)).extents); Vector3 size = ((Bounds)(ref bounds)).size; float num = length / ((Vector3)(ref size))[axis]; Quaternion val4 = (val2.localRotation = lean * Quaternion.FromToRotation(zero, Vector3.forward)); val2.localScale = Vector3.one * num; Vector3 val6 = at + lean * Vector3.forward * (0.025f + buried); val2.localPosition = val6 - val4 * (val3 * num); return val; } private static void AddPouch(Transform look, ZNetScene scene, Material iron) { //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_013f: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(-0.62f, 0.94f, PanelFront + 0.01f); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(-0.62f, 0.96f, PanelFront - 0.17f); if ((Object)(object)iron != (Object)null) { GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)2); Object.DestroyImmediate((Object)(object)val3.GetComponent<Collider>()); ((Object)val3).name = "wanted_hook"; val3.transform.SetParent(look, false); val3.transform.localPosition = (val + val2) / 2f; val3.transform.localRotation = Quaternion.FromToRotation(Vector3.up, val2 - val); Transform transform = val3.transform; Vector3 val4 = val2 - val; transform.localScale = new Vector3(0.018f, ((Vector3)(ref val4)).magnitude / 2f, 0.018f); ((Renderer)val3.GetComponent<MeshRenderer>()).sharedMaterial = iron; } Transform transform2 = new GameObject("wanted_pouch").transform; transform2.SetParent(look, false); transform2.localPosition = val2 + new Vector3(0f, -0.01f, 0.03f); transform2.localRotation = Quaternion.Euler(0f, 15f, 0f); transform2.localScale = Vector3.one * 2.2f; if ((Object)(object)PouchModel.Make(transform2, scene) == (Object)null) { Plugin.Log.LogWarning((object)"No material for the coin pouch: the board shows none"); } ((Component)transform2).gameObject.SetActive(false); } private static void AddColliders(GameObject board) { //IL_001c: 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_0050: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00d2: Unknown result type (might be due to invalid IL or missing references) Box("wanted_collider_post_l", new Vector3(-0.98f, 1.5f, 0.52f), new Vector3(0.3f, 3f, 0.3f)); Box("wanted_collider_post_r", new Vector3(0.98f, 1.5f, 0.52f), new Vector3(0.3f, 3f, 0.3f)); Box("wanted_collider_panel", new Vector3(0f, 1.6f, PanelFront + 0.025f), new Vector3(2.26f, 1.4000001f, 0.09f)); Box("wanted_collider_roof", new Vector3(0f, 2.8f, 0.52f), new Vector3(2.56f, 0.4f, 0.9f)); void Box(string name, Vector3 centre, Vector3 size) { //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_0018: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name) { layer = board.layer }; val.transform.SetParent(board.transform, false); BoxCollider val2 = val.AddComponent<BoxCollider>(); val2.center = centre; val2.size = size; val.AddComponent<BoardFace>(); } } private static void Flatten(Transform part) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown MeshRenderer component = ((Component)part).GetComponent<MeshRenderer>(); if ((Object)(object)_flatPlanks == (Object)null) { _flatPlanks = new Material(((Renderer)component).sharedMaterial) { name = "wanted_planks" }; if (_flatPlanks.HasProperty("_ValueNoiseVertex")) { _flatPlanks.SetFloat("_ValueNoiseVertex", 0f); } if (_flatPlanks.HasProperty("_RippleDistance")) { _flatPlanks.SetFloat("_RippleDistance", 0f); } _flatPlanks.DisableKeyword("_VALUENOISEVERTEX_ON"); } ((Renderer)component).sharedMaterial = _flatPlanks; } private static Transform Beam(Transform parent, Transform plank, Vector3 at, Vector3 size, float tilt) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) Transform val = Copy(parent, "beam", plank); val.localPosition = at; val.localRotation = Quaternion.Euler(0f, 0f, tilt); val.localScale = size; Fit(val); return val; } private static void Fit(Transform t) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0040: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = ((Component)t).GetComponent<MeshFilter>().sharedMesh.bounds; Vector3 localScale = t.localScale; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(localScale.x / ((Bounds)(ref bounds)).size.x, localScale.y / ((Bounds)(ref bounds)).size.y, localScale.z / ((Bounds)(ref bounds)).size.z); t.localScale = val; t.localPosition -= t.localRotation * Vector3.Scale(val, ((Bounds)(ref bounds)).center); } private static Transform Copy(Transform parent, string name, Transform source) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.AddComponent<MeshFilter>().sharedMesh = ((Component)source).GetComponent<MeshFilter>().sharedMesh; ((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterials = ((Renderer)((Component)source).GetComponent<MeshRenderer>()).sharedMaterials; return val.transform; } private static Mesh QuadMesh() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0029: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_00a1: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) Mesh val = new Mesh { name = "wanted_quad" }; val.vertices = (Vector3[])(object)new Vector3[4] { new Vector3(-0.5f, -0.5f, 0f), new Vector3(0.5f, -0.5f, 0f), new Vector3(-0.5f, 0.5f, 0f), new Vector3(0.5f, 0.5f, 0f) }; val.uv = (Vector2[])(object)new Vector2[4] { new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(0f, 1f), new Vector2(1f, 1f) }; val.triangles = new int[6] { 0, 2, 1, 2, 3, 1 }; val.RecalculateNormals(); val.RecalculateTangents(); val.RecalculateBounds(); return val; } private static Material MaterialOf(ZNetScene scene, string itemPrefab) { GameObject prefab = scene.GetPrefab(itemPrefab); MeshRenderer val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponentInChildren<MeshRenderer>(true) : null); if (!((Object)(object)val != (Object)null)) { return null; } return ((Renderer)val).sharedMaterial; } } internal static class Commands { private const string Owner = "Wanted"; private static readonly string[] ToolGuids = new string[2] { "com.quad.claudetools", "com.dhack.claudetools" }; private const string Usage = "wanted boards [radius]: the Wanted boards near the player, which way they face, their notices and materials | wanted names: prefab names the contract lists use that this game doesn't have, and the world's stage | wanted found: what discovery adds beyond the built-in lists (other mods' creatures, things, food, metals) | wanted spawns <creature>: its entries in the world's spawn lists | wanted sample [count] [stage]: notices as a board would write them, nothing posted | wanted post [count] [nail|arrow|knife ...]: put notices up on the nearest board now (single player, host or devcommands)"; private static BaseUnityPlugin _registeredWith; private static float _nextLook; internal static void Update() { if (Time.unscaledTime < _nextLook) { return; } _nextLook = Time.unscaledTime + 2f; BaseUnityPlugin val = null; string[] toolGuids = ToolGuids; foreach (string key in toolGuids) { if (Chainloader.PluginInfos.TryGetValue(key, out var value) && (Object)(object)value.Instance != (Object)null) { val = value.Instance; break; } } if ((Object)(object)val == (Object)null || val == _registeredWith) { return; } _registeredWith = val; try { MethodInfo method = ((object)val).GetType().GetMethod("RegisterCommand", BindingFlags.Static | BindingFlags.Public); if (!(method == null)) { Type type = method.GetParameters()[3].ParameterType.GetGenericArguments()[1].GetGenericArguments()[0]; MethodInfo method2 = type.GetMethod("Parse", new Type[1] { typeof(string) }); object obj = typeof(Commands).GetMethod("Wrap", BindingFlags.Static | BindingFlags.NonPublic).MakeGenericMethod(type).Invoke(null, new object[1] { method2 }); method.Invoke(null, new object[4] { "Wanted", "wanted", "wanted boards [radius]: the Wanted boards near the player, which way they face, their notices and materials | wanted names: prefab names the contract lists use that this game doesn't have, and the world's stage | wanted found: what discovery adds beyond the built-in lists (other mods' creatures, things, food, metals) | wanted spawns <creature>: its entries in the world's spawn lists | wanted sample [count] [stage]: notices as a board would write them, nothing posted | wanted post [count] [nail|arrow|knife ...]: put notices up on the nearest board now (single player, host or devcommands)", obj }); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Couldn't add the 'wanted' command to Claude Tools (" + ex.Message + ").")); } } private static Func<string[], Action<T>, Action<string>, IEnumerator> Wrap<T>(MethodInfo parse) { Func<string, T> toJson = (Func<string, T>)Delegate.CreateDelegate(typeof(Func<string, T>), parse); return (string[] args, Action<T> output, Action<string> error) => Run(args, delegate(object o) { output(toJson(JsonConvert.SerializeObject(o))); }, error); } internal static void Unregister() { try { ((object)_registeredWith)?.GetType().GetMethod("UnregisterAll", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, new object[1] { "Wanted" }); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Couldn't remove the 'wanted' command (" + ex.Message + ").")); } _registeredWith = null; } private static IEnumerator Run(string[] args, Action<object> output, Action<string> error) { //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_06ad: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected I4, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) try { string text = ((args.Length > 1) ? args[1].ToLowerInvariant() : ""); if (text == "spawns" && args.Length > 2) { List<string> list = new List<string>(); List<SpawnSystemList> list2 = new List<SpawnSystemList>(); GameObject prefab = ZNetScene.instance.GetPrefab("_ZoneCtrl"); SpawnSystem val = ((prefab != null) ? prefab.GetComponent<SpawnSystem>() : null); if ((Object)(object)val != (Object)null) { list2.AddRange(val.m_spawnLists); } foreach (SpawnSystemList item in list2) { foreach (SpawnData spawner in item.m_spawners) { if ((Object)(object)spawner.m_prefab != (Object)null && ((Object)spawner.m_prefab).name == args[2]) { list.Add($"{((Object)item).name}: biome={spawner.m_biome} ({(int)spawner.m_biome}) area={spawner.m_biomeArea} enabled={spawner.m_enabled} key='{spawner.m_requiredGlobalKey}' event='{spawner.m_requiredPersistentEvent}' night={spawner.m_spawnAtNight}/{spawner.m_spawnAtDay}"); } } } output(new Dictionary<string, object> { { "spawns", list } }); return null; } switch (text) { case "post": { if ((!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsServer()) && (!((Object)(object)Console.instance != (Object)null) || !((Terminal)Console.instance).IsCheatsEnabled())) { error("wanted post changes the world: single player, the host, or with devcommands."); return null; } Player me = Player.m_localPlayer; if ((Object)(object)me == (Object)null) { error("Not in a world."); return null; } NoticeBoard noticeBoard = (from b in NoticeBoard.Loaded where (Object)(object)b != (Object)null orderby Vector3.Distance(((Component)b).transform.position, ((Component)me).transform.position) select b).FirstOrDefault(); if ((Object)(object)noticeBoard == (Object)null || Vector3.Distance(((Component)noticeBoard).transform.position, ((Component)me).transform.position) > 20f) { error("No Wanted board within 20 m."); return null; } int result2; int count = ((args.Length <= 2 || !int.TryParse(args[2], out result2)) ? 1 : result2); List<Pin> list3 = new List<Pin>(); for (int num = 3; num < args.Length; num++) { if (Enum.TryParse<Pin>(args[num], ignoreCase: true, out var result3)) { list3.Add(result3); } } output(new Dictionary<string, object> { { "posted", noticeBoard.PostNow(count, list3) } }); return null; } case "sample": { int result4; int num2 = ((args.Length > 2 && int.TryParse(args[2], out result4)) ? result4 : 10); int result5; int forTier = ((args.Length > 3 && int.TryParse(args[3], out result5)) ? result5 : (-1)); Random rnd = new Random(); List<string> list4 = new List<string>(); for (int num3 = 0; num3 < num2; num3++) { Contract contract = Contracts.Make(rnd, forTier); if (contract != null) { list4.Add($"t{contract.Tier} {contract.Kind} {contract.Target} x{contract.Count} -> {contract.Reward}"); } } output(new Dictionary<string, object> { { "sample", list4 } }); return null; } case "found": { Discovery.Forget(); List<Entry> list5 = ContractData.AllEntries().ToList(); output(new Dictionary<string, object> { { "found", (from e in Discovery.Found orderby e.Tier, e.Kind select $"{e.Kind} t{e.Tier} {e.Prefab} x{e.Count} @{e.Value} ({Contracts.DisplayName(e.Prefab)})").ToList() }, { "foundRewards", Discovery.FoundPay.Select((PayEntry p) => $"t{p.Tier} {p.Prefab} @{p.Value} ({Contracts.DisplayName(p.Prefab)})").ToList() }, { "arrows", (from a in Discovery.Ammo orderby a.Tier select $"t{a.Tier} {a.Prefab} @{a.Value} ({Contracts.DisplayName(a.Prefab)})").ToList() }, { "valuables", Discovery.Valuables.Select((PayEntry v) => $"{v.Prefab} @{v.Value} ({Contracts.DisplayName(v.Prefab)})").ToList() }, { "creaturesSkipped", Discovery.Skipped() }, { "builtIn", ContractData.Entries.Count }, { "total", list5.Count } }); return null; } case "names": output(new Dictionary<string, object> { { "unknown", Contracts.Unknown() }, { "worldTier", Contracts.WorldTier() } }); return null; default: { if (text != "boards") { output(new Dictionary<string, object> { { "usage", "wanted boards [radius]: the Wanted boards near the player, which way they face, their notices and materials | wanted names: prefab names the contract lists use that this game doesn't have, and the world's stage | wanted found: what discovery adds beyond the built-in lists (other mods' creatures, things, food, metals) | wanted spawns <creature>: its entries in the world's spawn lists | wanted sample [count] [stage]: notices as a board would write them, nothing posted | wanted post [count] [nail|arrow|knife ...]: put notices up on the nearest board now (single player, host or devcommands)" } }); return null; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { error("Not in a world."); return null; } float result; float radius = ((args.Length > 2 && float.TryParse(args[2], out result)) ? result : 30f); output(new Dictionary<string, object> { { "boards", Boards(((Component)localPlayer).transform.position, radius) } }); break; } } } catch (Exception ex) { error(ex.Message); } return null; } private static List<object> Boards(Vector3 from, float radius) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) List<object> list = new List<object>(); int stableHashCode = StringExtensionMethods.GetStableHashCode("nick_wanted_board"); ZNetView[] array = Object.FindObjectsByType<ZNetView>((FindObjectsSortMode)0); foreach (ZNetView val in array) { if ((Object)(object)val == (Object)null || val.GetZDO() == null || val.GetZDO().GetPrefab() != stableHashCode) { continue; } Transform transform = ((Component)val).transform; if (!(Vector3.Distance(transform.position, from) > radius)) { Transform val2 = transform.Find("wanted_look"); object obj; if (!((Object)(object)val2 != (Object)null)) { obj = null; } else { Transform obj2 = val2.Find("plank"); obj = ((obj2 != null) ? ((Component)obj2).GetComponent<MeshRenderer>() : null); } MeshRenderer r = (MeshRenderer)obj; object obj3; if (!((Object)(object)val2 != (Object)null)) { obj3 = null; } else { Transform obj4 = val2.Find("notice_0/paper"); obj3 = ((obj4 != null) ? ((Component)obj4).GetComponent<MeshRenderer>() : null); } MeshRenderer r2 = (MeshRenderer)obj3; list.Add(new Dictionary<string, object> { { "at", new float[3] { Round(transform.position.x), Round(transform.position.y), Round(transform.position.z) } }, { "yaw", Round(transform.eulerAngles.y) }, { "chest", ((Object)(object)transform.Find("wanted_chest") != (Object)null) ? "moved (0.1.3 or later)" : "in the middle (older)" }, { "plank", Describe((Renderer)(object)r) }, { "paper", Describe((Renderer)(object)r2) }, { "notices", val.GetZDO().GetString("Wanted.notices", "") }, { "day", val.GetZDO().GetInt("Wanted.day", -1) } }); } } return list; } private static object Describe(Renderer r) { if ((Object)(object)r == (Object)null) { return null; } Material sharedMaterial = r.sharedMaterial; if ((Object)(object)sharedMaterial == (Object)null) { return "no material"; } return new Dictionary<string, object> { { "material", ((Object)sharedMaterial).name }, { "wobble", sharedMaterial.HasProperty("_ValueNoiseVertex") ? sharedMaterial.GetFloat("_ValueNoiseVertex") : (-1f) }, { "wobbleKeyword", sharedMaterial.IsKeywordEnabled("_VALUENOISEVERTEX_ON") }, { "ripple", sharedMaterial.HasProperty("_RippleDistance") ? sharedMaterial.GetFloat("_RippleDistance") : (-1f) } }; } private static float Round(float v) { return (float)Math.Round(v, 3); } } internal sealed class Entry { public Kind Kind; public int Tier; public string Prefab; public int Count; public float Value; public Entry(Kind kind, int tier, string prefab, int count, float value) { Kind = kind; Tier = tier; Prefab = prefab; Count = count; Value = value; } } internal sealed class BonusEntry { public string Group; public int Tier; public string Prefab; public float Value; public BonusEntry(string group, int tier, string prefab, float value) { Group = group; Tier = tier; Prefab = prefab; Value = value; } } internal sealed class PayEntry { public int Tier; public string Prefab; public float Value; public PayEntry(int tier, string prefab, float value) { Tier = tier; Prefab = prefab; Value = value; } } internal static class ContractData { public const string SyncKey = "contracts"; public static List<Entry> Entries = new List<Entry>(Defaults()); public static List<PayEntry> Pay = new List<PayEntry>(DefaultPay()); public static List<BonusEntry> Bonus = new List<BonusEntry>(DefaultBonus()); public static HashSet<string> Removed = new HashSet<string>(); public static readonly Dictionary<string, int> ValuableTiers = new Dictionary<string, int> { { "Amber", 0 }, { "AmberPearl", 0 }, { "Ruby", 1 }, { "SilverNecklace", 2 }, { "AncientCoin", 7 }, { "AncientGemstoneGreen", 7 }, { "AncientGemstoneOrange", 7 }, { "AncientGemstonePurple", 7 }, { "AncientGemstoneBlack", 7 } }; private const string Example = "{\r\n \"_help\": [\r\n \"Add things Wanted notices can ask for, or pay in, and take built-in ones out. Kinds: Kill (a creature prefab), Gather, Trophy,\",\r\n \"Provisions (item prefabs), Pay (an item notices of that stage pay in), Rare and Refined (bonuses now and then paid on top).\",\r\n \"Other mods' creatures, items, food, meads, arrows and valuables are found by themselves: this is for fine-tuning. Tier: 0 Meadows, 1 Black Forest, 2 Swamp,\",\r\n \"3 Mountain, 4 Plains, 5 Mistlands, 6 Ashlands, 7 Deep North. Count: a usual amount (a notice asks for it, give or take a fifth).\",\r\n \"Value: what one is worth in coins; the reward is the notice's worth times a premium for its kind. Remove: prefab names to drop\",\r\n \"from the built-in lists. Names this game doesn't have are skipped (Claude Tools: wanted names). On a server, the server's file\",\r\n \"applies to everyone. Changes apply to notices posted afterwards.\"\r\n ],\r\n \"add\": [\r\n { \"kind\": \"Provisions\", \"tier\": 1, \"prefab\": \"ExampleModStew\", \"count\": 4, \"value\": 10 }\r\n ],\r\n \"remove\": []\r\n}\r\n"; public static string FilePath => Path.Combine(Paths.ConfigPath, "nick.valheim.wanted.contracts.json"); public static IEnumerable<Entry> AllEntries() { Discovery.Ensure(); return Entries.Concat(Discovery.Found.Where((Entry f) => !Removed.Contains(f.Prefab))); } public static IEnumerable<PayEntry> AllPay() { Discovery.Ensure(); return Pay.Concat(Discovery.FoundPay.Where((PayEntry f) => !Removed.Contains(f.Prefab))); } private static IEnumerable<Entry> Defaults() { return new Entry[191] { K(0, "Boar", 6, 3f), K(0, "Deer", 5, 3f), K(0, "Neck", 6, 2f), K(0, "Greyling", 8, 2f), T(0, "TrophyBoar", 3, 10f), T(0, "TrophyDeer", 3, 8f), T(0, "TrophyNeck", 3, 8f), G(0, "Wood", 40, 0.5f), G(0, "Stone", 30, 0.5f), G(0, "Flint", 15, 1f), G(0, "Resin", 15, 1f), G(0, "LeatherScraps", 15, 1f), G(0, "DeerHide", 8, 2f), G(0, "Raspberry", 20, 0.5f), G(0, "Mushroom", 15, 1f), G(0, "Feathers", 10, 1f), G(0, "Honey", 6, 2f), P(0, "CookedMeat", 8, 3f), P(0, "CookedDeerMeat", 6, 3f), P(0, "NeckTailGrilled", 8, 2f), K(1, "Greydwarf", 8, 3f), K(1, "Greydwarf_Elite", 3, 10f), K(1, "Greydwarf_Shaman", 3, 8f), K(1, "Skeleton", 6, 4f), K(1, "Troll", 1, 40f), T(1, "TrophyGreydwarf", 5, 8f), T(1, "TrophyGreydwarfBrute", 2, 25f), T(1, "TrophyGreydwarfShaman", 2, 25f), T(1, "TrophySkeleton", 3, 20f), T(1, "TrophyFrostTroll", 1, 60f), G(1, "CopperOre", 15, 5f), G(1, "TinOre", 15, 5f), G(1, "GreydwarfEye", 15, 1f), G(1, "BoneFragments", 15, 1f), G(1, "Thistle", 10, 2f), G(1, "Blueberries", 20, 1f), G(1, "SurtlingCore", 4, 8f), G(1, "RoundLog", 20, 2f), G(1, "TrollHide", 4, 8f), P(1, "QueensJam", 6, 6f), P(1, "DeerStew", 5, 8f), P(1, "CarrotSoup", 5, 6f), P(1, "MinceMeatSauce", 5, 8f), P(1, "BoarJerky", 6, 6f), P(1, "MeadHealthMinor", 4, 10f), P(1, "MeadStaminaMinor", 4, 10f), P(1, "MeadTasty", 4, 8f), K(2, "Draugr", 6, 8f), K(2, "Draugr_Elite", 3, 20f), K(2, "Blob", 6, 6f), K(2, "Leech", 5, 6f), K(2, "Surtling", 5, 8f), K(2, "Wraith", 2, 25f), K(2, "Abomination", 1, 60f), T(2, "TrophyDraugr", 3, 30f), T(2, "TrophyDraugrElite", 2, 40f), T(2, "TrophyBlob", 3, 20f), T(2, "TrophyLeech", 3, 20f), T(2, "TrophySurtling", 3, 20f), T(2, "TrophyWraith", 1, 60f), T(2, "TrophyAbomination", 1, 100f), G(2, "IronScrap", 20, 14f), G(2, "Guck", 10, 3f), G(2, "Ooze", 10, 2f), G(2, "WitheredBone", 4, 10f), G(2, "Bloodbag", 10, 3f), G(2, "Entrails", 10, 2f), G(2, "ElderBark", 20, 2f), G(2, "FineWood", 20, 1.5f), G(2, "Chain", 2, 15f), P(2, "Sausages", 6, 8f), P(2, "TurnipStew", 5, 8f), P(2, "BlackSoup", 5, 8f), P(2, "ShocklateSmoothie", 4, 10f), P(2, "MeadPoisonResist", 4, 15f), P(2, "MeadHealthMedium", 4, 15f), P(2, "MeadStaminaMedium", 4, 15f), K(3, "Wolf", 5, 12f), K(3, "Hatchling", 4, 15f), K(3, "Fenring", 2, 30f), K(3, "StoneGolem", 1, 80f), K(3, "Ulv", 3, 20f), K(3, "Bat", 6, 5f), T(3, "TrophyWolf", 3, 30f), T(3, "TrophyHatchling", 3, 30f), T(3, "TrophyFenring", 2, 60f), T(3, "TrophySGolem", 1, 120f), T(3, "TrophyUlv", 2, 50f), G(3, "SilverOre", 20, 18f), G(3, "Obsidian", 20, 3f), G(3, "WolfPelt", 8, 5f), G(3, "FreezeGland", 8, 5f), G(3, "Crystal", 8, 6f), G(3, "WolfFang", 8, 4f), P(3, "OnionSoup", 5, 12f), P(3, "Eyescream", 5, 12f), P(3, "CookedWolfMeat", 8, 6f), P(3, "WolfMeatSkewer", 5, 12f), P(3, "WolfJerky", 6, 10f), P(3, "MeadFrostResist", 4, 20f), K(4, "Goblin", 6, 15f), K(4, "GoblinBrute", 2, 50f), K(4, "GoblinShaman", 2, 30f), K(4, "Deathsquito", 4, 15f), K(4, "Lox", 2, 40f), K(4, "BlobTar", 4, 15f), T(4, "TrophyGoblin", 3, 40f), T(4, "TrophyGoblinBrute", 1, 80f), T(4, "TrophyGoblinShaman", 1, 60f), T(4, "TrophyDeathsquito", 3, 40f), T(4, "TrophyLox", 2, 60f), T(4, "TrophyGrowth", 2, 40f), G(4, "BlackMetalScrap", 20, 22f), G(4, "Barley", 30, 2f), G(4, "Flax", 30, 2f), G(4, "Needle", 15, 4f), G(4, "LoxPelt", 6, 10f), G(4, "Tar", 15, 4f), G(4, "Cloudberry", 20, 2f), P(4, "Bread", 5, 15f), P(4, "LoxPie", 4, 25f), P(4, "BloodPudding", 5, 15f), P(4, "FishWraps", 5, 20f), P(4, "CookedLoxMeat", 8, 10f), P(4, "BarleyWine", 4, 25f), K(5, "Seeker", 6, 25f), K(5, "SeekerBrute", 1, 100f), K(5, "Tick", 6, 10f), K(5, "Gjall", 1, 120f), K(5, "Hare", 6, 8f), T(5, "TrophySeeker", 3, 50f), T(5, "TrophySeekerBrute", 1, 150f), T(5, "TrophyTick", 3, 30f), T(5, "TrophyGjall", 1, 200f), T(5, "TrophyHare", 3, 25f), G(5, "Softtissue", 20, 6f), G(5, "Carapace", 20, 8f), G(5, "YggdrasilWood", 30, 3f), G(5, "BlackMarble", 20, 3f), G(5, "Sap", 15, 4f), G(5, "MushroomMagecap", 10, 4f), G(5, "MushroomJotunPuffs", 10, 4f), G(5, "RoyalJelly", 10, 4f), P(5, "MisthareSupreme", 4, 30f), P(5, "Salad", 5, 20f), P(5, "MushroomOmelette", 5, 20f), P(5, "MeatPlatter", 4, 30f), P(5, "HoneyGlazedChicken", 4, 30f), P(5, "CookedHareMeat", 8, 10f), P(5, "MeadEitrMinor", 4, 30f), P(5, "MeadStaminaLingering", 4, 30f), P(5, "MeadHealthLingering", 4, 30f), K(6, "Charred_Melee", 6, 30f), K(6, "Charred_Archer", 4, 30f), K(6, "Charred_Mage", 2, 50f), K(6, "Asksvin", 4, 30f), K(6, "Morgen", 1, 150f), K(6, "Volture", 4, 25f), K(6, "FallenValkyrie", 1, 150f), K(6, "BlobLava", 4, 20f), T(6, "TrophyCharredMelee", 3, 60f), T(6, "TrophyCharredArcher", 2, 60f), T(6, "TrophyCharredMage", 2, 80f), T(6, "TrophyAsksvin", 3, 50f), T(6, "TrophyMorgen", 1, 250f), T(6, "TrophyVolture", 3, 50f), T(6, "TrophyFallenValkyrie", 1, 250f), G(6, "FlametalOreNew", 20, 30f), G(6, "CharcoalResin", 20, 4f), G(6, "Blackwood", 30, 3f), G(6, "AskHide", 6, 10f), G(6, "CelestialFeather", 3, 25f), G(6, "Grausten", 30, 1f), P(6, "ScorchingMedley", 4, 35f), P(6, "PiquantPie", 4, 35f), P(6, "SizzlingBerryBroth", 4, 35f), P(6, "MashedMeat", 4, 35f), P(6, "CookedVoltureMeat", 8, 12f), P(6, "CookedAsksvinMeat", 8, 12f), P(1, "nick_oil_ember", 3, 8f), P(1, "nick_oil_keen", 3, 8f), P(1, "nick_oil_trollfat", 3, 10f), P(1, "nick_oil_barkhide", 3, 10f), P(2, "nick_oil_venom", 3, 14f), P(2, "nick_oil_leech", 3, 14f), P(3, "nick_oil_rime", 3, 18f), P(4, "nick_oil_storm", 3, 24f), P(4, "nick_oil_loxfat", 3, 24f), P(5, "nick_oil_wisp", 3, 32f), P(5, "nick_oil_royal", 3, 32f), P(6, "nick_oil_cinder", 3, 40f) }; static Entry G(int t, string p, int n, float v) { return new Entry(Kind.Gather, t, p, n, v); } static Entry K(int t, string p, int n, float v) { return new Entry(Kind.Kill, t, p, n, v); } static Entry P(int t, string p, int n, float v) { return new Entry(Kind.Provisions, t, p, n, v); } static Entry T(int t, string p, int n, float v) { return new Entry(Kind.Trophy, t, p, n, v); } } private static IEnumerable<PayEntry> DefaultPay() { return new PayEntry[13] { new PayEntry(0, "Resin", 1f), new PayEntry(0, "Flint", 1f), new PayEntry(0, "LeatherScraps", 1f), new PayEntry(0, "DeerHide", 2f), new PayEntry(1, "Copper", 5f), new PayEntry(1, "Tin", 5f), new PayEntry(1, "Bronze", 12f), new PayEntry(2, "Iron", 14f), new PayEntry(3, "Silver", 18f), new PayEntry(4, "BlackMetal", 22f), new PayEntry(5, "BlackMarble", 3f), new PayEntry(5, "Carapace", 8f), new PayEntry(6, "FlametalNew", 30f) }; } private static IEnumerable<BonusEntry> DefaultBonus() { return new BonusEntry[16] { R(1, "AncientSeed", 40f), R(1, "SurtlingCore", 15f), R(2, "WitheredBone", 40f), R(2, "Chain", 25f), R(3, "DragonTear", 80f), R(4, "GoblinTotem", 80f), R(4, "YmirRemains", 60f), R(4, "Thunderstone", 60f), R(5, "DvergrKeyFragment", 100f), R(5, "BlackCore", 80f), R(6, "BellFragment", 150f), R(6, "MoltenCore", 80f), F(1, "BronzeNails", 1.2f), F(2, "IronNails", 1.4f), F(4, "LinenThread", 3f), F(5, "Eitr", 25f) }; static BonusEntry F(int t, string p, float v) { return new BonusEntry("Refined", t, p, v); } static BonusEntry R(int t, string p, float v) { return new BonusEntry("Rare", t, p, v); } } public static string OwnText() { try { if (!File.Exists(FilePath)) { File.WriteAllText(FilePath, "{\r\n \"_help\": [\r\n \"Add things Wanted notices can ask for, or pay in, and take built-in ones out. Kinds: Kill (a creature prefab), Gather, Trophy,\",\r\n \"Provisions (item prefabs), Pay (an item notices of that stage pay in), Rare and Refined (bonuses now and then paid on top).\",\r\n \"Other mods' creatures, items, food, meads, arrows and valuables are found by themselves: this is for fine-tuning. Tier: 0 Meadows, 1 Black Forest, 2 Swamp,\",\r\n \"3 Mountain, 4 Plains, 5 Mistlands, 6 Ashlands, 7 Deep North. Count: a usual amount (a notice asks for it, give or take a fifth).\",\r\n \"Value: what one is worth in coins; the reward is the notice's worth times a premium for its kind. Remove: prefab names to drop\",\r\n \"from the built-in lists. Names this game doesn't have are skipped (Claude Tools: wanted names). On a server, the server's file\",\r\n \"applies to everyone. Changes apply to notices posted afterwards.\"\r\n ],\r\n \"add\": [\r\n { \"kind\": \"Provisions\", \"tier\": 1, \"prefab\": \"ExampleModStew\", \"count\": 4, \"value\": 10 }\r\n ],\r\n \"remove\": []\r\n}\r\n"); } return File.ReadAllText(FilePath); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not read " + FilePath + ": " + ex.Message)); return ""; } } public static void Use(string text) { //IL_010f: Unknown result type (might be due to invalid IL or missing references) List<Entry> list = new List<Entry>(Defaults()); List<PayEntry> list2 = new List<PayEntry>(DefaultPay()); HashSet<string> removed = new HashSet<string>(); List<BonusEntry> list3 = new List<BonusEntry>(DefaultBonus()); try { if (!string.IsNullOrWhiteSpace(text)) { JObject val = JObject.Parse(text); HashSet<string> removed2 = default(HashSet<string>); ref HashSet<string> reference = ref removed2; JToken obj = val["remove"]; reference = new HashSet<string>((from s in ((IEnumerable<JToken>)((obj is JArray) ? obj : null))?.Select((JToken t) => (string)t) where s != null select s) ?? Enumerable.Empty<string>()); removed = removed2; list.RemoveAll((Entry e) => removed2.Contains(e.Prefab)); list2.RemoveAll((PayEntry p) => removed2.Contains(p.Prefab)); list3.RemoveAll((BonusEntry b) => removed2.Contains(b.Prefab)); JToken obj2 = val["add"]; foreach (JToken item in (JArray)(((object)((obj2 is JArray) ? obj2 : null)) ?? ((object)new JArray()))) { string text2 = (string)item[(object)"kind"]; string text3 = (string)item[(object)"prefab"]; int valueOrDefault = ((int?)item[(object)"tier"]).GetValueOrDefault(); if (!string.IsNullOrEmpty(text3) && valueOrDefault >= 0 && valueOrDefault < 8) { Kind result; if (string.Equals(text2, "rare", StringComparison.OrdinalIgnoreCase) || string.Equals(text2, "refined", StringComparison.OrdinalIgnoreCase)) { list3.Add(new BonusEntry(char.ToUpperInvariant(text2[0]) + text2.Substring(1).ToLowerInvariant(), valueOrDefault, text3, ((float?)item[(object)"value"]) ?? 1f)); } else if (string.Equals(text2, "pay", StringComparison.OrdinalIgnoreCase)) { list2.Add(new PayEntry(valueOrDefault, text3, ((float?)item[(object)"value"]) ?? 1f)); } else if (Enum.TryParse<Kind>(text2, ignoreCase: true, out result)) { list.Add(new Entry(result, valueOrDefault, text3, Math.Max(1, ((int?)item[(object)"count"]) ?? 1), ((float?)item[(object