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 RavenwoodBalrondPieces v2.0.0
plugins/RavenwoodBalrondPieces/RavenwoodBalrondPieces.dll
Decompiled 5 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using Balrond.Shared; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; using ServerSync; using TMPro; using UnityEngine; using UnityEngine.Audio; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("RavenwoodBalrondPieces")] [assembly: AssemblyDescription("Ravenwood building and furniture piece collection")] [assembly: AssemblyCompany("Balrond")] [assembly: AssemblyProduct("RavenwoodBalrondPieces")] [assembly: ComVisible(false)] [assembly: Guid("FE018D9B-F2F6-4BDC-AB33-0A5CFCCB04B9")] [assembly: AssemblyFileVersion("1.0.2.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.2.0")] [module: UnverifiableCode] namespace Balrond.Shared { public static class AudioRoutingService { public enum AudioRoute { SFX, Ambient, Music, Master } private enum TargetKind { Route, NamedRuntimeGroup } private sealed class AudioTarget { public TargetKind Kind; public AudioRoute Route; public string RuntimeGroupName; public string Reason; } private sealed class AudioBinding { public AudioSource Source; public AudioTarget Target; } private sealed class ProcessedNode { public GameObject Root; public readonly List<AudioBinding> AudioBindings = new List<AudioBinding>(); public readonly List<GameObject> ReferencedRoots = new List<GameObject>(); public readonly HashSet<GameObject> ReferencedRootSet = new HashSet<GameObject>(ReferenceComparer<GameObject>.Instance); } private sealed class ExplicitOverride { public bool UsesNamedGroup; public AudioRoute Route; public string RuntimeGroupName; } private sealed class RuntimeMixerCatalog { private readonly Dictionary<string, AudioMixerGroup> _groupsByName = new Dictionary<string, AudioMixerGroup>(StringComparer.OrdinalIgnoreCase); private AudioMixer _mixer; private AudioMixerGroup _master; private AudioMixerGroup _ambient; private AudioMixerGroup _music; private AudioMixerGroup _sfx; public bool IsReady => (Object)(object)_mixer != (Object)null || (Object)(object)_master != (Object)null || (Object)(object)_ambient != (Object)null || (Object)(object)_music != (Object)null; public void Rebuild(AudioMan audioMan) { _groupsByName.Clear(); _mixer = null; _master = null; _ambient = null; _music = null; _sfx = null; if ((Object)(object)audioMan == (Object)null) { return; } _master = ReadAudioManGroup(audioMan, "m_masterMixer"); _ambient = ReadAudioManGroup(audioMan, "m_ambientMixer"); _music = ReadAudioManGroup(audioMan, "m_musicMixer"); _mixer = GetMixer(_master) ?? GetMixer(_ambient) ?? GetMixer(_music); AddGroup(_master); AddGroup(_ambient); AddGroup(_music); if ((Object)(object)_mixer != (Object)null) { try { AudioMixerGroup[] array = _mixer.FindMatchingGroups(string.Empty); if (array != null) { for (int i = 0; i < array.Length; i++) { AddGroup(array[i]); } } } catch (Exception ex) { Warn("Could not enumerate runtime AudioMixer groups: " + ex.Message); } } _sfx = FindNamedGroup("SFX"); if ((Object)(object)_sfx == (Object)null) { _sfx = QueryExactGroup("SFX"); } if ((Object)(object)_sfx == (Object)null) { AudioMixerGroup val = FindNamedGroup("Effects"); if ((Object)(object)val == (Object)null) { val = QueryExactGroup("Effects"); } _sfx = val; } if ((Object)(object)_sfx == (Object)null) { _sfx = _master; WarnOnce("sfx-group-fallback", "Runtime SFX mixer group was not found. Falling back to the AudioMan master output group."); } } public AudioMixerGroup Resolve(AudioTarget target) { if (target == null) { return ResolveRoute(AudioRoute.SFX); } if (target.Kind == TargetKind.NamedRuntimeGroup) { AudioMixerGroup val = FindNamedGroup(target.RuntimeGroupName); if ((Object)(object)val == (Object)null) { val = QueryExactGroup(target.RuntimeGroupName); } if ((Object)(object)val != (Object)null) { return val; } return ResolveRoute(AudioRoute.SFX); } return ResolveRoute(target.Route); } public bool HasNamedGroup(string groupName) { if (string.IsNullOrEmpty(groupName)) { return false; } return (Object)(object)FindNamedGroup(groupName) != (Object)null || (Object)(object)QueryExactGroup(groupName) != (Object)null; } private AudioMixerGroup ResolveRoute(AudioRoute route) { return (AudioMixerGroup)(route switch { AudioRoute.Ambient => _ambient ?? _sfx ?? _master, AudioRoute.Music => _music ?? _sfx ?? _master, AudioRoute.Master => _master ?? _sfx ?? _ambient ?? _music, _ => _sfx ?? _master ?? _ambient ?? _music, }); } private AudioMixerGroup FindNamedGroup(string groupName) { if (!string.IsNullOrEmpty(groupName) && _groupsByName.TryGetValue(groupName, out var value)) { return value; } return null; } private AudioMixerGroup QueryExactGroup(string groupName) { if ((Object)(object)_mixer == (Object)null || string.IsNullOrEmpty(groupName)) { return null; } try { AudioMixerGroup[] array = _mixer.FindMatchingGroups(groupName); if (array == null) { return null; } foreach (AudioMixerGroup val in array) { AddGroup(val); if ((Object)(object)val != (Object)null && string.Equals(((Object)val).name, groupName, StringComparison.OrdinalIgnoreCase)) { return val; } } } catch (Exception ex) { WarnOnce("query-group-" + groupName, "Could not query runtime AudioMixer group '" + groupName + "': " + ex.Message); } return null; } private void AddGroup(AudioMixerGroup group) { if (!((Object)(object)group == (Object)null) && !string.IsNullOrEmpty(((Object)group).name) && !_groupsByName.ContainsKey(((Object)group).name)) { _groupsByName.Add(((Object)group).name, group); } } private static AudioMixer GetMixer(AudioMixerGroup group) { try { return ((Object)(object)group != (Object)null) ? group.audioMixer : null; } catch { return null; } } private static AudioMixerGroup ReadAudioManGroup(AudioMan audioMan, string fieldName) { try { FieldInfo field = typeof(AudioMan).GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { return null; } object value = field.GetValue(audioMan); AudioMixerGroup val = (AudioMixerGroup)((value is AudioMixerGroup) ? value : null); if ((Object)(object)val != (Object)null) { return val; } AudioSource val2 = (AudioSource)((value is AudioSource) ? value : null); if ((Object)(object)val2 != (Object)null) { return val2.outputAudioMixerGroup; } } catch (Exception ex) { WarnOnce("audioman-field-" + fieldName, "Could not read AudioMan." + fieldName + ": " + ex.Message); } return null; } } private sealed class ReferenceComparer<T> : IEqualityComparer<T> where T : class { public static readonly ReferenceComparer<T> Instance = new ReferenceComparer<T>(); public bool Equals(T x, T y) { return x == y; } public int GetHashCode(T obj) { return RuntimeHelpers.GetHashCode(obj); } } private const int MaxManagedDepth = 24; private const int MaxCollectionEntries = 4096; private static readonly RuntimeMixerCatalog MixerCatalog = new RuntimeMixerCatalog(); private static readonly Dictionary<string, ExplicitOverride> Overrides = new Dictionary<string, ExplicitOverride>(StringComparer.Ordinal); private static readonly Dictionary<GameObject, ProcessedNode> ProcessedNodes = new Dictionary<GameObject, ProcessedNode>(ReferenceComparer<GameObject>.Instance); private static readonly Dictionary<AudioSource, AudioBinding> SourceBindings = new Dictionary<AudioSource, AudioBinding>(ReferenceComparer<AudioSource>.Instance); private static readonly Dictionary<Type, FieldInfo[]> TraversalFields = new Dictionary<Type, FieldInfo[]>(); private static readonly HashSet<GameObject> RegisteredRootSet = new HashSet<GameObject>(ReferenceComparer<GameObject>.Instance); private static readonly List<GameObject> RegisteredRoots = new List<GameObject>(); private static readonly HashSet<GameObject> ActiveProcessing = new HashSet<GameObject>(ReferenceComparer<GameObject>.Instance); private static readonly HashSet<string> WarnedKeys = new HashSet<string>(StringComparer.Ordinal); private static Action<string> _infoLogger; private static Action<string> _warningLogger; private static Action<string> _errorLogger; public static bool DebugLogging { get; set; } public static void ConfigureLogging(Action<string> infoLogger, Action<string> warningLogger, Action<string> errorLogger) { _infoLogger = infoLogger; _warningLogger = warningLogger; _errorLogger = errorLogger; } public static void SetOverride(string gameObjectName, AudioRoute route) { if (!string.IsNullOrWhiteSpace(gameObjectName)) { Overrides[gameObjectName] = new ExplicitOverride { UsesNamedGroup = false, Route = route, RuntimeGroupName = null }; InvalidateClassificationCaches(); } } public static void SetOverrides(AudioRoute route, params string[] gameObjectNames) { if (gameObjectNames == null) { return; } bool flag = false; foreach (string text in gameObjectNames) { if (!string.IsNullOrWhiteSpace(text)) { Overrides[text] = new ExplicitOverride { UsesNamedGroup = false, Route = route, RuntimeGroupName = null }; flag = true; } } if (flag) { InvalidateClassificationCaches(); } } public static void SetMixerGroupOverride(string gameObjectName, string runtimeMixerGroupName) { if (!string.IsNullOrWhiteSpace(gameObjectName) && !string.IsNullOrWhiteSpace(runtimeMixerGroupName)) { Overrides[gameObjectName] = new ExplicitOverride { UsesNamedGroup = true, Route = AudioRoute.SFX, RuntimeGroupName = runtimeMixerGroupName }; InvalidateClassificationCaches(); } } public static void RemoveOverride(string gameObjectName) { if (!string.IsNullOrWhiteSpace(gameObjectName) && Overrides.Remove(gameObjectName)) { InvalidateClassificationCaches(); } } public static void Process(GameObject root) { if (IsUsable((Object)(object)root)) { RegisterRoot(root); if (MixerCatalog.IsReady) { ProcessRoot(root); } } } public static void Process(IEnumerable<GameObject> roots) { if (roots == null) { return; } foreach (GameObject root in roots) { if (IsUsable((Object)(object)root)) { RegisterRoot(root); } } if (!MixerCatalog.IsReady) { return; } for (int i = 0; i < RegisteredRoots.Count; i++) { GameObject val = RegisteredRoots[i]; if (IsUsable((Object)(object)val)) { ProcessRoot(val); } } } public static void OnAudioManAwake(AudioMan audioMan) { if ((Object)(object)audioMan == (Object)null) { return; } MixerCatalog.Rebuild(audioMan); if (!MixerCatalog.IsReady) { Error("AudioMan was available, but no usable runtime mixer group could be resolved."); return; } HashSet<GameObject> visited = new HashSet<GameObject>(ReferenceComparer<GameObject>.Instance); for (int i = 0; i < RegisteredRoots.Count; i++) { GameObject val = RegisteredRoots[i]; if (IsUsable((Object)(object)val)) { if (ProcessedNodes.TryGetValue(val, out var value)) { ValidateNodeGraph(value, visited); } else { ProcessRoot(val); } } } } private static void RegisterRoot(GameObject root) { if (RegisteredRootSet.Add(root)) { RegisteredRoots.Add(root); } } private static void ProcessRoot(GameObject root) { if (!MixerCatalog.IsReady || !IsUsable((Object)(object)root)) { return; } if (ProcessedNodes.TryGetValue(root, out var value)) { ValidateNodeGraph(value, new HashSet<GameObject>(ReferenceComparer<GameObject>.Instance)); } else { if (!ActiveProcessing.Add(root)) { return; } ProcessedNode processedNode = new ProcessedNode { Root = root }; ProcessedNodes[root] = processedNode; try { ScanAudioSources(root, processedNode); ScanBehaviourReferences(root, processedNode); } catch (Exception ex) { Error("Failed to process audio graph for '" + SafeName((Object)(object)root) + "': " + ex); } finally { ActiveProcessing.Remove(root); } } } private static void ScanAudioSources(GameObject root, ProcessedNode node) { AudioSource[] componentsInChildren; try { componentsInChildren = root.GetComponentsInChildren<AudioSource>(true); } catch (Exception ex) { Warn("Could not enumerate AudioSources under '" + SafeName((Object)(object)root) + "': " + ex.Message); return; } if (componentsInChildren == null) { return; } foreach (AudioSource val in componentsInChildren) { if (IsUsable((Object)(object)val)) { if (!SourceBindings.TryGetValue(val, out var value)) { value = new AudioBinding { Source = val, Target = ClassifySource(root, val) }; SourceBindings[val] = value; } if (!node.AudioBindings.Contains(value)) { node.AudioBindings.Add(value); } ApplyBinding(value, root); } } } private static void ScanBehaviourReferences(GameObject root, ProcessedNode node) { MonoBehaviour[] componentsInChildren; try { componentsInChildren = root.GetComponentsInChildren<MonoBehaviour>(true); } catch (Exception ex) { Warn("Could not enumerate MonoBehaviours under '" + SafeName((Object)(object)root) + "': " + ex.Message); return; } if (componentsInChildren == null) { return; } HashSet<object> managedVisited = new HashSet<object>(ReferenceComparer<object>.Instance); foreach (MonoBehaviour val in componentsInChildren) { if (IsUsable((Object)(object)val) && !(val is ZSFX)) { TraverseManagedObject(val, root, node, managedVisited, 0, isComponentRoot: true); } } } private static void TraverseManagedObject(object value, GameObject ownerRoot, ProcessedNode node, HashSet<object> managedVisited, int depth, bool isComponentRoot) { if (value == null || depth > 24) { return; } Type type = value.GetType(); if (!type.IsValueType && !managedVisited.Add(value)) { return; } FieldInfo[] traversalFields = GetTraversalFields(type, isComponentRoot); foreach (FieldInfo fieldInfo in traversalFields) { object value2; try { value2 = fieldInfo.GetValue(value); } catch { continue; } TraverseValue(value2, ownerRoot, node, managedVisited, depth + 1); } } private static void TraverseValue(object value, GameObject ownerRoot, ProcessedNode node, HashSet<object> managedVisited, int depth) { if (value == null || depth > 24) { return; } EffectList val = (EffectList)((value is EffectList) ? value : null); if (val != null) { TraverseEffectList(val, ownerRoot, node); return; } GameObject val2 = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val2 != (Object)null) { HandleReferencedGameObject(val2, ownerRoot, node); return; } Component val3 = (Component)((value is Component) ? value : null); if ((Object)(object)val3 != (Object)null) { if (IsUsable((Object)(object)val3)) { HandleReferencedGameObject(val3.gameObject, ownerRoot, node); } return; } AudioClip val4 = (AudioClip)((value is AudioClip) ? value : null); if ((Object)(object)val4 != (Object)null) { return; } Object val5 = (Object)((value is Object) ? value : null); if (val5 != (Object)null) { ScriptableObject val6 = (ScriptableObject)((value is ScriptableObject) ? value : null); if ((Object)(object)val6 != (Object)null) { TraverseManagedObject(val6, ownerRoot, node, managedVisited, depth, isComponentRoot: false); } return; } if (value is IDictionary dictionary) { int num = 0; { foreach (DictionaryEntry item in dictionary) { TraverseValue(item.Value, ownerRoot, node, managedVisited, depth + 1); num++; if (num >= 4096) { break; } } return; } } if (value is IEnumerable enumerable && !(value is string)) { int num2 = 0; { foreach (object item2 in enumerable) { TraverseValue(item2, ownerRoot, node, managedVisited, depth + 1); num2++; if (num2 >= 4096) { break; } } return; } } Type type = value.GetType(); if (ShouldTraverseManagedType(type)) { TraverseManagedObject(value, ownerRoot, node, managedVisited, depth, isComponentRoot: false); } } private static void TraverseEffectList(EffectList effectList, GameObject ownerRoot, ProcessedNode node) { EffectData[] effectPrefabs = effectList.m_effectPrefabs; if (effectPrefabs == null) { return; } for (int i = 0; i < effectPrefabs.Length; i++) { GameObject prefab = effectPrefabs[i].m_prefab; if (IsUsable((Object)(object)prefab)) { HandleReferencedGameObject(prefab, ownerRoot, node); } } } private static void HandleReferencedGameObject(GameObject referenced, GameObject ownerRoot, ProcessedNode ownerNode) { if (IsUsable((Object)(object)referenced) && IsUsable((Object)(object)ownerRoot) && !IsInsideHierarchy(referenced, ownerRoot)) { if (ownerNode.ReferencedRootSet.Add(referenced)) { ownerNode.ReferencedRoots.Add(referenced); } ProcessRoot(referenced); } } private static bool IsInsideHierarchy(GameObject candidate, GameObject root) { if (candidate == root) { return true; } try { Transform transform = candidate.transform; Transform transform2 = root.transform; return (Object)(object)transform != (Object)null && (Object)(object)transform2 != (Object)null && transform.IsChildOf(transform2); } catch { return false; } } private static AudioTarget ClassifySource(GameObject root, AudioSource source) { AudioTarget audioTarget = FindExplicitOverride(((Component)source).gameObject, root); if (audioTarget != null) { return audioTarget; } if (HierarchyHasSfxPrefix(((Component)source).gameObject, root)) { return RouteTarget(AudioRoute.SFX, "sfx_/vfx_/fx_ GameObject name"); } if (HierarchyHasZSFX(((Component)source).gameObject, root)) { return RouteTarget(AudioRoute.SFX, "ZSFX context"); } AudioMixerGroup val = null; try { val = source.outputAudioMixerGroup; } catch { val = null; } AudioTarget audioTarget2 = ClassifyOldMixerGroup(val); if (audioTarget2 != null) { return audioTarget2; } return RouteTarget(AudioRoute.SFX, "default SFX fallback"); } private static AudioTarget FindExplicitOverride(GameObject sourceObject, GameObject root) { Transform val = null; Transform val2 = null; try { val = (((Object)(object)sourceObject != (Object)null) ? sourceObject.transform : null); val2 = (((Object)(object)root != (Object)null) ? root.transform : null); } catch { return null; } while ((Object)(object)val != (Object)null) { string text = (((Object)(object)((Component)val).gameObject != (Object)null) ? ((Object)((Component)val).gameObject).name : null); if (!string.IsNullOrEmpty(text) && Overrides.TryGetValue(text, out var value)) { if (value.UsesNamedGroup) { return NamedTarget(value.RuntimeGroupName, "explicit mixer-group override on '" + text + "'"); } return RouteTarget(value.Route, "explicit route override on '" + text + "'"); } if (val == val2) { break; } val = val.parent; } return null; } private static bool HierarchyHasSfxPrefix(GameObject sourceObject, GameObject root) { Transform val = null; Transform val2 = null; try { val = (((Object)(object)sourceObject != (Object)null) ? sourceObject.transform : null); val2 = (((Object)(object)root != (Object)null) ? root.transform : null); } catch { return false; } while ((Object)(object)val != (Object)null) { string name = (((Object)(object)((Component)val).gameObject != (Object)null) ? ((Object)((Component)val).gameObject).name : null); if (HasSfxPrefix(name)) { return true; } if (val == val2) { break; } val = val.parent; } return false; } private static bool HierarchyHasZSFX(GameObject sourceObject, GameObject root) { Transform val = null; Transform val2 = null; try { val = (((Object)(object)sourceObject != (Object)null) ? sourceObject.transform : null); val2 = (((Object)(object)root != (Object)null) ? root.transform : null); } catch { return false; } while ((Object)(object)val != (Object)null) { try { if ((Object)(object)((Component)val).GetComponent<ZSFX>() != (Object)null) { return true; } } catch { } if (val == val2) { break; } val = val.parent; } return false; } private static AudioTarget ClassifyOldMixerGroup(AudioMixerGroup oldGroup) { if ((Object)(object)oldGroup == (Object)null || string.IsNullOrEmpty(((Object)oldGroup).name)) { return null; } string name = ((Object)oldGroup).name; if (IsGenericMasterName(name)) { return null; } if (ContainsInvariant(name, "ambient")) { return RouteTarget(AudioRoute.Ambient, "old mixer-group name: " + name); } if (ContainsInvariant(name, "music")) { return RouteTarget(AudioRoute.Music, "old mixer-group name: " + name); } if (ContainsInvariant(name, "sfx") || ContainsInvariant(name, "vfx") || ContainsInvariant(name, "effect")) { return RouteTarget(AudioRoute.SFX, "old mixer-group name: " + name); } if (MixerCatalog.HasNamedGroup(name)) { return NamedTarget(name, "matching runtime mixer-group name"); } return null; } private static bool HasSfxPrefix(string name) { if (string.IsNullOrEmpty(name)) { return false; } return name.StartsWith("sfx_", StringComparison.OrdinalIgnoreCase) || name.StartsWith("vfx_", StringComparison.OrdinalIgnoreCase) || name.StartsWith("fx_", StringComparison.OrdinalIgnoreCase); } private static bool IsGenericMasterName(string name) { return string.Equals(name, "Master", StringComparison.OrdinalIgnoreCase) || string.Equals(name, "MasterAudio", StringComparison.OrdinalIgnoreCase) || string.Equals(name, "Master Mixer", StringComparison.OrdinalIgnoreCase); } private static bool ContainsInvariant(string text, string fragment) { return text != null && fragment != null && text.IndexOf(fragment, StringComparison.OrdinalIgnoreCase) >= 0; } private static AudioTarget RouteTarget(AudioRoute route, string reason) { return new AudioTarget { Kind = TargetKind.Route, Route = route, RuntimeGroupName = null, Reason = reason }; } private static AudioTarget NamedTarget(string groupName, string reason) { return new AudioTarget { Kind = TargetKind.NamedRuntimeGroup, Route = AudioRoute.SFX, RuntimeGroupName = groupName, Reason = reason }; } private static void ApplyBinding(AudioBinding binding, GameObject semanticRoot) { if (binding == null || !IsUsable((Object)(object)binding.Source)) { return; } AudioMixerGroup val = MixerCatalog.Resolve(binding.Target); if ((Object)(object)val == (Object)null) { return; } AudioMixerGroup val2 = null; try { val2 = binding.Source.outputAudioMixerGroup; } catch { val2 = null; } if (val2 != val) { try { binding.Source.outputAudioMixerGroup = val; } catch (Exception ex) { Warn("Could not route AudioSource '" + SafeName((Object)(object)((Component)binding.Source).gameObject) + "' under '" + SafeName((Object)(object)semanticRoot) + "': " + ex.Message); return; } } if (DebugLogging) { Info("AudioSource '" + SafeName((Object)(object)((Component)binding.Source).gameObject) + "' under '" + SafeName((Object)(object)semanticRoot) + "' -> '" + ((Object)val).name + "' (" + ((binding.Target != null) ? binding.Target.Reason : "unknown") + ")."); } } private static void ValidateNodeGraph(ProcessedNode node, HashSet<GameObject> visited) { if (node == null || !IsUsable((Object)(object)node.Root) || !visited.Add(node.Root)) { return; } for (int i = 0; i < node.AudioBindings.Count; i++) { ApplyBinding(node.AudioBindings[i], node.Root); } for (int j = 0; j < node.ReferencedRoots.Count; j++) { GameObject val = node.ReferencedRoots[j]; if (IsUsable((Object)(object)val)) { if (ProcessedNodes.TryGetValue(val, out var value)) { ValidateNodeGraph(value, visited); } else { ProcessRoot(val); } } } } private static FieldInfo[] GetTraversalFields(Type type, bool isComponentRoot) { if (TraversalFields.TryGetValue(type, out var value)) { return value; } List<FieldInfo> list = new List<FieldInfo>(); Type type2 = type; while (type2 != null && type2 != typeof(object) && !(type2 == typeof(MonoBehaviour)) && !(type2 == typeof(Behaviour)) && !(type2 == typeof(Component)) && !(type2 == typeof(ScriptableObject)) && !(type2 == typeof(Object))) { FieldInfo[] array; try { array = type2.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } catch { array = null; } if (array != null) { foreach (FieldInfo fieldInfo in array) { if (ShouldInspectField(fieldInfo)) { list.Add(fieldInfo); } } } type2 = type2.BaseType; } value = list.ToArray(); TraversalFields[type] = value; return value; } private static bool ShouldInspectField(FieldInfo field) { if (field == null || field.IsStatic || field.IsLiteral || field.IsNotSerialized) { return false; } Type fieldType = field.FieldType; if (fieldType == null) { return false; } if (typeof(EffectList).IsAssignableFrom(fieldType) || typeof(GameObject).IsAssignableFrom(fieldType) || typeof(Component).IsAssignableFrom(fieldType) || typeof(ScriptableObject).IsAssignableFrom(fieldType)) { return true; } if (fieldType.IsArray || typeof(IEnumerable).IsAssignableFrom(fieldType)) { return true; } if (fieldType == typeof(object) || fieldType.IsInterface || fieldType.IsAbstract) { return HasSerializeReferenceAttribute(field); } return ShouldTraverseManagedType(fieldType); } private static bool HasSerializeReferenceAttribute(FieldInfo field) { try { object[] customAttributes = field.GetCustomAttributes(inherit: false); if (customAttributes == null) { return false; } foreach (object obj in customAttributes) { if (obj != null) { string fullName = obj.GetType().FullName; if (string.Equals(fullName, "UnityEngine.SerializeReference", StringComparison.Ordinal)) { return true; } } } } catch { } return false; } private static bool ShouldTraverseManagedType(Type type) { if (type == null || type.IsPrimitive || type.IsEnum || type.IsPointer) { return false; } if (type == typeof(string) || type == typeof(decimal) || type == typeof(DateTime) || type == typeof(TimeSpan) || type == typeof(Guid) || type == typeof(IntPtr) || type == typeof(UIntPtr) || type == typeof(Type)) { return false; } if (typeof(Delegate).IsAssignableFrom(type)) { return false; } if (typeof(Object).IsAssignableFrom(type)) { return typeof(ScriptableObject).IsAssignableFrom(type); } string text = type.Namespace ?? string.Empty; if (text.StartsWith("System", StringComparison.Ordinal) || text.StartsWith("UnityEngine", StringComparison.Ordinal)) { return false; } return type.IsClass || type.IsValueType; } private static void InvalidateClassificationCaches() { ProcessedNodes.Clear(); SourceBindings.Clear(); ActiveProcessing.Clear(); if (!MixerCatalog.IsReady) { return; } for (int i = 0; i < RegisteredRoots.Count; i++) { GameObject val = RegisteredRoots[i]; if (IsUsable((Object)(object)val)) { ProcessRoot(val); } } } private static bool IsUsable(Object obj) { if (obj == null) { return false; } try { return obj != (Object)null; } catch { return false; } } private static string SafeName(Object obj) { if (!IsUsable(obj)) { return "<null>"; } try { return obj.name ?? "<unnamed>"; } catch { return "<unavailable>"; } } private static void Info(string message) { if (_infoLogger != null) { _infoLogger("[AudioRoutingService] " + message); } } private static void Warn(string message) { if (_warningLogger != null) { _warningLogger("[AudioRoutingService] " + message); } } private static void Error(string message) { if (_errorLogger != null) { _errorLogger("[AudioRoutingService] " + message); } } private static void WarnOnce(string key, string message) { if (WarnedKeys.Add(key)) { Warn(message); } } } } namespace RavenwoodBalrondPieces { internal sealed class BuildPieceDefinition { internal string PrefabName { get; private set; } internal string DefaultRecipe { get; private set; } internal string CraftingStationPrefab { get; private set; } internal UsageTagFlags BaseUsage { get; private set; } internal string FuelPrefab { get; private set; } internal BuildPieceDefinition(string prefabName, string defaultRecipe, string craftingStationPrefab, UsageTagFlags baseUsage, string fuelPrefab = null) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) PrefabName = prefabName; DefaultRecipe = defaultRecipe; CraftingStationPrefab = craftingStationPrefab; BaseUsage = baseUsage; FuelPrefab = fuelPrefab; } } internal static class BuildPieceList { internal static readonly BuildPieceDefinition[] Definitions = new BuildPieceDefinition[149] { new BuildPieceDefinition("clutter_bookset1_bal", "FineWood:1,LeatherScraps:1,Resin:1,RWc_Deer:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("clutter_bookset2_bal", "FineWood:1,LeatherScraps:1,Resin:1,RWc_Deer:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("clutter_bookset3_bal", "FineWood:1,LeatherScraps:1,Resin:1,RWc_Deer:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("clutter_bottleset_bal", "RWc_Deer:5", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("clutter_cupset_bal", "RWc_Deer:5", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("clutter_tableset_bal", "RWc_Deer:5", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("Hearth_1x3_bal", "Stone:6,RWc_Deer:5", "piece_stonecutter", (UsageTagFlags)1, "Wood"), new BuildPieceDefinition("Hearth_2x3_bal", "Stone:12,RWc_Deer:5", "piece_stonecutter", (UsageTagFlags)1, "Wood"), new BuildPieceDefinition("Hearth_2x2_bal", "Stone:9,RWc_Deer:5", "piece_stonecutter", (UsageTagFlags)1, "Wood"), new BuildPieceDefinition("charred_chest_bal", "CharredBone:10,FlametalNew:10,MorgenHeart:1,RWc_Snake:1", "blackforge", (UsageTagFlags)128), new BuildPieceDefinition("dvergr_bed_bal", "Wood:2,ScaleHide:2,YggdrasilWood:2,RWc_Bear:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("dvergr_chair_bal", "LeatherScraps:2,YggdrasilWood:2,Copper:2,RWc_Bear:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("dvergr_chest_bal", "BronzeNails:12,YggdrasilWood:5,Copper:5,RWc_Snake:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("dvergr_shelf_bal", "Wood:2,YggdrasilWood:2,Copper:2,RWc_Bear:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("dvergr_stool_bal", "Wood:2,YggdrasilWood:2,Copper:2,RWc_Bear:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("dvergr_table_bal", "Wood:2,YggdrasilWood:2,Copper:2,RWc_Bear:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("piece_chest_private_bal", "BronzeNails:20,YggdrasilWood:5,DvergrKeyFragment:1,RWc_Bear:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("bed_noble_bal", "FineWood:5,JuteRed:2,LinenThread:5,RWc_Deer:5", "forge", (UsageTagFlags)128), new BuildPieceDefinition("black_carpet_end_bal", "TrollHide:1,LinenThread:1,Coal:4,RWc_Bear:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("black_carpet_mid_bal", "TrollHide:5,LinenThread:4,Coal:8,RWc_Bear:3", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("ground_spike_trap_bal", "Root:2,Wood:2,BoneFragments:5,RWc_Bear:3", "piece_workbench", (UsageTagFlags)1), new BuildPieceDefinition("piece_banner_black1_bal", "FineWood:1,LeatherScraps:4,Blueberries:2,RWc_Deer:3", "forge", (UsageTagFlags)128), new BuildPieceDefinition("piece_banner_black2_bal", "FineWood:1,LeatherScraps:4,Cloudberry:2,RWc_Deer:3", "forge", (UsageTagFlags)128), new BuildPieceDefinition("piece_banner_black3_bal", "FineWood:1,LeatherScraps:4,Guck:2,RWc_Deer:3", "forge", (UsageTagFlags)128), new BuildPieceDefinition("piece_banner_black4_bal", "FineWood:1,LeatherScraps:4,Bloodbag:2,RWc_Deer:3", "forge", (UsageTagFlags)128), new BuildPieceDefinition("piece_bed03_bal", "JuteRed:2,JuteBlue:4,YggdrasilWood:20,RWc_Snake:1", "piece_workbench", (UsageTagFlags)0), new BuildPieceDefinition("piece_candlechandelier_bal", "Honey:8,Chain:5,Iron:4,RWc_Snake:2", "forge", (UsageTagFlags)128, "Crystal"), new BuildPieceDefinition("piece_chest_jewelbox_bal", "FineWood:10,HardAntler:1,RWc_Deer:10", "forge", (UsageTagFlags)128), new BuildPieceDefinition("piece_chest_stone_bal", "Stone:30,Flint:10,SharpeningStone:1,RWc_Deer:5", "piece_stonecutter", (UsageTagFlags)128), new BuildPieceDefinition("piece_crystal_walltorch_bal", "Crystal:2,Iron:2,RWc_Wolf:1", "forge", (UsageTagFlags)128, "Crystal"), new BuildPieceDefinition("piece_crystalchandelier_bal", "Crystal:12,Iron:6,Chain:5,RWc_Wolf:2", "forge", (UsageTagFlags)128, "Resin"), new BuildPieceDefinition("piece_curtain_big_bal", "Silver:2,JuteRed:4,LeatherScraps:8,RWc_Wolf:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("piece_elegant_bench_bal", "Iron:1,Blackwood:4,JuteRed:1,RWc_Snake:1", "forge", (UsageTagFlags)0), new BuildPieceDefinition("piece_elegant_bench2_bal", "Iron:1,Blackwood:4,JuteRed:1,RWc_Snake:1", "forge", (UsageTagFlags)0), new BuildPieceDefinition("piece_emberwood_stool_bal", "Iron:1,Blackwood:2,JuteRed:1,RWc_Snake:1", "forge", (UsageTagFlags)0), new BuildPieceDefinition("piece_emberwoodchair_bal", "Iron:2,Blackwood:5,JuteRed:1,RWc_Snake:1", "forge", (UsageTagFlags)0), new BuildPieceDefinition("piece_table_round_noble_bal", "Iron:2,Blackwood:6,JuteRed:1,RWc_Snake:1", "forge", (UsageTagFlags)0), new BuildPieceDefinition("runefire_bal", "Thunderstone:2,TrophySkeleton:5,Flint:10,RWc_Bear:5", "piece_stonecutter", (UsageTagFlags)1, "TrophySkeleton"), new BuildPieceDefinition("linen_carpet_bal", "Bloodbag:2,LinenThread:10,RWc_Wolf:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("rug_neck_bal", "AskHide:2,RWc_Snake:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("rug_fox_bal", "LeatherScraps:20,RWc_Deer:5", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("rug_bear_bal", "BjornHide:4,RWc_Bear:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("wood_pillar4_bal", "Wood:4,RWc_Deer:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("wood_long_stair_bal", "FineWood:15,RWc_Deer:5", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("piece_grausten_roof_45_top_bal", "Grausten:5,RWc_Snake:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("dverger_gate_bal", "BlackMarble:12,Iron:6,MechanicalSpring:1,RWc_Lion:1", "blackforge", (UsageTagFlags)4), new BuildPieceDefinition("dvergr_secretdoor_bal", "BlackMarble:13,MechanicalSpring:1,RWc_Wolf:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("giant_metal_gate_bal", "BlackMarble:6,Iron:6,MechanicalSpring:1,RWc_Lion:1", "blackforge", (UsageTagFlags)4), new BuildPieceDefinition("blackmarble_floor4m_bal", "BlackMarble:12,RWc_Bear:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("blackmarble_roof27_bal", "BlackMarble:6,RWc_Bear:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("blackmarble_stair_inner_bal", "BlackMarble:6,RWc_Bear:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("blackmarble_stair_outer_bal", "BlackMarble:6,RWc_Bear:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("blackmarble_stone_ladder_bal", "BlackMarble:4,RWc_Bear:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("crystal_tile_floor_2x2_bal", "Crystal:3,RWc_Wolf:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("crystal_wall_2x2_bal", "Crystal:3,RWc_Wolf:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("emberwood_pillar2_bal", "RoundLog:3,Flint:2,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("emberwood_pillar4_bal", "RoundLog:6,Flint:4,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("plate_gate_bal", "FineWood:4,Iron:2,BlackMetal:4,RWc_Wolf:1", "forge", (UsageTagFlags)4), new BuildPieceDefinition("rawstone_pole_bal", "Stone:2,Flint:2,Wood:2,RWc_Deer:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("rune_floor_bal", "Stone:8,Crystal:4,RWc_Wolf:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("stone_floor_triangle_bal", "Stone:3,RWc_Deer:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("stone_long_stair_bal", "Stone:16,RWc_Deer:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("stone_pole_bal", "Stone:2,RWc_Deer:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("stone_railing_bal", "Stone:3,RWc_Deer:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("stone_roof27_bal", "Stone:6,RWc_Deer:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("stone_stair_corner_bal", "Stone:8,RWc_Deer:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("stone_stair_corner_left_bal", "Stone:8,RWc_Deer:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("stone_stair_inner_bal", "Stone:8,RWc_Deer:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("stone_stair_outer_bal", "Stone:8,RWc_Deer:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("stone_stair_railing_bal", "Stone:10,RWc_Deer:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("stone_stair_railing_left_bal", "Stone:9,RWc_Deer:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("stone_stair_railing_right_bal", "Stone:9,RWc_Deer:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("stone_stepladder_bal", "Stone:5,RWc_Deer:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("stonemoss_tile_floor_2x2_bal", "Stone:6,Wood:2,RWc_Deer:2", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("blackmarble_creep_slope_inverted_2x2x1_bal", "BlackMarble:2,RWc_Bear:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("blackmarble_1x1_enforced_bal", "BlackMarble:2,CopperScrap:1,RWc_Bear:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("stone_1x1_enforced_bal", "Stone:3,CopperScrap:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("blackmarble_Wall_Window_2x2_bal", "BlackMarble:4,RWc_Bear:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("stone_beam_bal", "Stone:2,RWc_Deer:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("blackmarble_long_stair_bal", "BlackMarble:16,RWc_Bear:1", "piece_stonecutter", (UsageTagFlags)4), new BuildPieceDefinition("clay_stair_bal", "Flint:2,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("ClayBeam_bal", "Flint:1,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("ClayCube_bal", "Flint:2,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("ClayPole_bal", "Flint:1,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("clayr_arch_bal", "Flint:1,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("ClayWall_bal", "Wood:2,Flint:2,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("bg_stake_wall_bal", "RoundLog:8,Wood:4,RWc_Bear:1", "piece_workbench", (UsageTagFlags)1), new BuildPieceDefinition("leather_roof_bal", "Wood:2,LeatherScraps:2,RWc_Deer:2", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("clay_floor_2x2_bal", "Wood:2,Flint:2,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("bush_roof_bal", "Wood:5,Dandelion:5,Thistle:5,RWc_Deer:5", "piece_workbench", (UsageTagFlags)0), new BuildPieceDefinition("bush_roof_top_bal", "Wood:5,Dandelion:5,Thistle:5,RWc_Deer:5", "piece_workbench", (UsageTagFlags)0), new BuildPieceDefinition("bush_roof_icorner_bal", "Wood:5,Dandelion:5,Thistle:5,RWc_Deer:5", "piece_workbench", (UsageTagFlags)0), new BuildPieceDefinition("bush_roof_ocorner_bal", "Wood:5,Dandelion:5,Thistle:5,RWc_Deer:5", "piece_workbench", (UsageTagFlags)0), new BuildPieceDefinition("piece_sharpstakes_big_bal", "Wood:10,RoundLog:10,RWc_Bear:1", "piece_workbench", (UsageTagFlags)1), new BuildPieceDefinition("Piece_hardwood_pillar_arch_bal", "RoundLog:3,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("Piece_hardwood_pillar_arch_small_bal", "RoundLog:1,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("Piece_hardwood_pillarbase_medium_bal", "RoundLog:2,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("Piece_hardwood_pillarbase_small_bal", "RoundLog:1,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("Piece_hardwood_pillarbase_tapered_bal", "RoundLog:3,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("Piece_hardwood_pillarbase_tapered_inverted_bal", "RoundLog:3,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("Piece_hardwood_pillarbeam_medium_bal", "RoundLog:2,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("Piece_hardwood_pillarbeam_small_bal", "RoundLog:1,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("piece_hardwood_roof_45_bal", "RoundLog:2,Flint:2,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("piece_hardwood_roof_45_arch_bal", "RoundLog:2,Flint:2,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("piece_hardwood_roof_45_arch_corner_bal", "RoundLog:2,Flint:2,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("piece_hardwood_roof_45_arch_corner2_bal", "RoundLog:2,Flint:2,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("piece_hardwood_roof_45_corner_bal", "RoundLog:2,Flint:2,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("piece_hardwood_roof_45_corner2_bal", "RoundLog:2,Flint:2,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("piece_hardwood_roof_45_top_bal", "RoundLog:2,Flint:2,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("wood_roof_flat_bal", "Wood:2,RWc_Deer:1", "piece_workbench", (UsageTagFlags)0), new BuildPieceDefinition("silver_ore_pile_bal", "SilverOre:30", "forge", (UsageTagFlags)1), new BuildPieceDefinition("bcopper_ore_pile_bal", "CopperOre:30", "forge", (UsageTagFlags)1), new BuildPieceDefinition("biron_ore_pile_bal", "IronScrap:30", "forge", (UsageTagFlags)1), new BuildPieceDefinition("bmetal_ore_pile_bal", "BlackMetalScrap:30", "forge", (UsageTagFlags)0), new BuildPieceDefinition("flametal_ore_pile_bal", "FlametalOreNew:30", "blackforge", (UsageTagFlags)0), new BuildPieceDefinition("straw_floor_2x2_bal", "Dandelion:5,RWc_Deer:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("rostrum_bal", "FineWood:3,Resin:3,RWc_Deer:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("sulfur_cauldron_bal", "BlackMetal:3,SulfurStone:3,RWc_Wolf:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("target_practice_bal", "Wood:3,Dandelion:3,LeatherScraps:3,RWc_Deer:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("fishing_rack_bal", "Wood:3,FishRaw:5,RWc_Deer:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("hardwood_door_bal", "RoundLog:3,IronScrap:2,RWc_Bear:1", "piece_workbench", (UsageTagFlags)4), new BuildPieceDefinition("animal_cages_bal", "Wood:10,LeatherScraps:5,RWc_Deer:3", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("supply_shelf_bal", "FineWood:5,Bronze:2,LeatherScraps:3,RWc_Bear:2", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("weapon_rack_bal", "Wood:6,Iron:1,Bronze:1,RWc_Snake:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("blackmarble_sarcophagus_bal", "BlackMarble:10,BoneFragments:10,DvergrKeyFragment:1,RWc_Wolf:1", "piece_stonecutter", (UsageTagFlags)128), new BuildPieceDefinition("bookcabinet_bal", "FineWood:8,LeatherScraps:10,RWc_Bear:5,RWc_Deer:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("herb_ladder_bal", "RoundLog:3,Dandelion:2,FreshSeaweed:2,RWc_Bear:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("hook_itemstand_bal", "Chain:1,Iron:2,RWc_Snake:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("itemstand26_inner_bal", "FineWood:2,Wood:1,RWc_Deer:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("itemstand26_outer_bal", "FineWood:2,Wood:1,RWc_Deer:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("itemstand45_inner_bal", "FineWood:2,Wood:1,RWc_Deer:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("itemstand45_outer_bal", "FineWood:2,Wood:1,RWc_Deer:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("piece_ashwood_echandelier_bal", "Flametal:4,Blackwood:2,Resin:4,RWc_Lion:1", "blackforge", (UsageTagFlags)128, "Resin"), new BuildPieceDefinition("piece_banner_metal1_long_bal", "Iron:1,LinenThread:2,Cloudberry:4,RWc_Wolf:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("piece_banner_metal2_long_bal", "Iron:1,LinenThread:2,Raspberry:4,RWc_Deer:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("piece_banner_metal3_long_bal", "Iron:1,LinenThread:2,Guck:4,RWc_Snake:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("piece_banner_metal4_long_bal", "Iron:1,LinenThread:2,Blueberries:4,RWc_Bear:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("piece_braziercolumn_bal", "Stone:12,Coal:2,Iron:1,RWc_Snake:1", "piece_stonecutter", (UsageTagFlags)1, "Coal"), new BuildPieceDefinition("piece_clamChest_bal", "BoneFragments:10,AmberPearl:1,RWc_Deer:2", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("piece_curtain_side_bal", "Silver:1,JuteBlue:2,LeatherScraps:4,RWc_Wolf:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("piece_sofa_bal", "JuteRed:4,JuteBlue:1,FineWood:9,RWc_Wolf:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("piece_sofa_reverse_bal", "JuteRed:4,JuteBlue:1,FineWood:9,RWc_Wolf:1", "forge", (UsageTagFlags)128), new BuildPieceDefinition("piece_table_drakkar_bal", "YggdrasilWood:20,CeramicPlate:20,BronzeNails:100,RWc_Lion:2", "blackforge", (UsageTagFlags)128), new BuildPieceDefinition("rostrum_itemstand_bal", "Stone:5,Flint:5,Resin:4,RWc_Deer:2", "piece_stonecutter", (UsageTagFlags)128), new BuildPieceDefinition("scarecrow_bal", "Wood:2,LeatherScraps:5,LinenThread:3,RWc_Snake:1", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("StatueRaven_bal", "Stone:20,RWc_Deer:5", "piece_stonecutter", (UsageTagFlags)1), new BuildPieceDefinition("StatueThor_bal", "BlackMarble:25,Stone:10,Ruby:2,RWc_Wolf:1", "piece_stonecutter", (UsageTagFlags)1), new BuildPieceDefinition("torn_carpet_bal", "Bloodbag:3,LinenThread:9,JuteRed:3,RWc_Snake:3", "piece_workbench", (UsageTagFlags)128), new BuildPieceDefinition("weathervane_bal", "Wood:5,Bronze:5,RWc_Bear:5", "forge", (UsageTagFlags)512) }; internal static readonly string[] buildPieces = CreateNameArray(); private static readonly Dictionary<string, BuildPieceDefinition> ByName = CreateMap(); internal static BuildPieceDefinition Find(string prefabName) { if (string.IsNullOrEmpty(prefabName)) { return null; } BuildPieceDefinition value; return ByName.TryGetValue(prefabName, out value) ? value : null; } private static string[] CreateNameArray() { string[] array = new string[Definitions.Length]; for (int i = 0; i < Definitions.Length; i++) { array[i] = Definitions[i].PrefabName; } return array; } private static Dictionary<string, BuildPieceDefinition> CreateMap() { Dictionary<string, BuildPieceDefinition> dictionary = new Dictionary<string, BuildPieceDefinition>(StringComparer.Ordinal); for (int i = 0; i < Definitions.Length; i++) { dictionary[Definitions[i].PrefabName] = Definitions[i]; } return dictionary; } } internal static class BuildPieceRecipeConfig { private const string GeneralSection = "1 - General"; private const string RecipeSection = "2 - Build Piece Recipes"; private static readonly Dictionary<string, ConfigEntry<string>> RecipeEntries = new Dictionary<string, ConfigEntry<string>>(StringComparer.Ordinal); internal static ConfigEntry<bool> LockConfiguration { get; private set; } internal static event Action<string> RecipeChanged; internal static void Initialize(Launch plugin) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown if ((Object)(object)plugin == (Object)null) { throw new ArgumentNullException("plugin"); } ResetEntries(); LockConfiguration = ((BaseUnityPlugin)plugin).Config.Bind<bool>("1 - General", "Lock Configuration", true, new ConfigDescription("When enabled, build-piece recipe settings are controlled by the server/host for connected clients.", (AcceptableValueBase)null, Array.Empty<object>())); ServerSyncBridge.AddLockingConfigEntry(LockConfiguration); BuildPieceDefinition[] definitions = BuildPieceList.Definitions; foreach (BuildPieceDefinition buildPieceDefinition in definitions) { string prefabName = buildPieceDefinition.PrefabName; ConfigEntry<string> val = ((BaseUnityPlugin)plugin).Config.Bind<string>("2 - Build Piece Recipes", prefabName, buildPieceDefinition.DefaultRecipe, new ConfigDescription("Recipe for '" + prefabName + "'. Format: ItemPrefab:Amount,ItemPrefab:Amount. Example: Stone:100 or Stone:80,Iron:10. Use NONE for a zero-cost piece.", (AcceptableValueBase)null, Array.Empty<object>())); val.SettingChanged += OnRecipeSettingChanged; RecipeEntries[prefabName] = val; ServerSyncBridge.AddConfigEntry<string>(val); } } internal static string GetRecipe(BuildPieceDefinition definition) { if (definition == null) { return null; } if (RecipeEntries.TryGetValue(definition.PrefabName, out var value) && value != null) { return value.Value; } return definition.DefaultRecipe; } internal static void Reset() { ResetEntries(); LockConfiguration = null; BuildPieceRecipeConfig.RecipeChanged = null; } private static void ResetEntries() { foreach (KeyValuePair<string, ConfigEntry<string>> recipeEntry in RecipeEntries) { if (recipeEntry.Value != null) { recipeEntry.Value.SettingChanged -= OnRecipeSettingChanged; } } RecipeEntries.Clear(); } private static void OnRecipeSettingChanged(object sender, EventArgs eventArgs) { ConfigEntryBase val = (ConfigEntryBase)((sender is ConfigEntryBase) ? sender : null); if (val != null) { BuildPieceRecipeConfig.RecipeChanged?.Invoke(val.Definition.Key); } } } public class BalrondWindControler : MonoBehaviour { public bool m_windDirection; public bool m_northdirection; public bool m_; private float m_cover; public AudioSource[] m_sfxLoops; public float m_bomRotationSpeed = 200f; public float m_propellerRotationSpeed = -600f; public float m_minWindSpeed = 0.1f; public float m_minPitch = 1f; public float m_maxPitch = 1.5f; public float m_maxPitchVel = 1f; public float m_maxVol = 0.01f; public float m_maxVolVel = 0.5f; public float m_audioChangeSpeed = 2f; public Transform m_bom; public Transform m_kompas; public Transform m_propeller; private float m_propAngle; private Quaternion currentRotation = Quaternion.identity; private void Start() { ((MonoBehaviour)this).InvokeRepeating("CheckCover", 0.1f, 5f); } private void Update() { //IL_0021: 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) //IL_0037: 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_003d: 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_0065: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //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_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)EnvMan.instance == (Object)null) { return; } float powerOutput = GetPowerOutput(); Vector3 val = EnvMan.instance.GetWindDir(); if ((Object)(object)m_propeller != (Object)null) { val = -val; } if ((Object)(object)m_bom != (Object)null && ((Vector3)(ref val)).sqrMagnitude > 0.0001f) { Quaternion val2 = Quaternion.LookRotation(val); m_bom.rotation = Quaternion.RotateTowards(m_bom.rotation, val2, m_bomRotationSpeed * powerOutput * Time.deltaTime); } if ((Object)(object)m_kompas != (Object)null) { Quaternion val3 = Quaternion.LookRotation(Vector3.forward, Vector3.up); m_kompas.rotation = Quaternion.RotateTowards(m_kompas.rotation, val3, m_bomRotationSpeed * powerOutput * Time.deltaTime); } if ((Object)(object)m_propeller != (Object)null) { m_propAngle += powerOutput * m_propellerRotationSpeed * Time.deltaTime; m_propeller.localRotation = Quaternion.Euler(0f, 0f, m_propAngle); } if ((Object)(object)m_bom != (Object)null) { if (Quaternion.Angle(currentRotation, m_bom.rotation) >= 0.1f) { UpdateAudio(Time.deltaTime); currentRotation = m_bom.rotation; } } else { UpdateAudio(Time.deltaTime); } } public float GetPowerOutput() { if ((Object)(object)EnvMan.instance == (Object)null) { return 0f; } return (1f - m_cover) * Utils.LerpStep(m_minWindSpeed, 1f, EnvMan.instance.GetWindIntensity()); } private void CheckCover() { //IL_0022: 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_0027: 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) Vector3 val = (((Object)(object)m_bom != (Object)null) ? m_bom.position : ((Component)this).transform.position); bool flag = default(bool); Cover.GetCoverForPoint(val, ref m_cover, ref flag, 0.5f); } private void UpdateAudio(float dt) { if (m_sfxLoops == null || m_sfxLoops.Length == 0) { return; } float powerOutput = GetPowerOutput(); float num = Mathf.Lerp(m_minPitch, m_maxPitch, Mathf.Clamp01(powerOutput / m_maxPitchVel)); float num2 = m_maxVol * Mathf.Clamp01(powerOutput / m_maxVolVel); for (int i = 0; i < m_sfxLoops.Length; i++) { AudioSource val = m_sfxLoops[i]; if (!((Object)(object)val == (Object)null)) { val.volume = Mathf.MoveTowards(val.volume, num2, m_audioChangeSpeed * dt); val.pitch = Mathf.MoveTowards(val.pitch, num, m_audioChangeSpeed * dt); } } } } internal static class ServerSyncBridge { private static object _syncObject; internal static void Initialize(string pluginGuid, string displayName, string version) { ConfigSync syncObject = new ConfigSync(pluginGuid) { DisplayName = displayName, CurrentVersion = version, MinimumRequiredVersion = version }; _syncObject = syncObject; } internal static void AddLockingConfigEntry(ConfigEntry<bool> entry) { GetSync().AddLockingConfigEntry<bool>(entry); } internal static void AddConfigEntry<T>(ConfigEntry<T> entry) { SyncedConfigEntry<T> syncedConfigEntry = GetSync().AddConfigEntry<T>(entry); syncedConfigEntry.SynchronizedConfig = true; } internal static void Reset() { _syncObject = null; } private static ConfigSync GetSync() { if (!(_syncObject is ConfigSync result)) { throw new InvalidOperationException("ServerSyncBridge was used before successful initialization."); } return result; } } internal static class BalrondHashCompat { public static int StableHash(string value) { if (value == null) { return 0; } return StringExtensionMethods.GetStableHashCode(value); } } internal sealed class EffectReferenceMapper { private readonly PrefabLookupCache _prefabCache = new PrefabLookupCache(); private List<GameObject> _scenePrefabs; internal void Rebuild(List<GameObject> scenePrefabs) { _scenePrefabs = scenePrefabs; _prefabCache.Rebuild(scenePrefabs); } internal void RepairBuildPiece(GameObject prefab) { if (!((Object)(object)prefab == (Object)null) && _scenePrefabs != null) { Piece component = prefab.GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { RepairEffectList(component.m_placeEffect); } WearNTear component2 = prefab.GetComponent<WearNTear>(); if ((Object)(object)component2 != (Object)null) { RepairEffectList(component2.m_hitEffect); RepairEffectList(component2.m_destroyedEffect); } } } private void RepairEffectList(EffectList effectList) { if (effectList == null) { return; } EffectData[] effectPrefabs = effectList.m_effectPrefabs; if (effectPrefabs == null || effectPrefabs.Length == 0) { return; } foreach (EffectData val in effectPrefabs) { if ((Object)(object)val.m_prefab == (Object)null) { continue; } string name = ((Object)val.m_prefab).name; if (!string.IsNullOrEmpty(name)) { GameObject val2 = _prefabCache.Find(name, _scenePrefabs); if ((Object)(object)val2 != (Object)null) { val.m_prefab = val2; } } } } } internal sealed class JsonLoader { private const string EnglishResourceSuffix = "Translations.English.English.json"; private CustomLocalization _localization; private bool _loaded; internal void LoadJson() { if (_loaded) { return; } _localization = LocalizationManager.Instance.GetLocalization(); Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = null; string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); for (int i = 0; i < manifestResourceNames.Length; i++) { if (manifestResourceNames[i].EndsWith("Translations.English.English.json", StringComparison.OrdinalIgnoreCase)) { text = manifestResourceNames[i]; break; } } if (text == null) { throw new InvalidOperationException("Embedded English localization resource was not found."); } using (Stream stream = executingAssembly.GetManifestResourceStream(text)) { using StreamReader streamReader = new StreamReader(stream); _localization.AddJsonFile("English", streamReader.ReadToEnd()); } _loaded = true; if (Launch.Log != null) { Launch.Log.LogInfo((object)"Jotunn English localization loaded."); } } internal void NormalizePiece(GameObject prefab) { if (!((Object)(object)prefab == (Object)null) && !string.IsNullOrEmpty(((Object)prefab).name)) { Piece component = prefab.GetComponent<Piece>(); if (!((Object)(object)component == (Object)null)) { string text = "tag_" + ((Object)prefab).name.ToLowerInvariant(); component.m_name = "$" + text; component.m_description = "$" + text + "_description"; } } } internal void NormalizePieces(IList<GameObject> prefabs) { if (prefabs != null) { for (int i = 0; i < prefabs.Count; i++) { NormalizePiece(prefabs[i]); } } } } public class ModResourceLoader { private const string BundleResourceName = "ravenwoodrepack"; private const string BaseAssetPath = "Assets/Custom/Comission/BuildPieceRepackRavenWood/"; private static readonly FieldInfo ObjectDbBuildPiecesField = typeof(ObjectDB).GetField("m_buildPieces", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static bool _loggedMissingObjectDbBuildPiecesField; private static readonly string[] HammerNames = new string[4] { "Hammer", "HammerIron", "HammerDverger", "HammerBlackmetal" }; private static readonly string[] OtherPrefabNames = new string[1] { "sfx_queendoor_open1" }; private readonly PrefabLookupCache _scenePrefabCache = new PrefabLookupCache(); private readonly Dictionary<int, string> _sceneHashNames = new Dictionary<int, string>(); private readonly EffectReferenceMapper _effectReferenceMapper = new EffectReferenceMapper(); private bool _sceneRegistrationCompleted; public AssetBundle assetBundle; public readonly List<GameObject> buildPrefabs = new List<GameObject>(); public readonly List<GameObject> vfxPrefabs = new List<GameObject>(); public readonly List<GameObject> registeredBuildPrefabs = new List<GameObject>(); public void loadAssets() { buildPrefabs.Clear(); vfxPrefabs.Clear(); registeredBuildPrefabs.Clear(); _sceneRegistrationCompleted = false; assetBundle = GetAssetBundleFromResources("ravenwoodrepack"); if (!((Object)(object)assetBundle == (Object)null)) { ShaderReplacement.RegisterBundleShaders(assetBundle); LoadPieces("Assets/Custom/Comission/BuildPieceRepackRavenWood/Pieces/"); LoadOther("Assets/Custom/Comission/BuildPieceRepackRavenWood/Other/"); } } public void AddPrefabsToZnetScene(ZNetScene zNetScene) { if (!((Object)(object)zNetScene == (Object)null) && zNetScene.m_prefabs != null) { registeredBuildPrefabs.Clear(); _scenePrefabCache.Rebuild(zNetScene.m_prefabs); RebuildSceneHashCache(zNetScene.m_prefabs); RegisterPrefabCollection(vfxPrefabs, zNetScene, null); RegisterPrefabCollection(buildPrefabs, zNetScene, registeredBuildPrefabs); _effectReferenceMapper.Rebuild(zNetScene.m_prefabs); for (int i = 0; i < registeredBuildPrefabs.Count; i++) { _effectReferenceMapper.RepairBuildPiece(registeredBuildPrefabs[i]); } _sceneRegistrationCompleted = true; } } public void FinalizeZNetSceneSetup(ZNetScene zNetScene) { if (!((Object)(object)zNetScene == (Object)null) && zNetScene.m_prefabs != null) { _scenePrefabCache.Rebuild(zNetScene.m_prefabs); RefreshRegisteredBuildPrefabs(zNetScene.m_prefabs); SetBalrondWindController(zNetScene); SetupBuildPiecesList(zNetScene); setupBuildPiecesListDB(); } } public void setupBuildPiecesListDB() { ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null || instance.m_items == null || !_sceneRegistrationCompleted) { return; } GameObject val = instance.GetItemPrefab("Hammer"); if ((Object)(object)val == (Object)null) { val = instance.m_items.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == "Hammer"); } if (TryGetPieceTable(val, out var pieceTable)) { AddBuildPrefabsToPieceTable(pieceTable, registeredBuildPrefabs); RavenwoodBuildMenuCompat.EnsureCategoryOnPieceTable(pieceTable, (PieceCategory)0); InvalidateObjectDbBuildPieceCache(instance); } } public bool IsHammerPieceTable(PieceTable pieceTable) { if ((Object)(object)pieceTable == (Object)null) { return false; } ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null || instance.m_items == null) { return false; } GameObject val = instance.GetItemPrefab("Hammer"); if ((Object)(object)val == (Object)null) { val = instance.m_items.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == "Hammer"); } if (!TryGetPieceTable(val, out var pieceTable2)) { return false; } return pieceTable == pieceTable2 || (!string.IsNullOrEmpty(((Object)pieceTable).name) && string.Equals(((Object)pieceTable).name, ((Object)pieceTable2).name, StringComparison.Ordinal)); } public int EnsureRuntimeHammerPieces(PieceTable pieceTable) { if (!IsHammerPieceTable(pieceTable) || pieceTable.m_pieces == null) { return 0; } int count = pieceTable.m_pieces.Count; AddBuildPrefabsToPieceTable(pieceTable, registeredBuildPrefabs); RavenwoodBuildMenuCompat.EnsureCategoryOnPieceTable(pieceTable, (PieceCategory)0); if ((Object)(object)ObjectDB.instance != (Object)null) { InvalidateObjectDbBuildPieceCache(ObjectDB.instance); } return pieceTable.m_pieces.Count - count; } public IEnumerable<GameObject> EnumerateAudioPrefabs() { for (int i = 0; i < buildPrefabs.Count; i++) { if ((Object)(object)buildPrefabs[i] != (Object)null) { yield return buildPrefabs[i]; } } for (int j = 0; j < vfxPrefabs.Count; j++) { if ((Object)(object)vfxPrefabs[j] != (Object)null) { yield return vfxPrefabs[j]; } } } private void LoadPieces(string path) { LoadPrefabCollection(BuildPieceList.buildPieces, path, buildPrefabs, "piece"); } private void LoadOther(string path) { LoadPrefabCollection(OtherPrefabNames, path, vfxPrefabs, "object"); } private void LoadPrefabCollection(string[] prefabNames, string path, List<GameObject> destination, string assetKind) { if (prefabNames == null || destination == null || (Object)(object)assetBundle == (Object)null) { return; } HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); List<string> list = new List<string>(); foreach (string text in prefabNames) { if (string.IsNullOrWhiteSpace(text)) { continue; } if (!hashSet.Add(text)) { if (Launch.Log != null) { Launch.Log.LogWarning((object)("Duplicate " + assetKind + " entry ignored while loading: " + text)); } continue; } GameObject val = null; try { val = assetBundle.LoadAsset<GameObject>(path + text + ".prefab"); } catch (Exception ex) { if (Launch.Log != null) { Launch.Log.LogError((object)("Failed to load " + assetKind + " '" + text + "': " + ex)); } continue; } if ((Object)(object)val == (Object)null) { list.Add(text); continue; } ShaderReplacement.Replace(val); destination.Add(val); } if (list.Count > 0 && Launch.Log != null) { int num = Math.Min(list.Count, 24); string text2 = string.Join(", ", list.GetRange(0, num).ToArray()); if (list.Count > num) { text2 += ", ..."; } Launch.Log.LogWarning((object)("AssetBundle is missing " + list.Count + " " + assetKind + " prefab(s): " + text2)); } } private AssetBundle GetAssetBundleFromResources(string filename) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); string text = null; for (int i = 0; i < manifestResourceNames.Length; i++) { if (manifestResourceNames[i].EndsWith(filename, StringComparison.OrdinalIgnoreCase)) { text = manifestResourceNames[i]; break; } } if (string.IsNullOrEmpty(text)) { if (Launch.Log != null) { Launch.Log.LogError((object)("Embedded AssetBundle resource not found: " + filename)); } return null; } using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { if (Launch.Log != null) { Launch.Log.LogError((object)("Could not open embedded AssetBundle resource: " + text)); } return null; } AssetBundle val = AssetBundle.LoadFromStream(stream); if ((Object)(object)val == (Object)null && Launch.Log != null) { Launch.Log.LogError((object)("AssetBundle.LoadFromStream returned null for: " + text)); } return val; } private void RebuildSceneHashCache(List<GameObject> prefabs) { _sceneHashNames.Clear(); if (prefabs == null) { return; } for (int i = 0; i < prefabs.Count; i++) { GameObject val = prefabs[i]; if (!((Object)(object)val == (Object)null) && !string.IsNullOrEmpty(((Object)val).name)) { int key = BalrondHashCompat.StableHash(((Object)val).name); if (!_sceneHashNames.ContainsKey(key)) { _sceneHashNames.Add(key, ((Object)val).name); } } } } private void RegisterPrefabCollection(List<GameObject> prefabs, ZNetScene zNetScene, List<GameObject> registered) { if (prefabs == null) { return; } for (int i = 0; i < prefabs.Count; i++) { GameObject val = prefabs[i]; if (RegisterPrefab(val, zNetScene) && registered != null && (Object)(object)val != (Object)null) { registered.Add(val); } } } private bool RegisterPrefab(GameObject prefab, ZNetScene zNetScene) { if ((Object)(object)prefab == (Object)null || string.IsNullOrEmpty(((Object)prefab).name) || (Object)(object)zNetScene == (Object)null || zNetScene.m_prefabs == null) { return false; } GameObject val = _scenePrefabCache.Find(((Object)prefab).name, zNetScene.m_prefabs); if ((Object)(object)val != (Object)null) { if ((Object)(object)val == (Object)(object)prefab) { return true; } if (Launch.Log != null) { Launch.Log.LogWarning((object)("Prefab name conflict for '" + ((Object)prefab).name + "'. Keeping the prefab already registered by the game or another mod.")); } return false; } int key = BalrondHashCompat.StableHash(((Object)prefab).name); if (_sceneHashNames.TryGetValue(key, out var value)) { if (Launch.Log != null) { Launch.Log.LogError((object)("Cannot register prefab '" + ((Object)prefab).name + "': stable hash is already used by '" + value + "'.")); } return false; } zNetScene.m_prefabs.Add(prefab); _scenePrefabCache.Remember(prefab); _sceneHashNames[key] = ((Object)prefab).name; return true; } private void RefreshRegisteredBuildPrefabs(List<GameObject> scenePrefabs) { registeredBuildPrefabs.Clear(); if (scenePrefabs == null) { return; } int num = 0; int num2 = 0; int num3 = 0; BuildPieceDefinition[] definitions = BuildPieceList.Definitions; for (int i = 0; i < definitions.Length; i++) { string prefabName = definitions[i].PrefabName; GameObject val = _scenePrefabCache.Find(prefabName, scenePrefabs); if ((Object)(object)val == (Object)null) { num3++; continue; } registeredBuildPrefabs.Add(val); GameObject val2 = null; for (int j = 0; j < buildPrefabs.Count; j++) { GameObject val3 = buildPrefabs[j]; if ((Object)(object)val3 != (Object)null && string.Equals(((Object)val3).name, prefabName, StringComparison.Ordinal)) { val2 = val3; break; } } if (val == val2) { num++; } else { num2++; } } if (Launch.Log != null) { Launch.Log.LogInfo((object)("Active Ravenwood build prefabs resolved: total=" + registeredBuildPrefabs.Count + ", owned=" + num + ", reusedExisting=" + num2 + ", missing=" + num3 + ".")); } } private void SetBalrondWindController(ZNetScene zNetScene) { if ((Object)(object)zNetScene == (Object)null || zNetScene.m_prefabs == null) { return; } GameObject val = _scenePrefabCache.Find("weathervane_bal", zNetScene.m_prefabs); if ((Object)(object)val == (Object)null) { return; } MonoBehaviour[] components = val.GetComponents<MonoBehaviour>(); foreach (MonoBehaviour val2 in components) { if ((Object)(object)val2 != (Object)null && string.Equals(((object)val2).GetType().Name, "BalrondWindControler", StringComparison.Ordinal)) { return; } } Windmill component = val.GetComponent<Windmill>(); if ((Object)(object)component == (Object)null) { if (Launch.Log != null) { Launch.Log.LogWarning((object)"Weathervane wind-controller source Windmill is missing. Existing prefab behavior was preserved."); } return; } BalrondWindControler balrondWindControler = val.AddComponent<BalrondWindControler>(); balrondWindControler.m_propeller = component.m_propeller; balrondWindControler.m_bom = component.m_bom; balrondWindControler.m_kompas = component.m_grindstone; balrondWindControler.m_sfxLoops = component.m_sfxLoops; balrondWindControler.m_windDirection = true; Object.DestroyImmediate((Object)(object)component); if (Launch.Log != null) { Launch.Log.LogInfo((object)"weathervane_bal wind controller initialized."); } } private void SetupBuildPiecesList(ZNetScene zNetScene) { GameObject tool = _scenePrefabCache.Find("Hammer", zNetScene.m_prefabs); if (!TryGetPieceTable(tool, out var pieceTable)) { if (Launch.Log != null) { Launch.Log.LogError((object)"Hammer PieceTable could not be resolved in ZNetScene."); } return; } for (int i = 0; i < HammerNames.Length; i++) { GameObject val = _scenePrefabCache.Find(HammerNames[i], zNetScene.m_prefabs); if ((Object)(object)val == (Object)null) { continue; } ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null) { if (Launch.Log != null) { Launch.Log.LogWarning((object)("Build tool has invalid ItemDrop data: " + HammerNames[i])); } } else { component.m_itemData.m_shared.m_buildPieces = pieceTable; } } GameObject ravenGuidePrefab = GetRavenGuidePrefab(zNetScene); for (int j = 0; j < registeredBuildPrefabs.Count; j++) { GameObject gameObject = registeredBuildPrefabs[j]; SetupRavenGuide(gameObject, ravenGuidePrefab); } AddBuildPrefabsToPieceTable(pieceTable, registeredBuildPrefabs); RavenwoodBuildMenuCompat.EnsureCategoryOnPieceTable(pieceTable, (PieceCategory)0); } private void AddBuildPrefabsToPieceTable(PieceTable pieceTable, List<GameObject> prefabs) { if ((Object)(object)pieceTable == (Object)null || pieceTable.m_pieces == null || prefabs == null) { return; } List<GameObject> pieces = pieceTable.m_pieces; HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); for (int i = 0; i < pieces.Count; i++) { GameObject val = pieces[i]; if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(((Object)val).name)) { hashSet.Add(((Object)val).name); } } for (int j = 0; j < prefabs.Count; j++) { GameObject prefab = prefabs[j]; if (!((Object)(object)prefab == (Object)null) && !string.IsNullOrEmpty(((Object)prefab).name) && !hashSet.Contains(((Object)prefab).name)) { GameObject val2 = pieces.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == ((Object)prefab).name); if ((Object)(object)val2 != (Object)null) { hashSet.Add(((Object)prefab).name); continue; } pieces.Add(prefab); hashSet.Add(((Object)prefab).name); } } } private static void InvalidateObjectDbBuildPieceCache(ObjectDB objectDb) { if ((Object)(object)objectDb == (Object)null) { return; } if (ObjectDbBuildPiecesField == null) { if (!_loggedMissingObjectDbBuildPiecesField && Launch.Log != null) { _loggedMissingObjectDbBuildPiecesField = true; Launch.Log.LogWarning((object)"ObjectDB.m_buildPieces was not found. Build-piece cache invalidation was skipped; verify the current Valheim API."); } return; } try { ObjectDbBuildPiecesField.SetValue(objectDb, null); } catch (Exception ex) { if (Launch.Log != null) { Launch.Log.LogWarning((object)("Could not invalidate ObjectDB build-piece cache: " + ex)); } } } private GameObject GetRavenGuidePrefab(ZNetScene zNetScene) { GameObject val = _scenePrefabCache.Find("Ravens", zNetScene.m_prefabs); if ((Object)(object)val != (Object)null) { return val; } GameObject val2 = _scenePrefabCache.Find("piece_workbench", zNetScene.m_prefabs); if ((Object)(object)val2 == (Object)null) { return null; } Transform val3 = val2.transform.Find("GuidePoint"); if ((Object)(object)val3 == (Object)null) { return null; } GuidePoint component = ((Component)val3).GetComponent<GuidePoint>(); return ((Object)(object)component != (Object)null) ? component.m_ravenPrefab : null; } private void SetupRavenGuide(GameObject gameObject, GameObject ravenPrefab) { if ((Object)(object)gameObject == (Object)null || (Object)(object)ravenPrefab == (Object)null) { return; } Transform val = gameObject.transform.Find("GuidePoint"); if (!((Object)(object)val == (Object)null)) { GuidePoint component = ((Component)val).GetComponent<GuidePoint>(); if ((Object)(object)component != (Object)null) { component.m_ravenPrefab = ravenPrefab; } } } private static bool TryGetPieceTable(GameObject tool, out PieceTable pieceTable) { pieceTable = null; if ((Object)(object)tool == (Object)null) { return false; } ItemDrop component = tool.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null) { return false; } pieceTable = component.m_itemData.m_shared.m_buildPieces; return (Object)(object)pieceTable != (Object)null && pieceTable.m_pieces != null; } } internal static class PieceMetadataCompat { private const int MaxAuditNames = 24; internal static void Apply(Piece piece, string prefabName) { //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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_0044: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_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_005a: Invalid comparison between Unknown and I4 //IL_006a: 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_0070: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Invalid comparison between Unknown and I4 //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)piece == (Object)null)) { if (piece.m_resources == null) { piece.m_resources = (Requirement[])(object)new Requirement[0]; } BuildPieceDefinition buildPieceDefinition = BuildPieceList.Find(prefabName); UsageTagFlags val = (UsageTagFlags)((buildPieceDefinition != null) ? ((int)buildPieceDefinition.BaseUsage) : 0); val |= InferFromName(prefabName); val |= InferFromComponents(((Component)piece).gameObject); if ((val & 0x60078) > 0) { val = (UsageTagFlags)(val | 4); } piece.m_usage |= val; if ((int)piece.m_usage == 0) { piece.m_usage = (UsageTagFlags)1; } } } internal static void Audit(IList<GameObject> prefabs) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Invalid comparison between Unknown and I4 //IL_00ca: Unknown result type (might be due to invalid IL or missing references) if (prefabs == null || Launch.Log == null) { return; } int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; List<string> list = new List<string>(); for (int i = 0; i < prefabs.Count; i++) { GameObject val = prefabs[i]; if ((Object)(object)val == (Object)null) { continue; } num++; Piece component = val.GetComponent<Piece>(); if ((Object)(object)component == (Object)null) { num2++; Remember(list, ((Object)val).name + "[no Piece]"); continue; } bool flag = false; if (!component.m_enabled) { num3++; flag = true; } if ((int)component.m_usage == 0) { num4++; flag = true; } if (!RavenwoodBuildMenuCompat.IsKnownCategory(component.m_category)) { num5++; flag = true; } if ((Object)(object)component.m_icon == (Object)null) { num6++; flag = true; } if (flag) { Remember(list, ((Object)val).name); } } Launch.Log.LogInfo((object)("Build-piece metadata audit: total=" + num + ", noPiece=" + num2 + ", disabled=" + num3 + ", zeroUsage=" + num4 + ", invalidCategory=" + num5 + ", missingIcon=" + num6 + ".")); if (list.Count > 0) { Launch.Log.LogWarning((object)("Build-piece metadata issues: " + string.Join(", ", list.ToArray()))); } } private static UsageTagFlags InferFromComponents(GameObject prefab) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0028: 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_0089: 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_0042: 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_0056: 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_005d: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)prefab == (Object)null) { return (UsageTagFlags)0; } UsageTagFlags val = (UsageTagFlags)0; if ((Object)(object)prefab.GetComponent<Container>() != (Object)null) { val = (UsageTagFlags)(val | 0x480); } if ((Object)(object)prefab.GetComponent<Fireplace>() != (Object)null) { val = (UsageTagFlags)(val | 0x100); } if ((Object)(object)prefab.GetComponent<Door>() != (Object)null) { val = (UsageTagFlags)(val | 0x40004); } if ((Object)(object)prefab.GetComponent<CraftingStation>() != (Object)null || (Object)(object)prefab.GetComponent<StationExtension>() != (Object)null) { val = (UsageTagFlags)(val | 2); } return val; } private static UsageTagFlags InferFromName(string prefabName) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: 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_007e: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00df: 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_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_03c1: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03f4: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(prefabName)) { return (UsageTagFlags)0; } string value = prefabName.ToLowerInvariant(); UsageTagFlags val = (UsageTagFlags)0; if (HasAny(value, "floor", "platform", "ceiling", "celling", "slab")) { val = (UsageTagFlags)(val | 8); } if (HasAny(value, "wall", "window")) { val = (UsageTagFlags)(val | 0x10); } if (HasAny(value, "roof", "canopy")) { val = (UsageTagFlags)(val | 0x20); } if (HasAny(value, "stair", "ladder", "ramp", "step")) { val = (UsageTagFlags)(val | 0x20000); } if (HasAny(value, "door", "gate", "hatch")) { val = (UsageTagFlags)(val | 0x40000); } if (HasAny(value, "beam", "pole", "pillar", "column", "arch", "frame", "trim", "railing", "slope", "oriel")) { val = (UsageTagFlags)(val | 0x40); } if (HasAny(value, "stake", "spike", "fence", "palisade", "barricade", "trap", "cage", "target")) { val = (UsageTagFlags)(val | 0x8000); } if (HasAny(value, "chair", "bench", "table", "bed", "throne", "stool", "carpet", "rug")) { val = (UsageTagFlags)(val | 0x80); } if (HasAny(value, "torch", "light", "lantern", "brazier", "braizer", "candle", "fire", "hearth")) { val = (UsageTagFlags)(val | 0x100); } if (HasAny(value, "chest", "storage", "shelf", "rack", "crate")) { val = (UsageTagFlags)(val | 0x400); } if (HasAny(value, "clutter", "banner", "deco", "decor", "statue", "raven", "dragon", "vigvisir", "rune", "rostrum")) { val = (UsageTagFlags)(val | 0x200); } if (HasAny(value, "workbench", "forge", "cauldron", "craft", "smelter", "kiln", "oven", "windmill", "spinning")) { val = (UsageTagFlags)(val | 2); } if (HasAny(value, "bridge", "cart", "wagon")) { val = (UsageTagFlags)(val | 0x800); } if (HasAny(value, "stack", "pile")) { val = (UsageTagFlags)(val | 0x10000); } return val; } private static bool HasAny(string value, params string[] tokens) { for (int i = 0; i < tokens.Length; i++) { if (value.IndexOf(tokens[i], StringComparison.Ordinal) >= 0) { return true; } } return false; } private static void Remember(List<string> names, string name) { if (names.Count < 24) { names.Add(name); } } } internal sealed class PrefabLookupCache { private readonly Dictionary<string, GameObject> _byName = new Dictionary<string, GameObject>(StringComparer.Ordinal); private List<GameObject> _source; public void Rebuild(List<GameObject> source) { _source = source; _byName.Clear(); if (source != null) { for (int i = 0; i < source.Count; i++) { Remember(source[i]); } } } public GameObject Find(string name, List<GameObject> source = null) { if (string.IsNullOrWhiteSpace(name)) { return null; } string normalizedName = name.Trim(); List<GameObject> list = source ?? _source; if (source != null && source != _source) { Rebuild(source); list = source; } if (_byName.TryGetValue(normalizedName, out var value)) { if ((Object)(object)value != (Object)null && ((Object)value).name == normalizedName) { return value; } _byName.Remove(normalizedName); } if (list == null) { return null; } GameObject val = list.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == normalizedName); if ((Object)(object)val != (Object)null) { _byName[normalizedName] = val; } return val; } public void Remember(GameObject prefab) { if (!((Object)(object)prefab == (Object)null) && !string.IsNullOrEmpty(((Object)prefab).name) && !_byName.ContainsKey(((Object)prefab).name)) { _byName.Add(((Object)prefab).name, prefab); } } public void Clear() { _source = null; _byName.Clear(); } } internal static class RavenwoodBuildMenuCompat { internal const string CategoryName = "Ravenwood"; internal const string CategoryLabelToken = "$jotunn_cat_ravenwood"; internal const string LegacyBuildMenuGuid = "Azumatt.LegacyBuildMenu"; internal const string RavenwoodJapanGuid = "JamesJonesTV.RavenwoodJapan"; internal const string JotunnGuid = "com.jotunn.jotunn"; internal const string MinimumJotunnVersion = "2.30.1"; internal const string HammerTimeGuid = "com.maxsch.valheim.HammerTime"; private static bool _hasCachedCategory; private static PieceCategory _cachedCategory; private static bool _loggedCategory; private static bool _loggedLegacyMirror; private static bool _loggedHudExpansion; internal static PieceCategory GetOrCreateRavenwoodCategory(PieceCategory fallback) { //IL_0073: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) try { PieceCategory? pieceCategory = PieceManager.Instance.GetPieceCategory("Ravenwood"); PieceCategory val = (pieceCategory.HasValue ? pieceCategory.Value : PieceManager.Instance.AddPieceCategory("Ravenwood")); Cache(val); return val; } catch (Exception ex) { if (Launch.Log != null) { Launch.Log.LogError((object)("Jotunn Ravenwood category registration failed: " + ex)); } return fallback; } } internal static PieceCategory RefreshRavenwoodCategory(PieceCategory fallback) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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) _hasCachedCategory = false; return GetOrCreateRavenwoodCategory(fallback); } internal static bool TryGetResolvedCategory(out PieceCategory category) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected I4, but got Unknown category = (PieceCategory)(int)GetOrCreateRavenwoodCategory((PieceCategory)0); return _hasCachedCategory; } internal static void AssignCategory(Piece piece, PieceCategory fallback) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)piece == (Object)null)) { PieceCategory orCreateRavenwoodCategory = GetOrCreateRavenwoodCategory(fallback); piece.m_category = (_hasCachedCategory ? orCreateRavenwoodCategory : fallback); } } internal static void ApplyProviderUsageTag(Piece piece) { } internal static void EnsureCategoryOnPieceTable(PieceTable pieceTable, PieceCategory fallback) { //IL_0011: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected I4, but got Unknown if ((Object)(object)pieceTable == (Object)null) { return; } PieceCategory orCreateRavenwoodCategory = GetOrCreateRavenwoodCategory(fallback); if (!_hasCachedCategory || pieceTable.m_categories == null || pieceTable.m_categoryLabels == null) { return; } int num = pieceTable.m_categories.IndexOf(orCreateRavenwoodCategory); if (num < 0) { pieceTable.m_categories.Add(orCreateRavenwoodCategory); pieceTable.m_categoryLabels.Add("$jotunn_cat_ravenwood"); num = pieceTable.m_categories.Count - 1; } else { while (pieceTable.m_categoryLabels.Count <= num) { pieceTable.m_categoryLabe