Files
Ultimate-Fishing-Simulator-…/Assets/Scripts/Assembly-CSharp/MonoBehaviourExtended.cs
2026-03-04 09:37:33 +08:00

1753 lines
42 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MonoBehaviourExtended : MonoBehaviour
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
protected class DependencyAttribute : PropertyAttribute
{
public string Of { get; set; }
public int Offset { get; set; }
public bool Optional { get; set; }
public DependencyAttribute()
{
}
public DependencyAttribute(int generationOffset)
{
Offset = generationOffset;
}
public override string ToString()
{
string text = base.ToString();
return text.Remove(0, text.IndexOf('+') + 1);
}
}
protected class ComponentDependencyAttribute : DependencyAttribute
{
public ComponentDependencyAttribute(int generationOffset = 0)
: base(generationOffset)
{
}
}
protected class OwnComponentAttribute : ComponentDependencyAttribute
{
public OwnComponentAttribute(int generationOffset = 0)
: base(generationOffset)
{
}
}
protected class ComponentAttribute : ComponentDependencyAttribute
{
public ComponentAttribute(int generationOffset = 0)
: base(generationOffset)
{
}
}
protected class GlobalComponentAttribute : ComponentDependencyAttribute
{
}
protected class ReferenceComponentAttribute : ComponentDependencyAttribute
{
public bool DeepSearch { get; set; }
public ReferenceComponentAttribute(bool deepSearch = false)
{
DeepSearch = deepSearch;
}
}
protected class ChildComponentAttribute : ComponentDependencyAttribute
{
public bool SkipItself { get; set; }
public ChildComponentAttribute(int generationOffset = 0)
: base(generationOffset)
{
}
}
protected class ParentComponentAttribute : ComponentDependencyAttribute
{
public bool SkipItself { get; set; }
public ParentComponentAttribute(int generationOffset = 0)
: base(generationOffset)
{
}
}
protected class SiblingComponentAttribute : ComponentDependencyAttribute
{
public bool SkipItself { get; set; }
public SiblingComponentAttribute(int generationOffset = 0)
: base(generationOffset)
{
}
}
protected class FamilyComponentAttribute : ComponentDependencyAttribute
{
public bool SkipItself { get; set; }
public bool FromRoot { get; set; }
public int Generations { get; set; }
public FamilyComponentAttribute(int generationsBackwards = 1)
{
Generations = generationsBackwards;
}
public FamilyComponentAttribute(bool fromRoot, int generationOffset = 0)
{
Generations = generationOffset;
FromRoot = fromRoot;
}
}
protected class ReferencePointAttribute : PropertyAttribute
{
}
protected class GameObjectDependencyAttribute : DependencyAttribute
{
protected virtual string Named { get; set; }
public string GetName()
{
return Named;
}
public GameObjectDependencyAttribute(int generationOffset = 0)
: base(generationOffset)
{
}
}
protected class ChildAttribute : GameObjectDependencyAttribute
{
public int Index { get; set; }
public ChildAttribute(int childIndex = 0)
{
Index = childIndex;
}
public ChildAttribute(string name)
{
Named = name;
Index = -1;
}
}
protected class ParentAttribute : GameObjectDependencyAttribute
{
public ParentAttribute(int parentIndex = 0)
: base(parentIndex)
{
}
public ParentAttribute(string name)
{
Named = name;
}
}
protected class ReferenceAttribute : GameObjectDependencyAttribute
{
protected override string Named
{
get
{
return base.Of;
}
set
{
base.Of = value;
}
}
public ReferenceAttribute(string name)
{
base.Of = name;
}
}
protected class RootAttribute : GameObjectDependencyAttribute
{
public int FromTop { get; set; }
public RootAttribute(int toSkipFromTop = 0)
{
FromTop = toSkipFromTop;
}
public RootAttribute(string name)
{
Named = name;
}
}
protected class SiblingAttribute : GameObjectDependencyAttribute
{
public int Index { get; set; }
public SiblingAttribute(int siblingIndex)
{
Index = siblingIndex;
}
public SiblingAttribute(string name)
{
Named = name;
Index = -1;
}
}
private class SceneOrDdols
{
private Scene? scene;
public SceneOrDdols(GameObject go)
{
try
{
scene = go.scene;
}
catch
{
scene = null;
}
}
public bool IsScene()
{
return scene.HasValue;
}
public Scene GetScene()
{
return scene.Value;
}
public GameObject[] GetRootGameObjects()
{
if (IsScene())
{
return GetRoots(GetScene()).ToArray();
}
return GetDontDestroyOnLoadObjects().ToArray();
}
public int GetRootCount()
{
if (IsScene())
{
return GetScene().rootCount;
}
return GetDontDestroyOnLoadObjects().Count;
}
public override string ToString()
{
if (IsScene())
{
return scene.Value.name;
}
return "DDOLs Scene";
}
public bool Equals(Scene scene2)
{
if (scene.HasValue)
{
return scene.Value == scene2;
}
return false;
}
}
protected internal class ToSkip : MonoBehaviour
{
}
public static int Verbosity { get; set; }
protected static void Log(string msg, bool quietly)
{
Log(msg, quietly ? 1 : 0);
}
protected static void Log(string msg, int minVerbosity = 0)
{
if (Verbosity >= minVerbosity)
{
Debug.Log(msg);
}
}
protected static void LogWarning(string msg, bool quietly)
{
LogWarning(msg, quietly ? 1 : (-1));
}
protected static void LogWarning(string msg, int minVerbosity = -1)
{
if (Verbosity >= 2)
{
Debug.Log("Warning: " + msg);
}
if (Verbosity >= minVerbosity)
{
Debug.LogWarning(msg);
}
}
public static List<GameObject> GetDontDestroyOnLoadObjects()
{
List<GameObject> list = new List<GameObject>();
for (int i = 0; i < SceneManager.sceneCount; i++)
{
list.AddRange(SceneManager.GetSceneAt(i).GetRootGameObjects());
}
List<GameObject> list2 = new List<GameObject>();
Transform[] array = Resources.FindObjectsOfTypeAll<Transform>();
foreach (Transform transform in array)
{
if (transform.parent == null && transform.hideFlags == HideFlags.None && !list.Contains(transform.gameObject))
{
list2.Add(transform.gameObject);
}
}
list2.Sort((GameObject x, GameObject y) => string.Compare(x.name, y.name));
return list2;
}
private Transform GetOffsetTransform(Transform t, int offset)
{
if (t == null)
{
return null;
}
if (offset > 0)
{
for (int i = 0; i < offset; i++)
{
t = t.parent;
if (t == null)
{
break;
}
}
}
else
{
for (int j = offset; j < 0; j++)
{
if (t.childCount == 0)
{
break;
}
t = t.GetChild(0);
}
}
return t;
}
private object GetReferenceComponent(List<GameObject> references, MethodInfo method)
{
if (references.Count == 0)
{
LogWarning("There are no [ReferencePoint] GameObjects to search in for the [ReferenceComponent] in " + this?.ToString() + ". For automatic search use [Component] instead.");
return null;
}
object obj = null;
foreach (GameObject reference in references)
{
Transform obj2;
try
{
obj2 = reference.transform;
}
catch
{
continue;
}
object[] parameters = new Type[0];
obj = method.Invoke(obj2, parameters);
if (obj != null)
{
break;
}
}
return obj;
}
private Transform FindGameObjectInChildren(Transform parent, string name)
{
for (int i = 0; i < parent.childCount; i++)
{
Transform child = parent.GetChild(i);
if (child.gameObject.name.Equals(name))
{
return child;
}
}
for (int j = 0; j < parent.childCount; j++)
{
Transform child2 = parent.GetChild(j);
Transform transform = FindGameObjectInChildren(child2, name);
if (transform != null)
{
return transform;
}
}
return null;
}
private Transform FindGameObjectIn(Transform parent, string name)
{
if (parent.gameObject.name.Equals(name))
{
return parent;
}
return FindGameObjectInChildren(parent, name);
}
private List<Scene> GetScenes(Transform startPoint)
{
List<Scene> list = new List<Scene>();
SceneOrDdols sceneOrDdols = new SceneOrDdols(startPoint?.gameObject);
if (sceneOrDdols.IsScene())
{
list.Add(sceneOrDdols.GetScene());
}
for (int i = 0; i < SceneManager.sceneCount; i++)
{
Scene sceneAt = SceneManager.GetSceneAt(i);
if (!sceneOrDdols.Equals(sceneAt))
{
list.Add(sceneAt);
}
}
return list;
}
private static List<GameObject> GetRoots(Scene scene)
{
List<GameObject> list = new List<GameObject>(scene.GetRootGameObjects());
list.Sort((GameObject x, GameObject y) => string.Compare(x.name, y.name));
return list;
}
private GameObject FindGameObject(string name, List<Scene> delayedScenes)
{
Transform parent = base.transform;
Transform transform = FindGameObjectIn(parent, name);
if (transform != null)
{
return transform.gameObject;
}
while (parent.parent != null)
{
Transform transform2 = parent;
parent = parent.parent;
if (transform2.gameObject.name.Equals(name))
{
return transform2.gameObject;
}
for (int i = 0; i < parent.childCount; i++)
{
Transform child = parent.GetChild(i);
if (child != transform2 && child.gameObject.name.Equals(name))
{
return child.gameObject;
}
}
for (int j = 0; j < parent.childCount; j++)
{
Transform child2 = parent.GetChild(j);
if (child2 != transform2)
{
transform = FindGameObjectInChildren(parent, name);
if (transform != null)
{
return child2.gameObject;
}
}
}
}
if (parent.name.Equals(name))
{
return parent.gameObject;
}
List<Scene> scenes = GetScenes(parent);
foreach (Scene item in scenes)
{
foreach (GameObject root in GetRoots(item))
{
if (root.name.Equals(name))
{
return root;
}
}
if (!item.isLoaded)
{
delayedScenes.Add(item);
}
}
List<GameObject> dontDestroyOnLoadObjects = GetDontDestroyOnLoadObjects();
foreach (GameObject item2 in dontDestroyOnLoadObjects)
{
if (item2.name.Equals(name))
{
return item2;
}
}
foreach (Scene item3 in scenes)
{
foreach (GameObject root2 in GetRoots(item3))
{
if (root2.transform != parent)
{
transform = FindGameObjectInChildren(root2.transform, name);
if (transform != null)
{
return transform.gameObject;
}
}
}
}
foreach (GameObject item4 in dontDestroyOnLoadObjects)
{
transform = FindGameObjectInChildren(item4.transform, name);
if (transform != null)
{
return transform.gameObject;
}
}
return null;
}
private GameObject FindGameObject(DependencyAttribute a, FieldInfo f, List<GameObject> references, out bool isDelayed)
{
isDelayed = false;
string of = a.Of;
GameObject gameObject = null;
List<Scene> list = new List<Scene>();
if (references.Count != 0)
{
FieldInfo field = GetType().GetField(of, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null && field.GetCustomAttribute(typeof(ReferencePointAttribute)) != null)
{
object value = field.GetValue(this);
try
{
if (value != null)
{
if (value is GameObject result)
{
return result;
}
if (value is Transform { gameObject: var result2 })
{
return result2;
}
}
}
catch
{
Debug.LogError("The " + field?.ToString() + " field in " + this?.ToString() + " is most likely unassigned.");
}
}
else
{
gameObject = FindGameObjectIn(references, of);
if (gameObject == null)
{
gameObject = FindGameObject(a.Of, list);
}
}
}
else
{
gameObject = FindGameObject(a.Of, list);
}
if (gameObject == null)
{
if (list.Count != 0)
{
isDelayed = true;
StartCoroutine(FindGameObjectInScenes(list, a, f, references));
}
else
{
if (!a.Optional)
{
LogWarning("No GameObject named \"" + a.Of + "\" was found for [" + a?.ToString() + "] " + f?.ToString() + " in " + this?.ToString() + ". Creating one...");
return new GameObject(a.Of);
}
Log("No GameObject named \"" + a.Of + "\" was found for [" + a?.ToString() + "] " + f?.ToString() + " in " + this?.ToString() + " but it's optional.", quietly: true);
}
}
return gameObject;
}
private GameObject FindGameObjectIn(IEnumerable<GameObject> list, string name)
{
foreach (GameObject item in list)
{
try
{
if (item.name.Equals(name))
{
return item;
}
}
catch
{
}
}
return null;
}
private IEnumerator InitDelayedSingleton(Type singletonType, FieldInfo f)
{
for (int i = 0; i < SceneManager.sceneCount; i++)
{
Scene scene = SceneManager.GetSceneAt(i);
while (!scene.isLoaded)
{
yield return null;
}
}
object value = singletonType.GetProperty("Instance").GetValue(null);
if (value != null)
{
f.SetValue(this, value);
Log("The [GlobalComponent] " + f?.ToString() + " field in " + this?.ToString() + " has been initialized with a delay. Don't use it in Start() & Awake()!");
}
}
private IEnumerator WaitForScenesToLoad(IEnumerable<Scene> scenes)
{
foreach (Scene scene in scenes)
{
while (!scene.isLoaded)
{
yield return null;
}
}
}
private GameObject FindGameObjectInScenes(IEnumerable<Scene> scenes, string name, bool deepSearch = true)
{
foreach (Scene scene in scenes)
{
foreach (GameObject root in GetRoots(scene))
{
if (root.transform.name.Equals(name))
{
return root;
}
}
}
if (deepSearch)
{
foreach (Scene scene2 in scenes)
{
foreach (GameObject root2 in GetRoots(scene2))
{
Transform transform = FindGameObjectInChildren(root2.transform, name);
if (transform != null)
{
return transform.gameObject;
}
}
}
}
return null;
}
private IEnumerator FindGameObjectInScenes(IEnumerable<Scene> scenes, DependencyAttribute a, FieldInfo f, List<GameObject> references = null)
{
yield return StartCoroutine(WaitForScenesToLoad(scenes));
GameObject gameObject = FindGameObjectInScenes(scenes, a.Of);
if (gameObject == null)
{
if (a.Optional)
{
Log("No GameObject named \"" + a.Of + "\" was found for [" + a?.ToString() + "] " + f?.ToString() + " in " + this?.ToString() + " but it's optional.", quietly: true);
yield break;
}
LogWarning("No GameObject named \"" + a.Of + "\" was found for [" + a?.ToString() + "] " + f?.ToString() + " in " + this?.ToString() + ". Creating one...");
gameObject = new GameObject(a.Of);
}
Log("The [" + a?.ToString() + "(Of = \"" + a.Of + "\")] " + f?.ToString() + " field in " + this?.ToString() + " is initialized with a delay. Don't use it in Start() & Awake()!");
Transform offsetTransform = GetOffsetTransform(gameObject.transform, a.Offset);
if (a is GameObjectDependencyAttribute a2)
{
InitObjectField(a2, f, offsetTransform);
}
else if (a is ComponentDependencyAttribute a3)
{
InitComponentField(a3, GetType(), f, offsetTransform, references);
}
}
private MethodInfo GetTopMethod(Type type)
{
return GetType().GetMethod("GetComponent", new Type[0]).MakeGenericMethod(type);
}
private MethodInfo GetDeepMethod(Type type)
{
return GetType().GetMethod("GetComponentInChildren", new Type[0]).MakeGenericMethod(type);
}
private bool HasToSkip(Transform t)
{
if (t.GetComponent<ToSkip>() == null)
{
return false;
}
return true;
}
private object FindComponentInChildren(Transform parent, MethodInfo method)
{
for (int i = 0; i < parent.childCount; i++)
{
Transform child = parent.GetChild(i);
if (!HasToSkip(child))
{
object[] parameters = new Type[0];
object obj = method.Invoke(child, parameters);
if (obj != null)
{
return obj;
}
}
}
for (int j = 0; j < parent.childCount; j++)
{
Transform child2 = parent.GetChild(j);
if (!HasToSkip(child2))
{
object obj2 = FindComponentInChildren(child2, method);
if (obj2 != null)
{
return obj2;
}
}
}
return null;
}
private object FindComponentIn(Transform parent, MethodInfo method)
{
if (HasToSkip(parent))
{
return null;
}
object[] parameters = new Type[0];
object obj = method.Invoke(parent, parameters);
if (obj != null)
{
return obj;
}
return FindComponentInChildren(parent, method);
}
private IEnumerator FindComponentInScenes(IEnumerable<Scene> scenes, FieldInfo f, bool deepSearch, bool isOptional, GameObject toSkip = null)
{
MethodInfo method = (deepSearch ? GetDeepMethod(f.FieldType) : GetTopMethod(f.FieldType));
if (toSkip != null)
{
toSkip.AddComponent<ToSkip>();
}
object target = null;
foreach (Scene scene in scenes)
{
while (!scene.isLoaded)
{
yield return null;
}
foreach (GameObject root in GetRoots(scene))
{
if (toSkip == root)
{
continue;
}
if (!deepSearch || toSkip == null)
{
Transform obj = root.transform;
object[] parameters = new Type[0];
target = method.Invoke(obj, parameters);
}
else
{
target = FindComponentIn(root.transform, GetTopMethod(f.FieldType));
}
if (target == null)
{
continue;
}
goto end_IL_008d;
}
}
end_IL_008d:
if (toSkip != null)
{
UnityEngine.Object.DestroyImmediate(toSkip.GetComponent<ToSkip>());
}
if (target == null && toSkip != null && deepSearch)
{
target = GetComponentOnlyInChildren(toSkip.transform, method);
}
if (f.GetValue(this) != null && deepSearch)
{
yield break;
}
if (target != null)
{
f.SetValue(this, target);
Log("The " + f?.ToString() + " field in " + this?.ToString() + " has been initialized with a delay. Don't use it in Start() & Awake()!");
}
else if (f.GetValue(this) == null)
{
if (isOptional)
{
Log("Instance of " + f?.ToString() + " not found for " + this?.ToString() + " but it's optional.", quietly: true);
}
else
{
LogWarning("Instance of " + f?.ToString() + " not found for " + this?.ToString() + ". Creating it with a delay... Don't use it in Start() & Awake()!");
CreateComponent(new GlobalComponentAttribute(), f, null, null);
}
}
}
private object FindInRoots(FieldInfo f, bool deepSearch, bool isOptional, GameObject startPoint, out bool isDelayed, bool skip = false)
{
MethodInfo methodInfo = (deepSearch ? GetDeepMethod(f.FieldType) : GetTopMethod(f.FieldType));
Transform parent = null;
int siblingIndex = -1;
if (skip && startPoint != null)
{
parent = startPoint.transform.parent;
siblingIndex = startPoint.transform.GetSiblingIndex();
startPoint.transform.SetParent(null);
}
isDelayed = false;
List<Scene> list = new List<Scene>();
object obj = null;
foreach (Scene scene in GetScenes(startPoint?.transform))
{
foreach (GameObject root in GetRoots(scene))
{
if (!skip || !(startPoint == root))
{
Transform obj2 = root.transform;
object[] parameters = new Type[0];
obj = methodInfo.Invoke(obj2, parameters);
if (obj != null)
{
goto end_IL_00fb;
}
}
}
if (!scene.isLoaded)
{
list.Add(scene);
}
continue;
end_IL_00fb:
break;
}
if (obj == null)
{
foreach (GameObject dontDestroyOnLoadObject in GetDontDestroyOnLoadObjects())
{
if (!skip || !(startPoint == dontDestroyOnLoadObject))
{
Transform obj3 = dontDestroyOnLoadObject.transform;
object[] parameters = new Type[0];
obj = methodInfo.Invoke(obj3, parameters);
if (obj != null)
{
break;
}
}
}
}
if (skip && startPoint != null)
{
startPoint.transform.SetParent(parent);
startPoint.transform.SetSiblingIndex(siblingIndex);
}
if (obj == null)
{
if (list.Count != 0)
{
isDelayed = true;
StartCoroutine(FindComponentInScenes(list, f, deepSearch, isOptional, skip ? startPoint : null));
}
else if (skip && startPoint != null && deepSearch)
{
obj = GetComponentOnlyInChildren(startPoint.transform, methodInfo);
}
}
return obj;
}
private object GetComponentOnlyInChildren(Transform parent, MethodInfo method)
{
for (int i = 0; i < parent.childCount; i++)
{
Transform child = parent.GetChild(i);
object[] parameters = new Type[0];
object obj = method.Invoke(child, parameters);
if (obj != null)
{
return obj;
}
}
return null;
}
private object GetSingletonComponent(FieldInfo f, out bool isDelayed)
{
isDelayed = false;
try
{
Type fieldType = f.FieldType;
Type type = typeof(MonoBehaviourSingleton<>).MakeGenericType(fieldType);
if (fieldType.IsSubclassOf(type))
{
object value = type.GetProperty("Instance").GetValue(null);
if (value == null)
{
StartCoroutine(InitDelayedSingleton(type, f));
isDelayed = true;
}
return value;
}
}
catch
{
return null;
}
return null;
}
private void InitComponentField(ComponentDependencyAttribute a, Type t, FieldInfo f, Transform startPoint, List<GameObject> references)
{
object obj = null;
if (a is ChildComponentAttribute childComponentAttribute)
{
if (startPoint != null)
{
MethodInfo deepMethod = GetDeepMethod(f.FieldType);
if (childComponentAttribute.SkipItself)
{
obj = GetComponentOnlyInChildren(startPoint, deepMethod);
}
else
{
Transform obj2 = startPoint;
object[] parameters = new Type[0];
obj = deepMethod.Invoke(obj2, parameters);
}
}
else
{
obj = FindInRoots(f, deepSearch: true, a.Optional, base.transform.gameObject, out var isDelayed);
if (isDelayed)
{
return;
}
}
}
else if (a is FamilyComponentAttribute familyComponentAttribute)
{
Transform transform = startPoint;
startPoint = ((!familyComponentAttribute.FromRoot) ? GetOffsetTransform(startPoint, familyComponentAttribute.Generations) : GetRoot(startPoint, familyComponentAttribute.Generations));
if (startPoint != null)
{
MethodInfo deepMethod2 = GetDeepMethod(f.FieldType);
if (familyComponentAttribute.SkipItself)
{
Transform parent = transform.parent;
int siblingIndex = transform.GetSiblingIndex();
transform.SetParent(null);
if (startPoint != transform)
{
Transform obj3 = startPoint;
object[] parameters = new Type[0];
obj = deepMethod2.Invoke(obj3, parameters);
}
if (obj == null && startPoint.root != transform)
{
obj = GetComponentOnlyInChildren(transform, deepMethod2);
}
transform.SetParent(parent);
transform.SetSiblingIndex(siblingIndex);
}
else
{
Transform obj4 = startPoint;
object[] parameters = new Type[0];
obj = deepMethod2.Invoke(obj4, parameters);
}
}
else
{
obj = FindInRoots(f, deepSearch: true, a.Optional, transform?.gameObject, out var isDelayed2, familyComponentAttribute.SkipItself);
if (isDelayed2)
{
return;
}
}
}
else if (a is ParentComponentAttribute parentComponentAttribute)
{
if (parentComponentAttribute.SkipItself)
{
startPoint = startPoint?.parent;
}
if (startPoint != null)
{
MethodInfo methodInfo = t.GetMethod("GetComponentInParent", new Type[0]).MakeGenericMethod(f.FieldType);
Transform obj5 = startPoint;
object[] parameters = new Type[0];
obj = methodInfo.Invoke(obj5, parameters);
}
}
else if (a is GlobalComponentAttribute)
{
if (a.Of != null && startPoint != null)
{
MethodInfo topMethod = GetTopMethod(f.FieldType);
Transform obj6 = startPoint;
object[] parameters = new Type[0];
obj = topMethod.Invoke(obj6, parameters);
}
if (obj == null)
{
if (!a.Optional)
{
obj = GetSingletonComponent(f, out var isDelayed3);
if (isDelayed3)
{
return;
}
}
if (obj == null)
{
obj = FindInRoots(f, deepSearch: false, a.Optional, startPoint.gameObject, out var isDelayed4);
if (obj == null)
{
obj = FindInRoots(f, deepSearch: true, a.Optional, startPoint.gameObject, out var isDelayed5);
if (obj == null && (isDelayed4 || isDelayed5))
{
return;
}
}
}
}
}
else if (a is SiblingComponentAttribute siblingComponentAttribute)
{
Transform transform2 = startPoint?.parent;
if (transform2 != null)
{
MethodInfo topMethod2 = GetTopMethod(f.FieldType);
if (siblingComponentAttribute.SkipItself)
{
int siblingIndex2 = startPoint.GetSiblingIndex();
startPoint.SetParent(null);
obj = GetComponentOnlyInChildren(transform2, topMethod2);
startPoint.SetParent(transform2);
startPoint.SetSiblingIndex(siblingIndex2);
}
else
{
obj = GetComponentOnlyInChildren(transform2, topMethod2);
}
}
else
{
obj = FindInRoots(f, deepSearch: false, a.Optional, startPoint?.gameObject, out var isDelayed6, siblingComponentAttribute.SkipItself);
if (isDelayed6)
{
return;
}
}
}
else if (a is OwnComponentAttribute)
{
if (startPoint != null)
{
MethodInfo topMethod3 = GetTopMethod(f.FieldType);
Transform obj7 = startPoint;
object[] parameters = new Type[0];
obj = topMethod3.Invoke(obj7, parameters);
}
}
else if (a is ReferenceComponentAttribute referenceComponentAttribute)
{
MethodInfo methodInfo2 = (referenceComponentAttribute.DeepSearch ? GetDeepMethod(f.FieldType) : GetTopMethod(f.FieldType));
if (a.Of != null)
{
if (startPoint != null)
{
Transform obj8 = startPoint;
object[] parameters = new Type[0];
obj = methodInfo2.Invoke(obj8, parameters);
}
}
else
{
obj = GetReferenceComponent(references, methodInfo2);
}
}
else if (a is ComponentAttribute)
{
if (!a.Optional && a.Of == null)
{
obj = GetSingletonComponent(f, out var isDelayed7);
if (isDelayed7)
{
return;
}
}
MethodInfo topMethod4 = GetTopMethod(f.FieldType);
if (obj == null && a.Of == null && references.Count != 0)
{
obj = GetReferenceComponent(references, topMethod4);
}
if (obj == null && startPoint != null)
{
MethodInfo deepMethod3 = GetDeepMethod(f.FieldType);
Transform obj9 = startPoint;
object[] parameters = new Type[0];
obj = deepMethod3.Invoke(obj9, parameters);
while (obj == null)
{
Transform transform3 = startPoint;
Transform parent2 = startPoint.parent;
if (parent2 == null)
{
break;
}
startPoint = parent2;
parameters = new Type[0];
obj = topMethod4.Invoke(transform3, parameters);
if (obj == null)
{
obj = GetComponentOnlyInChildren(startPoint, topMethod4);
}
if (obj != null)
{
continue;
}
for (int i = 0; i < startPoint.childCount; i++)
{
Transform child = startPoint.GetChild(i);
if (child != transform3)
{
obj = GetComponentOnlyInChildren(child, deepMethod3);
}
if (obj != null)
{
break;
}
}
}
}
if (obj == null)
{
if (startPoint != null)
{
Transform obj10 = startPoint;
object[] parameters = new Type[0];
obj = topMethod4.Invoke(obj10, parameters);
}
if (obj == null)
{
obj = FindInRoots(f, deepSearch: true, a.Optional, startPoint?.gameObject, out var isDelayed8, startPoint != null);
if (isDelayed8)
{
return;
}
}
}
}
if (obj == null)
{
if (a.Optional)
{
Log("Instance of [" + a?.ToString() + "] " + f?.ToString() + " not found for " + this?.ToString() + " but it's optional.", quietly: true);
}
else
{
LogWarning("Instance of [" + a?.ToString() + "] " + f?.ToString() + " not found for " + this?.ToString() + ". Creating one...");
CreateComponent(a, f, startPoint, references);
}
}
else
{
f.SetValue(this, obj);
}
}
private Transform GetChild(Transform parent, int index)
{
if (index < 0 || index >= parent.childCount)
{
return null;
}
return parent.GetChild(index);
}
private Transform GetRoot(Transform startPoint, int offsetFromTop)
{
int num = 0;
Transform transform = startPoint;
while (transform.parent != null)
{
num++;
transform = transform.parent;
}
if (offsetFromTop != 0)
{
transform = startPoint;
num -= Mathf.Abs(offsetFromTop);
transform = GetOffsetTransform(transform, num);
}
return transform;
}
private Transform GetTransformByStartPoint(GameObjectDependencyAttribute a, FieldInfo f, Transform startPoint)
{
if (startPoint == null)
{
return null;
}
Transform transform = null;
if (a is ParentAttribute)
{
transform = startPoint.parent;
}
else if (a is ChildAttribute childAttribute)
{
transform = GetChild(startPoint, childAttribute.Index);
if (transform == null)
{
string msg = "ChildIndex of [" + a?.ToString() + "(" + childAttribute.Index + ")] " + f?.ToString() + " in " + this?.ToString() + " is out of rage of " + startPoint.name + "'s children.";
if (a.Optional)
{
Log(msg, quietly: true);
}
else
{
LogWarning(msg);
}
}
}
else if (a is SiblingAttribute siblingAttribute)
{
Transform parent = startPoint.parent;
if (parent != null)
{
transform = GetChild(parent, siblingAttribute.Index);
if (transform == null)
{
string msg2 = "ChildIndex of [" + a?.ToString() + "(" + siblingAttribute.Index + ")] " + f?.ToString() + " in " + this?.ToString() + " is out of rage of " + parent.name + "'s children.";
if (a.Optional)
{
Log(msg2, quietly: true);
}
else
{
LogWarning(msg2);
}
}
}
else
{
SceneOrDdols sceneOrDdols = new SceneOrDdols(startPoint.gameObject);
GameObject[] rootGameObjects = sceneOrDdols.GetRootGameObjects();
int index = siblingAttribute.Index;
if (index < 0 || index >= rootGameObjects.Length)
{
string msg3 = "ChildIndex of [" + a?.ToString() + "(" + index + ")] " + f?.ToString() + " in " + this?.ToString() + " is out of rage of " + sceneOrDdols?.ToString() + "'s roots.";
if (a.Optional)
{
Log(msg3, quietly: true);
}
else
{
LogWarning(msg3);
}
}
else
{
transform = rootGameObjects[index].transform;
}
}
}
else if (a is ReferenceAttribute)
{
transform = startPoint;
}
else if (a is RootAttribute rootAttribute)
{
transform = GetRoot(startPoint, rootAttribute.FromTop);
}
return transform;
}
private IEnumerator FindGameObjectInRoots(GameObjectDependencyAttribute a, IEnumerable<Scene> scenes, FieldInfo f, bool isOptional, string name, bool deepSearch)
{
yield return StartCoroutine(WaitForScenesToLoad(scenes));
GameObject gameObject = FindGameObjectInScenes(scenes, name, deepSearch);
if (gameObject == null)
{
if (f.GetValue(this) != null)
{
yield break;
}
if (isOptional)
{
Log("No GameObject named \"" + name + "\" was found for [" + a?.ToString() + "] " + f?.ToString() + " in " + this?.ToString() + " but it's optional.", quietly: true);
yield break;
}
LogWarning("No GameObject named \"" + name + "\" was found for [" + a?.ToString() + "] " + f?.ToString() + " in " + this?.ToString() + ". Creating one...");
gameObject = new GameObject(name);
}
if (f.FieldType == typeof(GameObject))
{
f.SetValue(this, gameObject);
}
else
{
f.SetValue(this, gameObject.transform);
}
Log("The [" + a?.ToString() + "(Named = \"" + name + "\")] " + f?.ToString() + " field in " + this?.ToString() + " has been initialized with a delay. Don't use it in Start() & Awake()!");
}
private Transform FindGameObjectInRoots(GameObjectDependencyAttribute a, FieldInfo f, bool isOptional, string name, bool deepSearch, out bool isDelayed)
{
isDelayed = false;
List<Scene> list = new List<Scene>();
foreach (Scene scene in GetScenes(base.transform))
{
foreach (GameObject root in GetRoots(scene))
{
if (deepSearch)
{
Transform transform = FindGameObjectInChildren(root.transform, name);
if (transform != null)
{
return transform;
}
}
else if (root.transform.name.Equals(name))
{
return root.transform;
}
}
if (!scene.isLoaded)
{
list.Add(scene);
}
}
if (list.Count != 0)
{
isDelayed = true;
StartCoroutine(FindGameObjectInRoots(a, list, f, isOptional, name, deepSearch));
}
return null;
}
private Transform GetTransformByName(GameObjectDependencyAttribute a, FieldInfo f, Transform startPoint, out bool isDelayed)
{
isDelayed = false;
string value = a.GetName();
if (a is ParentAttribute)
{
if (startPoint != null)
{
while (startPoint.parent != null)
{
startPoint = startPoint.parent;
if (startPoint.name.Equals(value))
{
return startPoint;
}
}
}
return null;
}
if (a is ChildAttribute)
{
if (startPoint != null)
{
return FindGameObjectInChildren(startPoint, value);
}
return FindGameObjectInRoots(a, f, a.Optional, value, deepSearch: true, out isDelayed);
}
if (a is SiblingAttribute)
{
startPoint = startPoint?.parent;
if (startPoint != null)
{
for (int i = 0; i < startPoint.childCount; i++)
{
Transform child = startPoint.GetChild(i);
if (child.name.Equals(value))
{
return child;
}
}
return null;
}
return FindGameObjectInRoots(a, f, a.Optional, value, deepSearch: false, out isDelayed);
}
if (a is ReferenceAttribute)
{
return startPoint;
}
if (a is RootAttribute rootAttribute)
{
if (startPoint != null)
{
int num = 0;
List<Transform> list = new List<Transform>();
Transform transform = startPoint;
while (transform.parent != null)
{
num++;
transform = transform.parent;
}
transform = startPoint;
num -= Mathf.Abs(rootAttribute.FromTop);
if (num < 0)
{
transform = GetOffsetTransform(startPoint, num);
}
for (int j = 0; j < Mathf.Abs(num); j++)
{
list.Add(transform);
if (transform.parent == null)
{
break;
}
transform = transform.parent;
}
if (num < 0)
{
list.Reverse();
transform = GetOffsetTransform(startPoint, num);
}
if (transform.name.Equals(value))
{
return transform;
}
SiblingAttribute siblingAttribute = new SiblingAttribute(value);
siblingAttribute.Optional = rootAttribute.Optional;
Transform transformByName = GetTransformByName(siblingAttribute, f, transform, out isDelayed);
if (transformByName != null)
{
return transformByName;
}
for (int num2 = list.Count - 1; num2 >= 0; num2--)
{
Transform transform2 = list[num2];
if (transform2.name.Equals(value))
{
return transform2;
}
}
}
else if (rootAttribute.FromTop == 0)
{
return FindGameObjectInRoots(a, f, a.Optional, value, deepSearch: false, out isDelayed);
}
}
return null;
}
private void InitObjectField(GameObjectDependencyAttribute a, FieldInfo f, Transform startPoint)
{
Transform transform;
if (a.GetName() == null)
{
transform = GetTransformByStartPoint(a, f, startPoint);
}
else
{
transform = GetTransformByName(a, f, startPoint, out var isDelayed);
if (isDelayed && !(a is RootAttribute))
{
return;
}
}
if (transform == null)
{
if (a.Optional)
{
Log("Instance of [" + a?.ToString() + "] " + f?.ToString() + " not found for " + this?.ToString() + " but it's optional.", quietly: true);
}
else
{
LogWarning("Instance of [" + a?.ToString() + "] " + f?.ToString() + " not found for " + this?.ToString() + ".");
CreateGameObject(a, f, startPoint);
}
}
else if (f.FieldType == typeof(GameObject))
{
f.SetValue(this, transform.gameObject);
}
else
{
f.SetValue(this, transform);
}
}
private void CreateGameObject(GameObjectDependencyAttribute a, FieldInfo f, Transform startPoint)
{
if (startPoint == null)
{
return;
}
string text = a.GetName() ?? f.Name;
Transform transform = new GameObject(text).transform;
if (a is ParentAttribute)
{
transform.SetParent(startPoint.parent);
startPoint.SetParent(transform);
}
else if (a is ChildAttribute childAttribute)
{
for (int i = startPoint.childCount; i < childAttribute.Index; i++)
{
new GameObject("Child" + (i + 1)).transform.SetParent(startPoint);
}
transform.SetParent(startPoint);
if (childAttribute.Index >= 0)
{
transform.SetSiblingIndex(childAttribute.Index);
}
}
else if (a is SiblingAttribute siblingAttribute)
{
Transform parent = startPoint.parent;
for (int j = parent?.childCount ?? new SceneOrDdols(startPoint.gameObject).GetRootCount(); j < siblingAttribute.Index; j++)
{
Transform obj = new GameObject("Sibling" + (j + 1)).transform;
obj.SetParent(startPoint);
obj.SetParent(parent);
}
transform.SetParent(startPoint);
transform.SetParent(parent);
if (siblingAttribute.Index >= 0)
{
transform.SetSiblingIndex(siblingAttribute.Index);
}
}
else if (a is RootAttribute rootAttribute)
{
if (rootAttribute.FromTop != 0)
{
int num = 0;
Transform transform2 = startPoint;
while (transform2.parent != null)
{
num++;
transform2 = transform2.parent;
}
transform2 = startPoint;
num -= Mathf.Abs(rootAttribute.FromTop);
transform2 = GetOffsetTransform(transform2, num);
transform.SetParent(transform2.parent);
}
else
{
transform.SetParent(startPoint);
transform.SetParent(null);
}
}
if (f.FieldType == typeof(GameObject))
{
f.SetValue(this, transform.gameObject);
}
else
{
f.SetValue(this, transform);
}
Log("New GameObject called " + text + " has been created.", quietly: true);
}
private void CreateComponent(ComponentDependencyAttribute a, FieldInfo f, Transform startPoint, List<GameObject> references)
{
Type fieldType = f.FieldType;
Component value = null;
if (a is ChildComponentAttribute || a is FamilyComponentAttribute || a is SiblingComponentAttribute)
{
if (a is SiblingComponentAttribute)
{
startPoint = startPoint?.parent;
}
GameObject obj = new GameObject(fieldType.Name, fieldType);
value = obj.GetComponent(fieldType);
obj.transform.SetParent(startPoint);
}
else if (a is ParentComponentAttribute || a is GlobalComponentAttribute || a is OwnComponentAttribute || a is ComponentAttribute)
{
value = ((!(startPoint != null)) ? new GameObject(fieldType.Name, fieldType).GetComponent(fieldType) : startPoint.gameObject.AddComponent(fieldType));
}
else if (a is ReferenceComponentAttribute)
{
if (a.Of != null || references.Count == 0)
{
if (startPoint != null)
{
value = startPoint.gameObject.AddComponent(fieldType);
}
else
{
GameObject obj2 = new GameObject(fieldType.Name, fieldType);
value = obj2.GetComponent(fieldType);
obj2.transform.SetParent(base.transform);
obj2.transform.SetParent(null);
}
}
else
{
value = references[Mathf.Min(a.Offset, references.Count - 1)].AddComponent(fieldType);
}
}
f.SetValue(this, value);
Log("New component [" + a?.ToString() + "] " + f?.ToString() + " for " + this?.ToString() + " has been created.", quietly: true);
}
protected void Awake()
{
Type type = GetType();
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
List<GameObject> list = new List<GameObject>();
FieldInfo[] array = fields;
foreach (FieldInfo fieldInfo in array)
{
object[] customAttributes = fieldInfo.GetCustomAttributes(typeof(GameObjectDependencyAttribute), inherit: true);
if (customAttributes.Length > 1)
{
for (int j = 0; j < customAttributes.Length - 1; j++)
{
((GameObjectDependencyAttribute)customAttributes[j]).Optional = true;
}
}
object[] array2 = customAttributes;
for (int k = 0; k < array2.Length; k++)
{
GameObjectDependencyAttribute gameObjectDependencyAttribute = (GameObjectDependencyAttribute)array2[k];
if (fieldInfo.IsPublic && !fieldInfo.IsNotSerialized)
{
LogWarning("You tried to inject a public (serialized) GameObject! (" + fieldInfo?.ToString() + " in " + this?.ToString() + ") It should be private or marked with [NonSerialized], otherwise it may conflict with the Unity serializer and the dependency may not be injected.");
}
if (fieldInfo.GetValue(this) != null)
{
break;
}
if (fieldInfo.FieldType != typeof(GameObject) && fieldInfo.FieldType != typeof(Transform))
{
Debug.LogError(gameObjectDependencyAttribute?.ToString() + " cannot be applied to " + fieldInfo?.ToString() + " in " + this?.ToString() + " as it's not of GameObject/Transform type.");
}
Transform transform = null;
if (gameObjectDependencyAttribute.Of != null)
{
transform = FindGameObject(gameObjectDependencyAttribute, fieldInfo, list, out var _)?.transform;
if (transform == null)
{
continue;
}
}
else
{
transform = base.transform;
}
transform = GetOffsetTransform(transform, gameObjectDependencyAttribute.Offset);
InitObjectField(gameObjectDependencyAttribute, fieldInfo, transform);
}
if (fieldInfo.GetCustomAttribute(typeof(ReferencePointAttribute)) != null)
{
if (fieldInfo.FieldType == typeof(GameObject))
{
list.Add((GameObject)fieldInfo.GetValue(this));
continue;
}
if (fieldInfo.FieldType == typeof(Transform))
{
list.Add(((Transform)fieldInfo.GetValue(this)).gameObject);
continue;
}
Debug.LogError("ReferencePointAttribute cannot be applied to " + fieldInfo?.ToString() + " in " + this?.ToString() + " as it's not of GameObject/Transform type.");
}
}
array = fields;
foreach (FieldInfo fieldInfo2 in array)
{
object[] customAttributes2 = fieldInfo2.GetCustomAttributes(typeof(ComponentDependencyAttribute), inherit: true);
if (customAttributes2.Length > 1)
{
for (int l = 0; l < customAttributes2.Length - 1; l++)
{
((ComponentDependencyAttribute)customAttributes2[l]).Optional = true;
}
}
object[] array2 = customAttributes2;
for (int k = 0; k < array2.Length; k++)
{
ComponentDependencyAttribute componentDependencyAttribute = (ComponentDependencyAttribute)array2[k];
if (fieldInfo2.GetValue(this) != null)
{
break;
}
Transform transform2 = null;
if (componentDependencyAttribute.Of != null)
{
transform2 = FindGameObject(componentDependencyAttribute, fieldInfo2, list, out var _)?.transform;
if (transform2 == null)
{
continue;
}
}
else
{
transform2 = base.transform;
}
transform2 = GetOffsetTransform(transform2, componentDependencyAttribute.Offset);
InitComponentField(componentDependencyAttribute, type, fieldInfo2, transform2, list);
}
}
}
}