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 balrond WeaponCrate v0.1.2
plugins/BalrondWeaponCrate.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; 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 System.Text; using System.Text.RegularExpressions; using Balrond.Shared; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using JetBrains.Annotations; using LitJson2; using Microsoft.CodeAnalysis; using ServerSync; using TMPro; using UnityEngine; using UnityEngine.Audio; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("BalrondWeaponCrate")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BalrondWeaponCrate")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("b6cf3f26-ceac-41f7-9df1-09f3f9b898b4")] [assembly: AssemblyFileVersion("0.1.2.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.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 BalrondWeaponCrate { internal static class WeaponCrateConfig { internal static ConfigEntry<bool> LockConfiguration; internal static ConfigEntry<bool> ShieldsAreWeapons; internal static ConfigEntry<bool> ForceCostToSelf; internal static ConfigEntry<int> CostAmount; internal static ConfigEntry<bool> RequireAttachChild; internal static ConfigEntry<string> ManualIncludeWeapons; internal static ConfigEntry<string> ManualIncludeArmors; internal static ConfigEntry<string> ManualExclude; internal static ConfigEntry<KeyCode> RaiseKey; internal static ConfigEntry<KeyCode> LowerKey; internal static ConfigEntry<KeyCode> LeftKey; internal static ConfigEntry<KeyCode> RightKey; internal static ConfigEntry<KeyCode> AwayKey; internal static ConfigEntry<KeyCode> CloserKey; internal static ConfigEntry<KeyCode> NextPoseKey; internal static ConfigEntry<KeyCode> PrevPoseKey; internal static ConfigEntry<bool> DebugLogging; internal static ConfigEntry<bool> AudioDebugLogging; internal static void Bind(ConfigFile config) { LockConfiguration = config.Bind<bool>("Server", "LockConfiguration", true, "Lock synchronized ZBalrondWeaponCrate settings to the server/host values."); ServerSyncBridge.AddLockingConfigEntry(LockConfiguration); ShieldsAreWeapons = BindSynced(config, "Filtering", "ShieldsAreWeapons", value: true, "Treat shields as weapon entries instead of armor entries."); RequireAttachChild = BindSynced(config, "Filtering", "RequireAttachChild", value: false, "Only expose item prefabs that contain an 'attach' child transform."); ManualIncludeWeapons = BindSynced(config, "Filtering", "ManualIncludeWeapons", string.Empty, "Comma-separated prefab IDs that should be considered for the weapon category."); ManualIncludeArmors = BindSynced(config, "Filtering", "ManualIncludeArmors", string.Empty, "Comma-separated prefab IDs that should be considered for the armor category."); ManualExclude = BindSynced(config, "Filtering", "ManualExclude", string.Empty, "Comma-separated prefab IDs to exclude from Weapon Crate build-piece generation."); ForceCostToSelf = BindSynced(config, "Costs", "ForceCostToSelf", value: true, "When enabled, generated display pieces cost copies of the displayed item itself."); CostAmount = BindSynced(config, "Costs", "CostAmount", 1, "Number of copies of the displayed item required when ForceCostToSelf is enabled."); RaiseKey = config.Bind<KeyCode>("Controls", "RaiseKey", (KeyCode)273, "While placing with Weapon Crate: raise the item. Local input, never synchronized."); LowerKey = config.Bind<KeyCode>("Controls", "LowerKey", (KeyCode)274, "While placing with Weapon Crate: lower the item. Local input, never synchronized."); LeftKey = config.Bind<KeyCode>("Controls", "LeftKey", (KeyCode)276, "While placing with Weapon Crate: move it left. Local input, never synchronized."); RightKey = config.Bind<KeyCode>("Controls", "RightKey", (KeyCode)275, "While placing with Weapon Crate: move it right. Local input, never synchronized."); AwayKey = config.Bind<KeyCode>("Controls", "AwayKey", (KeyCode)280, "While placing with Weapon Crate: move it away. Local input, never synchronized."); CloserKey = config.Bind<KeyCode>("Controls", "CloserKey", (KeyCode)281, "While placing with Weapon Crate: move it closer. Local input, never synchronized."); NextPoseKey = config.Bind<KeyCode>("Controls", "NextPoseKey", (KeyCode)278, "While placing with Weapon Crate: cycle to next armor pose. Local input, never synchronized."); PrevPoseKey = config.Bind<KeyCode>("Controls", "PrevPoseKey", (KeyCode)279, "While placing with Weapon Crate: cycle to previous armor pose. Local input, never synchronized."); DebugLogging = config.Bind<bool>("Diagnostics", "DebugLogging", false, "Enable additional ZBalrondWeaponCrate diagnostic logging. Local client setting; not synchronized."); AudioDebugLogging = config.Bind<bool>("Diagnostics", "AudioDebugLogging", false, "Enable detailed AudioRoutingService logging. Local client setting; not synchronized."); } private static ConfigEntry<T> BindSynced<T>(ConfigFile config, string section, string key, T value, string description) { ConfigEntry<T> val = config.Bind<T>(section, key, value, description); ServerSyncBridge.AddConfigEntry<T>(val); return val; } internal static string[] ParsePrefabList(ConfigEntry<string> entry) { if (entry == null || string.IsNullOrWhiteSpace(entry.Value)) { return new string[0]; } string[] array = entry.Value.Split(new char[4] { ',', ';', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); List<string> list = new List<string>(array.Length); HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length != 0 && hashSet.Add(text)) { list.Add(text); } } return list.ToArray(); } } internal static class ServerSyncBridge { private static ConfigSync sync; internal static void Initialize(string pluginGuid, string displayName, string version) { sync = new ConfigSync(pluginGuid) { DisplayName = displayName, CurrentVersion = version, MinimumRequiredVersion = version, ModRequired = true }; } internal static void AddLockingConfigEntry(ConfigEntry<bool> entry) { sync.AddLockingConfigEntry<bool>(entry); } internal static void AddConfigEntry<T>(ConfigEntry<T> entry) { SyncedConfigEntry<T> syncedConfigEntry = sync.AddConfigEntry<T>(entry); syncedConfigEntry.SynchronizedConfig = true; } internal static void Reset() { sync = null; } } public class BalrondTranslator { public static Dictionary<string, Dictionary<string, string>> translations = new Dictionary<string, Dictionary<string, string>>(); public static Dictionary<string, string> getLanguage(string language) { Dictionary<string, string> result = null; try { result = translations[language]; } catch (Exception) { } return result; } } public static class ColliderSanitizer { public static void SanitizeForBuildPiece(GameObject visualRoot, bool removeAllMeshColliders, bool debugLog = false, string debugPrefix = null) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)visualRoot == (Object)null) { return; } RemoveMeshColliders(visualRoot, removeAllMeshColliders, debugLog, debugPrefix); if (!((Object)(object)visualRoot.GetComponentInChildren<Collider>(true) != (Object)null)) { Renderer componentInChildren = visualRoot.GetComponentInChildren<Renderer>(true); if (!((Object)(object)componentInChildren == (Object)null)) { AddPrimitiveColliderFromBounds(visualRoot, componentInChildren.bounds, debugLog, debugPrefix); } } } private static void RemoveMeshColliders(GameObject root, bool removeAll, bool debugLog, string debugPrefix) { MeshCollider[] componentsInChildren = root.GetComponentsInChildren<MeshCollider>(true); foreach (MeshCollider val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } Mesh sharedMesh = val.sharedMesh; if (removeAll || (Object)(object)sharedMesh == (Object)null || !sharedMesh.isReadable) { Object.Destroy((Object)(object)val); if (debugLog) { string text = (((Object)(object)sharedMesh != (Object)null) ? ((Object)sharedMesh).name : "null"); Debug.Log((object)(debugPrefix + " Removed MeshCollider on " + ((Object)root).name + " (mesh=" + text + ", removeAll=" + removeAll + ")")); } } } } private static void AddPrimitiveColliderFromBounds(GameObject root, Bounds worldBounds, bool debugLog, string debugPrefix) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) Vector3 center = root.transform.InverseTransformPoint(((Bounds)(ref worldBounds)).center); Vector3 lossyScale = root.transform.lossyScale; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(SafeDiv(((Bounds)(ref worldBounds)).size.x, lossyScale.x), SafeDiv(((Bounds)(ref worldBounds)).size.y, lossyScale.y), SafeDiv(((Bounds)(ref worldBounds)).size.z, lossyScale.z)); float num = Mathf.Max(val.x, val.z); if (val.y > num * 1.6f) { CapsuleCollider val2 = root.AddComponent<CapsuleCollider>(); val2.center = center; float num2 = num * 0.5f; val2.radius = Mathf.Max(0.01f, num2); val2.height = Mathf.Max(val2.radius * 2f, val.y); val2.direction = 1; if (debugLog) { Debug.Log((object)(debugPrefix + " Added CapsuleCollider fallback on " + ((Object)root).name)); } } else { BoxCollider val3 = root.AddComponent<BoxCollider>(); val3.center = center; val3.size = val; if (debugLog) { Debug.Log((object)(debugPrefix + " Added BoxCollider fallback on " + ((Object)root).name)); } } } private static float SafeDiv(float a, float b) { if (Mathf.Abs(b) < 0.0001f) { return a; } return a / b; } } public class DatabaseAddMethods { public void AddItems(List<GameObject> items) { foreach (GameObject item in items) { AddItem(item); } } public void AddRecipes(List<Recipe> recipes) { foreach (Recipe recipe in recipes) { AddRecipe(recipe); } } public void AddStatuseffects(List<StatusEffect> statusEffects) { foreach (StatusEffect statusEffect in statusEffects) { AddStatus(statusEffect); } } private bool IsObjectDBValid() { return (Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items.Count != 0 && ObjectDB.instance.m_recipes.Count != 0 && (Object)(object)ObjectDB.instance.GetItemPrefab("Amber") != (Object)null; } private void AddStatus(StatusEffect status) { if (!IsObjectDBValid()) { return; } if ((Object)(object)status != (Object)null) { if ((Object)(object)ObjectDB.instance.GetStatusEffect(status.m_nameHash) == (Object)null) { ObjectDB.instance.m_StatusEffects.Add(status); } else { Debug.Log((object)(Launch.projectName + ": " + ((Object)status).name + " - Status already in the game")); } } else { Debug.LogError((object)(Launch.projectName + ": " + ((Object)status).name + " - Status not found")); } } private void AddRecipe(Recipe recipe) { if (!IsObjectDBValid()) { return; } if ((Object)(object)recipe != (Object)null) { if ((Object)(object)ObjectDB.instance.m_recipes.Find((Recipe x) => ((Object)x).name == ((Object)recipe).name) == (Object)null) { if ((Object)(object)recipe.m_item != (Object)null) { ObjectDB.instance.m_recipes.Add(recipe); } } else { Debug.Log((object)(Launch.projectName + ": " + ((Object)recipe).name + " - Recipe with this name already in the Game")); } } else { Debug.LogError((object)(Launch.projectName + ": " + ((Object)recipe).name + " - Recipe not found")); } } private void AddItem(GameObject newPrefab) { if (!IsObjectDBValid()) { return; } ItemDrop component = newPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { if ((Object)(object)ObjectDB.instance.GetItemPrefab(((Object)newPrefab).name) == (Object)null) { ObjectDB.instance.m_items.Add(newPrefab); Dictionary<int, GameObject> dictionary = (Dictionary<int, GameObject>)typeof(ObjectDB).GetField("m_itemByHash", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(ObjectDB.instance); dictionary[((Object)newPrefab).name.GetHashCode()] = newPrefab; } else { Debug.Log((object)(Launch.projectName + ": " + ((Object)newPrefab).name + " - ItemDrop already exist")); } } else { Debug.LogError((object)(Launch.projectName + ": " + ((Object)newPrefab).name + " - ItemDrop not found on prefab")); } } } [Serializable] public class MappedEffectList { public List<EffectInfo> pieceEffect; public List<EffectInfo> destroyedEffects; public List<EffectInfo> hitEffects; public List<EffectInfo> switchEffect; public List<EffectInfo> blockEffect; public List<EffectInfo> equipEffect; public List<EffectInfo> hitEffect; public List<EffectInfo> hitTerrainEffect; public List<EffectInfo> holdStartEffect; public List<EffectInfo> startEffect; public List<EffectInfo> trailStartEffect; public List<EffectInfo> triggerEffect; public List<EffectInfo> unequipEffect; public EffectList createEffectListFromInfo(List<EffectInfo> list) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown EffectList val = new EffectList(); List<EffectData> list2 = new List<EffectData>(); val.m_effectPrefabs = list2.ToArray(); return val; } private EffectData createEffectData(EffectInfo info) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown EffectData val = new EffectData(); val.m_inheritParentRotation = info.inheritRotation; val.m_multiplyParentVisualScale = info.multiplyScale; val.m_childTransform = info.childName; val.m_inheritParentScale = info.inheritScale; val.m_variant = info.variant; val.m_scale = info.scale; val.m_attach = info.attach; val.m_follow = info.follow; val.m_prefab = ZNetScene.instance.m_prefabs.Find((GameObject x) => ((Object)x).name == info.name); return val; } } [Serializable] public struct EffectInfo { public string name; public bool enabled; public int variant; public bool attach; public bool follow; public bool inheritRotation; public bool inheritScale; public bool multiplyScale; public bool radnomRotation; public bool scale; public string childName; public EffectInfo(string name, bool enabled = true, int variant = -1, bool attach = false, bool follow = false, bool inheritRotation = false, bool inheritScale = false, bool multiplyScale = false, bool radnomRotation = false, bool scale = false, string childName = null) { this.name = name; this.enabled = enabled; this.variant = variant; this.attach = attach; this.follow = follow; this.inheritRotation = inheritRotation; this.inheritScale = inheritScale; this.multiplyScale = multiplyScale; this.radnomRotation = radnomRotation; this.scale = scale; this.childName = childName; } } public sealed class ModResourceLoader { public AssetBundle assetBundle; public readonly List<GameObject> itemPrefabs = new List<GameObject>(); public readonly List<GameObject> otherPrefabs = new List<GameObject>(); public void loadAssets() { assetBundle = GetAssetBundleFromResources("balrondweaponcrate"); if ((Object)(object)assetBundle == (Object)null) { Debug.LogWarning((object)(Launch.projectName + " AssetBundle not found (embedded resource endswith 'balrondweaponcrate').")); return; } string basePath = "Assets/Custom/BalrondWeaponCrate/"; loadItems(basePath); loadOther(basePath); } public void AddPrefabsToZnetScene(ZNetScene zNetScene) { if (!((Object)(object)zNetScene == (Object)null)) { validateAddedPrefabs(itemPrefabs, zNetScene); validateAddedPrefabs(otherPrefabs, zNetScene); zNetScene.m_prefabs.RemoveAll((GameObject x) => (Object)(object)x == (Object)null); } } private void loadItems(string basePath) { string[] nameList = new string[1] { "WeaponCrate_bal" }; addNewPrefabToCollection(nameList, basePath, itemPrefabs, "item", requireZNetView: false); } private void loadOther(string basePath) { string mainPath = basePath + "Other/"; string[] nameList = new string[0]; addNewPrefabToCollection(nameList, mainPath, otherPrefabs, "other", requireZNetView: false); } private void validateAddedPrefabs(List<GameObject> list, ZNetScene zNetScene) { if (list == null || (Object)(object)zNetScene == (Object)null) { return; } for (int i = 0; i < list.Count; i++) { GameObject val = list[i]; if (!((Object)(object)val == (Object)null)) { int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)val).name); if (zNetScene.m_namedPrefabs.ContainsKey(stableHashCode)) { Debug.LogWarning((object)("DUPLICATE: " + ((Object)val).name)); } else { zNetScene.m_prefabs.Add(val); } } } } private void addNewPrefabToCollection(string[] nameList, string mainPath, List<GameObject> prefabList, string typeName, bool requireZNetView) { if ((Object)(object)assetBundle == (Object)null || nameList == null || nameList.Length == 0) { return; } foreach (string text in nameList) { if (string.IsNullOrEmpty(text)) { continue; } GameObject val = assetBundle.LoadAsset<GameObject>(mainPath + text + ".prefab"); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("Could not find " + typeName + " with name: " + text + " at " + mainPath)); continue; } if (requireZNetView && (Object)(object)val.GetComponent<ZNetView>() == (Object)null) { Debug.LogWarning((object)("Prefab has no ZNetView (skipped): " + text)); continue; } ShaderReplacment.Replace(val); prefabList.Add(val); if (Launch.DebugLog) { Debug.Log((object)(Launch.projectName + " Loaded " + typeName + ": " + text)); } } } private static AssetBundle GetAssetBundleFromResources(string filenameSuffix) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = null; string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); foreach (string text2 in manifestResourceNames) { if (text2.EndsWith(filenameSuffix, StringComparison.OrdinalIgnoreCase)) { text = text2; break; } } if (text == null) { if (Launch.DebugLog) { Debug.LogWarning((object)(Launch.projectName + " Embedded resources: " + string.Join(", ", manifestResourceNames))); } return null; } using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { return null; } return AssetBundle.LoadFromStream(stream); } } public class ShaderReplacment { public static List<GameObject> prefabsToReplaceShader = new List<GameObject>(); public static List<Material> materialsInPrefabs = new List<Material>(); public string[] shaderlist = new string[49] { "Custom/AlphaParticle", "Custom/Blob", "Custom/Bonemass", "Custom/Clouds", "Custom/Creature", "Custom/Decal", "Custom/Distortion", "Custom/Flow", "Custom/FlowOpaque", "Custom/Grass", "Custom/GuiScroll", "Custom/Heightmap", "Custom/icon", "Custom/InteriorSide", "Custom/LitGui", "Custom/LitParticles", "Custom/mapshader", "Custom/ParticleDecal", "Custom/Piece", "Custom/Player", "Custom/Rug", "Custom/ShadowBlob", "Custom/SkyboxProcedural", "Custom/SkyObject", "Custom/StaticRock", "Custom/Tar", "Custom/Trilinearmap", "Custom/UI/BGBlur", "Custom/Vegetation", "Custom/Water", "Custom/WaterBottom", "Custom/WaterMask", "Custom/Yggdrasil", "Custom/Yggdrasil/root", "Hidden/BlitCopyHDRTonemap", "Hidden/Dof/DepthOfFieldHdr", "Hidden/Dof/DX11Dof", "Hidden/Internal-Loading", "Hidden/Internal-UIRDefaultWorld", "Hidden/SimpleClear", "Hidden/SunShaftsComposite", "Lux Lit Particles/ Bumped", "Lux Lit Particles/ Tess Bumped", "Particles/Standard Surface2", "Particles/Standard Unlit2", "Standard TwoSided", "ToonDeferredShading2017", "Unlit/DepthWrite", "Unlit/Lighting" }; public static List<Shader> shaders = new List<Shader>(); private static readonly HashSet<Shader> CachedShaders = new HashSet<Shader>(); public static bool debug = true; public static Shader findShader(string name) { Shader[] array = Resources.FindObjectsOfTypeAll<Shader>(); if (array.Length == 0) { Debug.LogWarning((object)"SHADER LIST IS EMPTY!"); return null; } if (debug) { } return shaders.Find((Shader x) => ((Object)x).name == name); } public static Shader GetShaderByName(string name) { return shaders.Find((Shader x) => ((Object)x).name == name.Trim()); } public static void debugShaderList(List<Shader> shadersRes) { foreach (Shader shadersRe in shadersRes) { Debug.LogWarning((object)("SHADER NAME IS: " + ((Object)shadersRe).name)); } debug = false; } public static void Replace(GameObject gameObject) { prefabsToReplaceShader.Add(gameObject); GetMaterialsInPrefab(gameObject); } public static void GetMaterialsInPrefab(GameObject gameObject) { Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { Material[] sharedMaterials = val.sharedMaterials; if (sharedMaterials == null || sharedMaterials.Length == 0) { continue; } Material[] array2 = sharedMaterials; foreach (Material val2 in array2) { if ((Object)(object)val2 != (Object)null) { materialsInPrefabs.Add(val2); } } } } public static void getMeShaders() { AssetBundle[] array = Resources.FindObjectsOfTypeAll<AssetBundle>(); AssetBundle[] array2 = array; foreach (AssetBundle val in array2) { IEnumerable<Shader> enumerable3; try { IEnumerable<Shader> enumerable2; if (!val.isStreamedSceneAssetBundle || !Object.op_Implicit((Object)(object)val)) { IEnumerable<Shader> enumerable = val.LoadAllAssets<Shader>(); enumerable2 = enumerable; } else { enumerable2 = from shader in ((IEnumerable<string>)val.GetAllAssetNames()).Select((Func<string, Shader>)val.LoadAsset<Shader>) where (Object)(object)shader != (Object)null select shader; } enumerable3 = enumerable2; } catch (Exception) { continue; } if (enumerable3 == null) { continue; } foreach (Shader item in enumerable3) { CachedShaders.Add(item); } } } public static void runMaterialFix() { getMeShaders(); shaders.AddRange(CachedShaders); foreach (Material materialsInPrefab in materialsInPrefabs) { Shader shader = materialsInPrefab.shader; if (!((Object)(object)shader == (Object)null)) { string name = ((Object)shader).name; if (!(name == "Standard") && !name.Contains("ScrollingTex") && name.Contains("Balrond")) { setProperValue(materialsInPrefab, name); } } } } private static void setProperValue(Material material, string shaderName) { string name = shaderName.Replace("Balrond", "Custom"); name = checkNaming(name); Shader shaderByName = GetShaderByName(name); if ((Object)(object)shaderByName == (Object)null) { Debug.LogWarning((object)("Shader not found " + name)); } else { material.shader = shaderByName; } } private static string checkNaming(string name) { string result = name; if (name.Contains("Bumped")) { result = name.Replace("Custom", "Lux Lit Particles"); } if (name.Contains("Tess Bumped")) { result = name.Replace("Custom", "Lux Lit Particles"); } if (name.Contains("Standard Surface")) { result = name.Replace("Custom", "Particles"); result = result.Replace("Standard Surface2", "Standard Surface"); } if (name.Contains("Standard Unlit")) { result = name.Replace("Custom", "Particles"); result = result.Replace("Standard Unlit", "Standard Unlit2"); result = result.Replace("Standard Unlit22", "Standard Unlit2"); } return result; } } public class TableMapper { public static CraftingStation cauldron; public static CraftingStation workbench; public static CraftingStation heavyWorkbench; public static CraftingStation forge; public static CraftingStation ironworks; public static CraftingStation blackforge; public static CraftingStation stoneCutter; public static CraftingStation artisian; public static CraftingStation magetable; public static CraftingStation runeforge; public static CraftingStation tannery; public static CraftingStation fletcher; public static CraftingStation grill; public static CraftingStation alchemylab; public static CraftingStation shamantable; public static CraftingStation foodtable; public static List<GameObject> pieces = new List<GameObject>(); public static void setupTables(List<GameObject> list) { pieces = list; prepareTables(); } private static CraftingStation FindStation(List<GameObject> list, string name, string replacement = "piece_workbench") { GameObject val = list.Find((GameObject x) => ((Object)x).name == name); if ((Object)(object)val != (Object)null) { return val.GetComponent<CraftingStation>(); } if ((Object)(object)val == (Object)null) { val = list.Find((GameObject x) => ((Object)x).name == replacement); if ((Object)(object)val != (Object)null) { return val.GetComponent<CraftingStation>(); } } Debug.LogWarning((object)("TableMapper - Station not found: " + name)); return null; } private static void prepareTables() { cauldron = FindStation(pieces, "piece_cauldron"); workbench = FindStation(pieces, "piece_workbench"); heavyWorkbench = FindStation(pieces, "piece_heavy_workbench_bal"); forge = FindStation(pieces, "forge"); ironworks = FindStation(pieces, "piece_metalworks_bal", "forge"); blackforge = FindStation(pieces, "blackforge"); stoneCutter = FindStation(pieces, "piece_stonecutter"); artisian = FindStation(pieces, "piece_artisanstation"); runeforge = FindStation(pieces, "piece_runeforge_bal", "blackforge"); magetable = FindStation(pieces, "piece_magetable"); fletcher = FindStation(pieces, "piece_fletcher_bal"); shamantable = FindStation(pieces, "piece_shamantable_bal", "piece_magetable"); foodtable = FindStation(pieces, "piece_preptable"); alchemylab = FindStation(pieces, "piece_MeadCauldron"); } } public class ItemUtils { public static bool IsWeaponType(ItemType type, bool shieldsAreWeapons) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 if ((int)type == 3) { return true; } if ((int)type == 14) { return true; } if ((int)type == 22) { return true; } if ((int)type == 4) { return true; } if ((int)type == 15) { return true; } if ((int)type == 5) { return shieldsAreWeapons; } return false; } public static bool IsArmorType(ItemType type, bool shieldsAreWeapons) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 if ((int)type == 6) { return true; } if ((int)type == 7) { return true; } if ((int)type == 11) { return true; } if ((int)type == 17) { return true; } if ((int)type == 18) { return true; } if ((int)type == 5) { return !shieldsAreWeapons; } return false; } public static bool HasAnyIcon(ItemDrop drop) { if ((Object)(object)drop == (Object)null || drop.m_itemData == null || drop.m_itemData.m_shared == null) { return false; } try { Sprite[] icons = drop.m_itemData.m_shared.m_icons; return icons != null && icons.Length != 0 && (Object)(object)icons[0] != (Object)null; } catch { return false; } } public static Sprite SafeFirstIcon(ItemDrop drop) { try { Sprite[] icons = drop.m_itemData.m_shared.m_icons; if (icons != null && icons.Length != 0) { return icons[0]; } } catch { } return null; } public static bool HasUsableVisual(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { return false; } Transform val = FindChildRecursiveByName(prefab.transform, "attach"); if ((Object)(object)val != (Object)null && !((Object)val).name.Equals("attach_skin", StringComparison.OrdinalIgnoreCase)) { return true; } MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>(true); if (componentsInChildren == null || componentsInChildren.Length == 0) { return false; } foreach (MeshRenderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null)) { GameObject gameObject = ((Component)val2).gameObject; if (!((Object)(object)gameObject == (Object)null) && !((Object)(object)gameObject.GetComponent<SkinnedMeshRenderer>() != (Object)null)) { return true; } } } return false; } public static Transform FindChildRecursiveByName(Transform root, string wantedName) { if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(wantedName)) { return null; } Queue<Transform> queue = new Queue<Transform>(); queue.Enqueue(root); while (queue.Count > 0) { Transform val = queue.Dequeue(); if (!((Object)(object)val == (Object)null)) { if (!string.IsNullOrEmpty(((Object)val).name) && ((Object)val).name.Equals(wantedName, StringComparison.OrdinalIgnoreCase)) { return val; } for (int i = 0; i < val.childCount; i++) { queue.Enqueue(val.GetChild(i)); } } } return null; } public static GameObject PickVisualRoot(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { return null; } Transform val = FindChildRecursiveByName(prefab.transform, "attach"); if ((Object)(object)val != (Object)null && !((Object)val).name.Equals("attach_skin", StringComparison.OrdinalIgnoreCase)) { return ((Component)val).gameObject; } MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>(true); if (componentsInChildren == null || componentsInChildren.Length == 0) { return null; } foreach (MeshRenderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null)) { GameObject gameObject = ((Component)val2).gameObject; if (!((Object)(object)gameObject == (Object)null) && !((Object)(object)gameObject.GetComponent<SkinnedMeshRenderer>() != (Object)null)) { return gameObject; } } } return null; } } public class JsonLoader { public string defaultPath = string.Empty; public void loadJson() { LoadTranslations(); justDefaultPath(); } public void justDefaultPath() { string configPath = Paths.ConfigPath; string text = Path.Combine(configPath, "ZBalrondWeaponCrate-translation/"); defaultPath = text; } public void createDefaultPath() { string configPath = Paths.ConfigPath; string text = Path.Combine(configPath, "ZBalrondWeaponCrate-translation/"); if (!Directory.Exists(text)) { CreateFolder(text); } else { Debug.Log((object)("ZBalrondWeaponCrate: Folder already exists: " + text)); } defaultPath = text; } private string[] jsonFilePath(string folderName, string extension) { string configPath = Paths.ConfigPath; string text = Path.Combine(configPath, "ZBalrondWeaponCrate-translation/"); if (!Directory.Exists(text)) { CreateFolder(text); } else { Debug.Log((object)("ZBalrondWeaponCrate: Folder already exists: " + text)); } string[] files = Directory.GetFiles(text, extension); Debug.Log((object)("ZBalrondWeaponCrate:" + folderName + " Json Files Found: " + files.Length)); return files; } private static void CreateFolder(string path) { try { Directory.CreateDirectory(path); Debug.Log((object)"ZBalrondWeaponCrate: Folder created successfully."); } catch (Exception ex) { Debug.Log((object)("ZBalrondWeaponCrate: Error creating folder: " + ex.Message)); } } private void LoadTranslations() { int num = 0; string[] array = jsonFilePath("Translation", "*.json"); foreach (string text in array) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text); string json = File.ReadAllText(text); JsonData jsonData = JsonMapper.ToObject(json); Dictionary<string, string> dictionary = new Dictionary<string, string>(); foreach (string key in jsonData.Keys) { dictionary[key] = jsonData[key].ToString(); } if (dictionary != null) { BalrondTranslator.translations.Add(fileNameWithoutExtension, dictionary); Debug.Log((object)("ZBalrondWeaponCrate: Json Files Language: " + fileNameWithoutExtension)); num++; } else { Debug.LogError((object)("ZBalrondWeaponCrate: Loading FAILED file: " + text)); } } Debug.Log((object)("ZBalrondWeaponCrate: Translation JsonFiles Loaded: " + num)); } } [BepInPlugin("balrond.astafaraios.ZBalrondWeaponCrate", "ZBalrondWeaponCrate", "0.1.2")] public sealed class Launch : BaseUnityPlugin { [HarmonyPatch] private static class AudioMan_Initialize_Patch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(AudioMan), "Awake", (Type[])null, (Type[])null) ?? AccessTools.Method(typeof(AudioMan), "Start", (Type[])null, (Type[])null) ?? AccessTools.Method(typeof(AudioMan), "OnEnable", (Type[])null, (Type[])null) ?? throw new MissingMethodException(typeof(AudioMan).FullName, "Awake/Start/OnEnable"); } private static void Postfix(AudioMan __instance) { AudioRoutingService.OnAudioManAwake(__instance); } } [HarmonyPatch(typeof(FejdStartup), "SetupGui")] private static class FejdStartup_SetupGUI { private static void Postfix() { bool flag = false; string selectedLanguage = Localization.instance.GetSelectedLanguage(); Dictionary<string, string> dictionary = BalrondTranslator.getLanguage("English"); if ("English" != selectedLanguage) { Dictionary<string, string> language = BalrondTranslator.getLanguage(selectedLanguage); if (language != null) { dictionary = language; } else { Debug.Log((object)"ZBalrondWeaponCrate: Did not find translation file loading English"); } } if (dictionary != null) { foreach (KeyValuePair<string, string> item in dictionary) { Localization.instance.AddWord(item.Key, item.Value); } return; } Debug.LogWarning((object)"ZBalrondWeaponCrate: No translation file found!"); } } [HarmonyPriority(800)] [HarmonyPatch(typeof(Localization), "SetupLanguage")] private static class Translation_SetupLanguage { private static void Prefix(Localization __instance, string language) { bool flag = false; Dictionary<string, string> dictionary = BalrondTranslator.getLanguage("English"); if ("English" != language) { Dictionary<string, string> language2 = BalrondTranslator.getLanguage(language); if (language2 != null) { dictionary = language2; } else { Debug.Log((object)"ZBalrondWeaponCrate: Did not find translation file loading English"); } } if (dictionary != null) { foreach (KeyValuePair<string, string> item in dictionary) { __instance.AddWord(item.Key, item.Value); } return; } Debug.LogWarning((object)"ZBalrondWeaponCrate: No translation file found!"); } } [HarmonyPriority(800)] [HarmonyPatch(typeof(Localization), "LoadCSV")] private static class Translation_LoadCSV { private static void Prefix(Localization __instance, string language) { bool flag = false; Dictionary<string, string> dictionary = BalrondTranslator.getLanguage("English"); if ("English" != language) { Dictionary<string, string> language2 = BalrondTranslator.getLanguage(language); if (language2 != null) { dictionary = language2; } else { Debug.Log((object)"ZBalrondWeaponCrate: Did not find translation file loading English"); } } if (dictionary != null) { foreach (KeyValuePair<string, string> item in dictionary) { __instance.AddWord(item.Key, item.Value); } return; } Debug.LogWarning((object)"ZBalrondWeaponCrate: No translation file found!"); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetScene_Awake_Path { private static bool ranFix; private static void Prefix(ZNetScene __instance) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 bool flag = false; if (!((Object)(object)__instance == (Object)null)) { modResourceLoader.AddPrefabsToZnetScene(__instance); if (!ranFix && (int)SystemInfo.graphicsDeviceType != 4) { ShaderReplacment.runMaterialFix(); ranFix = true; } } } private static void Postfix() { if (IsObjectDBValid()) { recipeFactory.EnsureRecipes(); } } } [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDB_Awake_Path { private static void Postfix() { bool flag = false; if (IsObjectDBValid()) { databaseAddMethods.AddItems(modResourceLoader.itemPrefabs); recipeFactory.EnsureRecipes(); weaponCrateBuilder.BuildWeaponCratePieces(); } } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class Object_CopyOtherDB_Path { private static void Postfix() { bool flag = false; if (IsObjectDBValid()) { databaseAddMethods.AddItems(modResourceLoader.itemPrefabs); recipeFactory.EnsureRecipes(); weaponCrateBuilder.BuildWeaponCratePieces(); } } } private Harmony harmony; public const string PluginGUID = "balrond.astafaraios.ZBalrondWeaponCrate"; public const string PluginName = "ZBalrondWeaponCrate"; public const string PluginVersion = "0.1.2"; public static DatabaseAddMethods databaseAddMethods = new DatabaseAddMethods(); public static readonly ModResourceLoader modResourceLoader = new ModResourceLoader(); public static readonly WeaponCrateBuilder weaponCrateBuilder = new WeaponCrateBuilder(); public static readonly RecipeFactory recipeFactory = new RecipeFactory(); public static readonly JsonLoader jsonLoader = new JsonLoader(); public static readonly string projectName = "[ZBalrondWeaponCrate]"; public const bool Enabled = true; public const string WeaponCratePrefabName = "WeaponCrate_bal"; public const string TemplatePrefabName = "FierySvinstew"; public const PieceCategory WeaponCategory = (PieceCategory)7; public const PieceCategory ArmorCategory = (PieceCategory)6; public static bool DebugLog => WeaponCrateConfig.DebugLogging != null && WeaponCrateConfig.DebugLogging.Value; public static bool ShieldsAreWeapons => WeaponCrateConfig.ShieldsAreWeapons == null || WeaponCrateConfig.ShieldsAreWeapons.Value; public static bool ForceCostToSelf => WeaponCrateConfig.ForceCostToSelf == null || WeaponCrateConfig.ForceCostToSelf.Value; public static int CostAmount => (WeaponCrateConfig.CostAmount == null) ? 1 : Math.Max(1, WeaponCrateConfig.CostAmount.Value); public static bool RequireAttachChild => WeaponCrateConfig.RequireAttachChild != null && WeaponCrateConfig.RequireAttachChild.Value; public static string[] ManualIncludeWeapons => WeaponCrateConfig.ParsePrefabList(WeaponCrateConfig.ManualIncludeWeapons); public static string[] ManualIncludeArmors => WeaponCrateConfig.ParsePrefabList(WeaponCrateConfig.ManualIncludeArmors); public static string[] ManualExclude => WeaponCrateConfig.ParsePrefabList(WeaponCrateConfig.ManualExclude); private void Awake() { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown ServerSyncBridge.Initialize("balrond.astafaraios.ZBalrondWeaponCrate", "ZBalrondWeaponCrate", "0.1.2"); WeaponCrateConfig.Bind(((BaseUnityPlugin)this).Config); AudioRoutingService.ConfigureLogging(delegate(string message) { ((BaseUnityPlugin)this).Logger.LogInfo((object)message); }, delegate(string message) { ((BaseUnityPlugin)this).Logger.LogWarning((object)message); }, delegate(string message) { ((BaseUnityPlugin)this).Logger.LogError((object)message); }); AudioRoutingService.DebugLogging = WeaponCrateConfig.AudioDebugLogging.Value; WeaponCrateConfig.AudioDebugLogging.SettingChanged += delegate { AudioRoutingService.DebugLogging = WeaponCrateConfig.AudioDebugLogging.Value; }; jsonLoader.loadJson(); bool flag = true; modResourceLoader.loadAssets(); AudioRoutingService.Process((IEnumerable<GameObject>)modResourceLoader.itemPrefabs); AudioRoutingService.Process((IEnumerable<GameObject>)modResourceLoader.otherPrefabs); harmony = new Harmony("balrond.astafaraios.ZBalrondWeaponCrate"); harmony.PatchAll(); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } ServerSyncBridge.Reset(); } public static bool IsObjectDBValid() { return (Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items != null && ObjectDB.instance.m_items.Count != 0 && (Object)(object)ObjectDB.instance.GetItemPrefab("Amber") != (Object)null; } internal static void Log(string msg) { if (DebugLog) { Debug.Log((object)(projectName + " " + msg)); } } } public static class ItemVfxApplier { public static GameObject ApplyTemplateSparkles(GameObject targetPrefab, Transform templateSparkles, bool debugLog = false, string debugPrefix = null) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)targetPrefab == (Object)null || (Object)(object)templateSparkles == (Object)null) { return null; } Transform val = ItemUtils.FindChildRecursiveByName(targetPrefab.transform, ((Object)templateSparkles).name); if ((Object)(object)val != (Object)null) { return ((Component)val).gameObject; } try { GameObject val2 = Object.Instantiate<GameObject>(((Component)templateSparkles).gameObject); ((Object)val2).name = ((Object)templateSparkles).name; val2.transform.SetParent(targetPrefab.transform, false); val2.transform.localPosition = templateSparkles.localPosition; val2.transform.localRotation = templateSparkles.localRotation; val2.transform.localScale = templateSparkles.localScale; return val2; } catch (Exception ex) { if (debugLog) { Debug.LogWarning((object)(debugPrefix + " Failed cloning sparkles onto " + ((Object)targetPrefab).name + ": " + ex)); } return null; } } public static void StripRootParticleSystems(GameObject targetPrefab, bool debugLog = false, string debugPrefix = null) { if ((Object)(object)targetPrefab == (Object)null) { return; } try { ParticleSystem[] components = targetPrefab.GetComponents<ParticleSystem>(); ParticleSystem[] array = components; foreach (ParticleSystem val in array) { Object.Destroy((Object)(object)val); } ParticleSystemRenderer[] components2 = targetPrefab.GetComponents<ParticleSystemRenderer>(); ParticleSystemRenderer[] array2 = components2; foreach (ParticleSystemRenderer val2 in array2) { Object.Destroy((Object)(object)val2); } } catch (Exception ex) { if (debugLog) { Debug.LogWarning((object)(debugPrefix + " Failed stripping root ParticleSystems on " + ((Object)targetPrefab).name + ": " + ex)); } } } public static GameObject ApplySparklesAndCleanRoot(GameObject targetPrefab, Transform templateSparkles, bool debugLog = false, string debugPrefix = null) { GameObject result = ApplyTemplateSparkles(targetPrefab, templateSparkles, debugLog, debugPrefix); StripRootParticleSystems(targetPrefab, debugLog, debugPrefix); return result; } } public class PieceNTearSetter { public static void CopyPieceSettings(ItemDrop drop, Piece dst, Piece src) { //IL_004d: 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) dst.m_allowAltGroundPlacement = true; dst.m_allowedInDungeons = true; dst.m_allowRotatedOverlap = true; dst.m_blockingPieces = src.m_blockingPieces; dst.m_blockRadius = 0f; dst.m_notOnTiltingSurface = false; dst.m_canBeRemoved = true; dst.m_canRotate = true; if (!ItemUtils.IsArmorType(drop.m_itemData.m_shared.m_itemType, shieldsAreWeapons: true)) { dst.m_clipEverything = true; dst.m_clipGround = true; } dst.m_comfort = 0; dst.m_comfortGroup = src.m_comfortGroup; dst.m_comfortObject = src.m_comfortObject; dst.m_connectRadius = src.m_connectRadius; dst.m_craftingStation = src.m_craftingStation; dst.m_cultivatedGroundOnly = false; dst.m_groundOnly = src.m_groundOnly; dst.m_groundPiece = src.m_groundPiece; ((StaticTarget)dst).m_haveCenter = ((StaticTarget)src).m_haveCenter; dst.m_inCeilingOnly = src.m_inCeilingOnly; dst.m_isUpgrade = false; dst.m_mustBeAboveConnected = src.m_mustBeAboveConnected; dst.m_mustConnectTo = src.m_mustConnectTo; dst.m_waterPiece = src.m_waterPiece; dst.m_vegetationGroundOnly = false; dst.m_targetNonPlayerBuilt = false; dst.m_spaceRequirement = 0f; dst.m_placeEffect = src.m_placeEffect; dst.m_returnResourceHeightOffset = src.m_returnResourceHeightOffset; } public static void CopyWearNTearSettings(WearNTear dst, WearNTear src) { //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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) dst.m_ashDamageImmune = src.m_ashDamageImmune; dst.m_ashDamageResist = src.m_ashDamageResist; dst.m_ashMaterialValue = src.m_ashMaterialValue; dst.m_ashDamageTime = src.m_ashDamageTime; dst.m_ashroof = src.m_ashroof; dst.m_autoCreateFragments = src.m_autoCreateFragments; dst.m_biome = src.m_biome; dst.m_health = src.m_health; dst.m_hitEffect = src.m_hitEffect; dst.m_hitNoise = src.m_hitNoise; dst.m_minToolTier = src.m_minToolTier; dst.m_burnable = src.m_burnable; dst.m_destroyedEffect = src.m_destroyedEffect; dst.m_switchEffect = src.m_switchEffect; dst.m_damages = src.m_damages; dst.m_destroyNoise = src.m_destroyNoise; dst.m_support = src.m_support; dst.m_staticPosition = src.m_staticPosition; dst.m_noSupportWear = src.m_noSupportWear; dst.m_noRoofWear = src.m_noRoofWear; } public static void SetSingleRequirement(Piece piece, string resPrefabName, int amount, int amountPerLevel, bool recover) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(resPrefabName); if ((Object)(object)itemPrefab == (Object)null) { Debug.LogWarning((object)(Launch.projectName + " Cost item not found: " + resPrefabName + " (fallback Wood)")); itemPrefab = ObjectDB.instance.GetItemPrefab("Wood"); } Requirement val = new Requirement { m_resItem = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null), m_amount = amount, m_amountPerLevel = amountPerLevel, m_recover = recover }; piece.m_resources = (Requirement[])(object)new Requirement[1] { val }; } } public sealed class RecipeFactory { private const string DefaultStationPrefab = "piece_workbench"; private const int DefaultStationLevel = 1; public void EnsureRecipes() { if (Launch.IsObjectDBValid()) { EnsureWeaponCrateRecipe(); } } private void EnsureWeaponCrateRecipe() { string text = "WeaponCrate_bal"; string text2 = "Recipe_" + text; ItemDrop val = ResolveItemDrop(text, allowInjectIntoObjectDB: true); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("ZBalrondWeaponCrate: RecipeFactory - could not resolve ItemDrop for: " + text + " (not found in ObjectDB nor ZNetScene)")); return; } Recipe val2 = FindRecipeByName(text2); if ((Object)(object)val2 != (Object)null) { EnsureWorkbench(val2); return; } Recipe val3 = FindRecipeByItem(val); if ((Object)(object)val3 != (Object)null) { return; } CraftingStation val4 = FindStation("piece_workbench"); if (!((Object)(object)val4 == (Object)null)) { Recipe val5 = ScriptableObject.CreateInstance<Recipe>(); ((Object)val5).name = text2; val5.m_item = val; val5.m_amount = 1; val5.m_enabled = true; val5.m_craftingStation = val4; val5.m_minStationLevel = 1; val5.m_repairStation = val5.m_craftingStation; List<Requirement> list = new List<Requirement> { CreateReq("Wood", 10, 0, recover: true), CreateReq("BronzeNails", 2, 0, recover: true) }; list.RemoveAll((Requirement r) => r == null || (Object)(object)r.m_resItem == (Object)null); val5.m_resources = list.ToArray(); if (ObjectDB.instance.m_recipes == null) { ObjectDB.instance.m_recipes = new List<Recipe>(); } ObjectDB.instance.m_recipes.Add(val5); RefreshObjectDBLookups(ObjectDB.instance); Debug.Log((object)("ZBalrondWeaponCrate: Added recipe: " + text2 + " (station=" + (((Object)(object)val5.m_craftingStation != (Object)null) ? ((Object)val5.m_craftingStation).name : "none/hand") + ")")); } } private static void EnsureWorkbench(Recipe recipe) { if (!((Object)(object)recipe == (Object)null) && !((Object)(object)recipe.m_craftingStation != (Object)null)) { CraftingStation val = FindStation("piece_workbench"); if (!((Object)(object)val == (Object)null)) { recipe.m_craftingStation = val; recipe.m_repairStation = val; recipe.m_minStationLevel = 1; RefreshObjectDBLookups(ObjectDB.instance); } } } private static ItemDrop ResolveItemDrop(string itemPrefabName, bool allowInjectIntoObjectDB) { if (string.IsNullOrEmpty(itemPrefabName)) { return null; } GameObject val = null; if ((Object)(object)ObjectDB.instance != (Object)null) { val = ObjectDB.instance.GetItemPrefab(itemPrefabName); if ((Object)(object)val == (Object)null && ObjectDB.instance.m_items != null) { val = ObjectDB.instance.m_items.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == itemPrefabName); } } if ((Object)(object)val == (Object)null && (Object)(object)ZNetScene.instance != (Object)null) { val = ZNetScene.instance.GetPrefab(itemPrefabName); } if ((Object)(object)val == (Object)null) { return null; } ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { return null; } if (allowInjectIntoObjectDB && (Object)(object)ObjectDB.instance != (Object)null) { if (ObjectDB.instance.m_items == null) { ObjectDB.instance.m_items = new List<GameObject>(); } bool flag = false; for (int num = 0; num < ObjectDB.instance.m_items.Count; num++) { GameObject val2 = ObjectDB.instance.m_items[num]; if ((Object)(object)val2 != (Object)null && ((Object)val2).name == ((Object)val).name) { flag = true; break; } } if (!flag) { ObjectDB.instance.m_items.Add(val); RefreshObjectDBLookups(ObjectDB.instance); if (Launch.DebugLog) { Debug.Log((object)("ZBalrondWeaponCrate: RecipeFactory - injected item prefab into ObjectDB.m_items: " + ((Object)val).name)); } } } return component; } private static CraftingStation FindStation(string stationPrefabName) { if (string.IsNullOrEmpty(stationPrefabName)) { return null; } if ((Object)(object)ZNetScene.instance == (Object)null) { return null; } GameObject prefab = ZNetScene.instance.GetPrefab(stationPrefabName); if ((Object)(object)prefab == (Object)null) { return null; } return prefab.GetComponent<CraftingStation>(); } private static Requirement CreateReq(string itemPrefabName, int amount, int amountPerLevel, bool recover) { //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown if (string.IsNullOrEmpty(itemPrefabName) || (Object)(object)ObjectDB.instance == (Object)null) { return null; } GameObject val = ObjectDB.instance.GetItemPrefab(itemPrefabName); if ((Object)(object)val == (Object)null && ObjectDB.instance.m_items != null) { val = ObjectDB.instance.m_items.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == itemPrefabName); } if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("ZBalrondWeaponCrate: RecipeFactory - requirement item not found: " + itemPrefabName)); return null; } ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { Debug.LogWarning((object)("ZBalrondWeaponCrate: RecipeFactory - requirement ItemDrop missing: " + itemPrefabName)); return null; } return new Requirement { m_resItem = component, m_amount = amount, m_amountPerLevel = amountPerLevel, m_recover = recover }; } private static Recipe FindRecipeByName(string recipeName) { if ((Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_recipes == null || string.IsNullOrEmpty(recipeName)) { return null; } for (int i = 0; i < ObjectDB.instance.m_recipes.Count; i++) { Recipe val = ObjectDB.instance.m_recipes[i]; if ((Object)(object)val != (Object)null && ((Object)val).name == recipeName) { return val; } } return null; } private static Recipe FindRecipeByItem(ItemDrop item) { if ((Object)(object)item == (Object)null || (Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_recipes == null) { return null; } for (int i = 0; i < ObjectDB.instance.m_recipes.Count; i++) { Recipe val = ObjectDB.instance.m_recipes[i]; if ((Object)(object)val != (Object)null && (Object)(object)val.m_item == (Object)(object)item) { return val; } if ((Object)(object)val != (Object)null && (Object)(object)val.m_item != (Object)null && (Object)(object)((Component)val.m_item).gameObject != (Object)null && (Object)(object)((Component)item).gameObject != (Object)null && ((Object)((Component)val.m_item).gameObject).name == ((Object)((Component)item).gameObject).name) { return val; } } return null; } private static void RefreshObjectDBLookups(ObjectDB db) { if (!((Object)(object)db == (Object)null)) { InvokeIfExists(db, "UpdateItemHashes"); InvokeIfExists(db, "UpdateRecipeHashes"); InvokeIfExists(db, "UpdateCraftingStations"); } } private static void InvokeIfExists(object target, string methodName) { try { if (target != null && !string.IsNullOrEmpty(methodName)) { MethodInfo method = target.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(method == null) && method.GetParameters().Length == 0) { method.Invoke(target, null); } } } catch (Exception ex) { if (Launch.DebugLog) { Debug.LogWarning((object)("ZBalrondWeaponCrate: RecipeFactory - failed invoking " + methodName + ": " + ex)); } } } } [HarmonyPatch] public static class WeaponCrateRotatePatch { public sealed class WeaponCratePieceMarker : MonoBehaviour { } private sealed class State { public int GhostId = -1; public float XAngle = 0f; public float ZAngle = 0f; public Vector3 Offset = Vector3.zero; public float TiltScroll; public int LastFrame = -1; public Renderer[] Renderers; public float RenderersTime = -1f; } private sealed class WheelState { public int Rotation; public float Scroll; } private const float TiltStep = 15f; private const float MetresPerSecond = 0.5f; private const float MaxOffset = 2f; public static int CurrentPose; private static readonly ConditionalWeakTable<Player, State> s_state = new ConditionalWeakTable<Player, State>(); private static readonly List<Renderer> s_renderers = new List<Renderer>(); private static State Get(Player p) { return s_state.GetOrCreateValue(p); } private static bool AltDown() { return ZInput.GetKey((KeyCode)308, true) || ZInput.GetKey((KeyCode)307, true); } private static bool CtrlDown() { return ZInput.GetKey((KeyCode)306, true) || ZInput.GetKey((KeyCode)305, true); } public static bool KeyDown(ConfigEntry<KeyCode> key) { //IL_0005: 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) return key != null && (int)key.Value != 0 && ZInput.GetKey(key.Value, true); } private static float Axis(ConfigEntry<KeyCode> plus, ConfigEntry<KeyCode> minus) { return (KeyDown(plus) ? 1f : 0f) - (KeyDown(minus) ? 1f : 0f); } private static Vector3 Flat(Vector3 v) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_002c: Unknown result type (might be due to invalid IL or missing references) v.y = 0f; return (((Vector3)(ref v)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref v)).normalized : Vector3.zero; } [HarmonyPatch(typeof(Player), "UpdatePlacement")] [HarmonyPrefix] private static void UpdatePlacement_TiltPrefix(Player __instance, bool takeInput, out WheelState __state) { __state = null; if (!takeInput || (Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !((Character)__instance).InPlaceMode() || Hud.IsPieceSelectionVisible()) { return; } GameObject placementGhost = __instance.m_placementGhost; if ((Object)(object)placementGhost == (Object)null || !placementGhost.activeInHierarchy || (Object)(object)placementGhost.GetComponent<WeaponCratePieceMarker>() == (Object)null) { return; } bool flag = CtrlDown(); bool flag2 = AltDown(); if (!flag && !flag2) { return; } __state = new WheelState { Rotation = __instance.m_placeRotation, Scroll = __instance.m_scrollCurrAmount }; State state = Get(__instance); state.TiltScroll += ZInput.GetMouseScrollWheel(); float scrollAmountThreshold = __instance.m_scrollAmountThreshold; int num = 0; if (state.TiltScroll > scrollAmountThreshold) { state.TiltScroll = 0f; num = 1; } else if (state.TiltScroll < 0f - scrollAmountThreshold) { state.TiltScroll = 0f; num = -1; } if (num != 0) { if (flag) { state.XAngle = Mathf.Repeat(state.XAngle + (float)num * 15f, 360f); } if (flag2) { state.ZAngle = Mathf.Repeat(state.ZAngle + (float)num * 15f, 360f); } } } [HarmonyPatch(typeof(Player), "UpdatePlacement")] [HarmonyPostfix] private static void UpdatePlacement_TiltPostfix(Player __instance, WheelState __state) { if (__state != null && !((Object)(object)__instance == (Object)null)) { __instance.m_placeRotation = __state.Rotation; __instance.m_scrollCurrAmount = __state.Scroll; } } [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] [HarmonyPostfix] private static void UpdatePlacementGhost_Postfix(Player __instance, bool flashGuardStone) { //IL_00a1: 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_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_032e: 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_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: 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) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0223: 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_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !((Character)__instance).InPlaceMode()) { return; } GameObject placementGhost = __instance.m_placementGhost; if ((Object)(object)placementGhost == (Object)null || !placementGhost.activeSelf || (Object)(object)placementGhost.GetComponent<WeaponCratePieceMarker>() == (Object)null) { return; } State state = Get(__instance); int instanceID = ((Object)placementGhost).GetInstanceID(); if (state.GhostId != instanceID) { state.GhostId = instanceID; state.XAngle = 0f; state.ZAngle = 0f; state.Offset = Vector3.zero; state.Renderers = null; } if (state.LastFr