mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-14 15:46:36 +08:00
Project refactor, namespace cleanup, splitting UI/functionality.
This commit is contained in:
227
src/Core/Search/SearchProvider.cs
Normal file
227
src/Core/Search/SearchProvider.cs
Normal file
@ -0,0 +1,227 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityExplorer.Core;
|
||||
using UnityExplorer.Core.Runtime;
|
||||
using UnityExplorer.UI.Main;
|
||||
|
||||
namespace UnityExplorer.Search
|
||||
{
|
||||
public static class SearchProvider
|
||||
{
|
||||
internal static object[] StaticClassSearch(string input)
|
||||
{
|
||||
var list = new List<Type>();
|
||||
|
||||
var nameFilter = "";
|
||||
if (!string.IsNullOrEmpty(input))
|
||||
nameFilter = input.ToLower();
|
||||
|
||||
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
foreach (var type in asm.TryGetTypes().Where(it => it.IsSealed && it.IsAbstract))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(nameFilter) && !type.FullName.ToLower().Contains(nameFilter))
|
||||
continue;
|
||||
|
||||
list.Add(type);
|
||||
}
|
||||
}
|
||||
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
internal static string[] s_instanceNames = new string[]
|
||||
{
|
||||
"m_instance",
|
||||
"m_Instance",
|
||||
"s_instance",
|
||||
"s_Instance",
|
||||
"_instance",
|
||||
"_Instance",
|
||||
"instance",
|
||||
"Instance",
|
||||
"<Instance>k__BackingField",
|
||||
"<instance>k__BackingField",
|
||||
};
|
||||
|
||||
internal static object[] SingletonSearch(string input)
|
||||
{
|
||||
var instances = new List<object>();
|
||||
|
||||
var nameFilter = "";
|
||||
if (!string.IsNullOrEmpty(input))
|
||||
nameFilter = input.ToLower();
|
||||
|
||||
var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
|
||||
|
||||
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
// Search all non-static, non-enum classes.
|
||||
foreach (var type in asm.TryGetTypes().Where(it => !(it.IsSealed && it.IsAbstract) && !it.IsEnum))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(nameFilter) && !type.FullName.ToLower().Contains(nameFilter))
|
||||
continue;
|
||||
#if CPP
|
||||
// Only look for Properties in IL2CPP, not for Mono.
|
||||
PropertyInfo pi;
|
||||
foreach (var name in s_instanceNames)
|
||||
{
|
||||
pi = type.GetProperty(name, flags);
|
||||
if (pi != null)
|
||||
{
|
||||
var instance = pi.GetValue(null, null);
|
||||
if (instance != null)
|
||||
{
|
||||
instances.Add(instance);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Look for a typical Instance backing field.
|
||||
FieldInfo fi;
|
||||
foreach (var name in s_instanceNames)
|
||||
{
|
||||
fi = type.GetField(name, flags);
|
||||
if (fi != null)
|
||||
{
|
||||
var instance = fi.GetValue(null);
|
||||
if (instance != null)
|
||||
{
|
||||
instances.Add(instance);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
return instances.ToArray();
|
||||
}
|
||||
|
||||
internal static object[] UnityObjectSearch(string input, string customTypeInput, SearchContext context,
|
||||
ChildFilter childFilter, SceneFilter sceneFilter)
|
||||
{
|
||||
Type searchType = null;
|
||||
switch (context)
|
||||
{
|
||||
case SearchContext.GameObject:
|
||||
searchType = typeof(GameObject); break;
|
||||
|
||||
case SearchContext.Component:
|
||||
searchType = typeof(Component); break;
|
||||
|
||||
case SearchContext.Custom:
|
||||
if (string.IsNullOrEmpty(customTypeInput))
|
||||
{
|
||||
ExplorerCore.LogWarning("Custom Type input must not be empty!");
|
||||
return null;
|
||||
}
|
||||
if (ReflectionUtility.GetTypeByName(customTypeInput) is Type customType)
|
||||
if (typeof(UnityEngine.Object).IsAssignableFrom(customType))
|
||||
searchType = customType;
|
||||
else
|
||||
ExplorerCore.LogWarning($"Custom type '{customType.FullName}' is not assignable from UnityEngine.Object!");
|
||||
else
|
||||
ExplorerCore.LogWarning($"Could not find a type by the name '{customTypeInput}'!");
|
||||
break;
|
||||
|
||||
default:
|
||||
searchType = typeof(UnityEngine.Object); break;
|
||||
}
|
||||
|
||||
if (searchType == null)
|
||||
return null;
|
||||
|
||||
var allObjects = RuntimeProvider.Instance.FindObjectsOfTypeAll(searchType);
|
||||
var results = new List<object>();
|
||||
|
||||
// perform filter comparers
|
||||
|
||||
string nameFilter = null;
|
||||
if (!string.IsNullOrEmpty(input))
|
||||
nameFilter = input.ToLower();
|
||||
|
||||
bool canGetGameObject = (sceneFilter != SceneFilter.Any || childFilter != ChildFilter.Any)
|
||||
&& (context == SearchContext.GameObject || typeof(Component).IsAssignableFrom(searchType));
|
||||
|
||||
string sceneFilterString = null;
|
||||
if (!canGetGameObject)
|
||||
{
|
||||
if (context != SearchContext.UnityObject && (sceneFilter != SceneFilter.Any || childFilter != ChildFilter.Any))
|
||||
ExplorerCore.LogWarning($"Type '{searchType}' cannot have Scene or Child filters applied to it");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sceneFilter == SceneFilter.DontDestroyOnLoad)
|
||||
sceneFilterString = "DontDestroyOnLoad";
|
||||
else if (sceneFilter == SceneFilter.Explicit)
|
||||
sceneFilterString = SearchPage.Instance.m_sceneDropdown.options[SearchPage.Instance.m_sceneDropdown.value].text;
|
||||
}
|
||||
|
||||
foreach (var obj in allObjects)
|
||||
{
|
||||
// name check
|
||||
if (!string.IsNullOrEmpty(nameFilter) && !obj.name.ToLower().Contains(nameFilter))
|
||||
continue;
|
||||
|
||||
if (canGetGameObject)
|
||||
{
|
||||
#if MONO
|
||||
var go = context == SearchContext.GameObject
|
||||
? obj as GameObject
|
||||
: (obj as Component).gameObject;
|
||||
#else
|
||||
var go = context == SearchContext.GameObject
|
||||
? obj.TryCast<GameObject>()
|
||||
: obj.TryCast<Component>().gameObject;
|
||||
#endif
|
||||
|
||||
// scene check
|
||||
if (sceneFilter != SceneFilter.Any)
|
||||
{
|
||||
if (!go)
|
||||
continue;
|
||||
|
||||
switch (context)
|
||||
{
|
||||
case SearchContext.GameObject:
|
||||
if (go.scene.name != sceneFilterString)
|
||||
continue;
|
||||
break;
|
||||
case SearchContext.Custom:
|
||||
case SearchContext.Component:
|
||||
if (go.scene.name != sceneFilterString)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (childFilter != ChildFilter.Any)
|
||||
{
|
||||
if (!go)
|
||||
continue;
|
||||
|
||||
// root object check (no parent)
|
||||
if (childFilter == ChildFilter.HasParent && !go.transform.parent)
|
||||
continue;
|
||||
else if (childFilter == ChildFilter.RootObject && go.transform.parent)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
results.Add(obj);
|
||||
}
|
||||
|
||||
return results.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user