#if UNITY_EDITOR
using FishNet.Utility.Constant;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace FishNet.Editing
{
public static class Finding
{
#region Private.
///
/// Path where the FishNet.Runtime assembly is.
///
[System.NonSerialized]
private static string _fishNetRuntimePath = string.Empty;
///
/// Path where the FishNet.Generated assembly is.
///
private static string _fishNetGeneratedPath = string.Empty;
#endregion
///
/// Sets FishNet assembly paths.
///
///
private static void SetPaths(bool error)
{
if (_fishNetGeneratedPath != string.Empty && _fishNetRuntimePath != string.Empty)
return;
string[] guids = AssetDatabase.FindAssets("t:asmdef", new string[] { "Assets" });
string[] objectPaths = new string[guids.Length];
for (int i = 0; i < guids.Length; i++)
objectPaths[i] = AssetDatabase.GUIDToAssetPath(guids[i]);
string runtimeName = (UtilityConstants.RUNTIME_ASSEMBLY_NAME + ".asmdef").ToLower();
string generatedName = (UtilityConstants.GENERATED_ASSEMBLY_NAME + ".asmdef").ToLower();
/* Find all network managers which use Single prefab linking
* as well all network object prefabs. */
foreach (string item in objectPaths)
{
//Found directory to create object in.
if (item.ToLower().Contains(runtimeName))
_fishNetRuntimePath = System.IO.Path.GetDirectoryName(item);
else if (item.ToLower().Contains(generatedName))
_fishNetGeneratedPath = System.IO.Path.GetDirectoryName(item);
if (_fishNetGeneratedPath != string.Empty && _fishNetRuntimePath != string.Empty)
return;
}
}
///
/// Gets path for where the FishNet.Runtime assembly is.
///
///
public static string GetFishNetRuntimePath(bool error)
{
SetPaths(error);
return _fishNetRuntimePath;
}
///
/// Gets path for where the FishNet.Generated assembly is.
///
///
///
public static string GetFishNetGeneratedPath(bool error)
{
SetPaths(error);
return _fishNetGeneratedPath;
}
///
/// Gets all GameObjects in Assets and optionally scenes.
///
///
///
public static List GetGameObjects(bool userAssemblies, bool fishNetAssembly, bool includeScenes, string[] ignoredPaths = null)
{
List results = new List();
string[] guids;
string[] objectPaths;
guids = AssetDatabase.FindAssets("t:GameObject", null);
objectPaths = new string[guids.Length];
for (int i = 0; i < guids.Length; i++)
objectPaths[i] = AssetDatabase.GUIDToAssetPath(guids[i]);
foreach (string item in objectPaths)
{
bool inFishNet = item.Contains(_fishNetRuntimePath);
if (inFishNet && !fishNetAssembly)
continue;
if (!inFishNet && !userAssemblies)
continue;
if (ignoredPaths != null)
{
bool ignore = false;
foreach (string path in ignoredPaths)
{
if (item.Contains(path))
{
ignore = true;
break;
}
}
if (ignore)
continue;
}
GameObject go = (GameObject)AssetDatabase.LoadAssetAtPath(item, typeof(GameObject));
results.Add(go);
}
if (includeScenes)
results.AddRange(GetSceneGameObjects());
return results;
}
///
/// Gets all GameObjects in all open scenes.
///
///
private static List GetSceneGameObjects()
{
List results = new List();
for (int i = 0; i < SceneManager.sceneCount; i++)
results.AddRange(GetSceneGameObjects(SceneManager.GetSceneAt(i)));
return results;
}
///
/// Gets all GameObjects in a scene.
///
private static List GetSceneGameObjects(Scene s)
{
List results = new List();
List buffer = new List();
//Iterate all root objects for the scene.
GameObject[] gos = s.GetRootGameObjects();
for (int i = 0; i < gos.Length; i++)
{
/* Get GameObjects within children of each
* root object then add them to the cache. */
gos[i].GetComponentsInChildren(true, buffer);
foreach (Transform t in buffer)
results.Add(t.gameObject);
}
return results;
}
///
/// Gets created ScriptableObjects of T.
///
///
///
public static List GetScriptableObjects(bool fishNetAssembly, bool breakOnFirst = false)
{
System.Type tType = typeof(T);
List results = new List();
string[] guids = AssetDatabase.FindAssets("t:ScriptableObject", new string[] { "Assets" });
string[] objectPaths = new string[guids.Length];
for (int i = 0; i < guids.Length; i++)
objectPaths[i] = AssetDatabase.GUIDToAssetPath(guids[i]);
/* This might be faster than using directory comparers.
* Don't really care since this occurs only at edit. */
List fishNetPaths = new List();
fishNetPaths.Add(_fishNetGeneratedPath.Replace(@"/", @"\"));
fishNetPaths.Add(_fishNetGeneratedPath.Replace(@"\", @"/"));
fishNetPaths.Add(_fishNetRuntimePath.Replace(@"/", @"\"));
fishNetPaths.Add(_fishNetRuntimePath.Replace(@"\", @"/"));
/* Find all network managers which use Single prefab linking
* as well all network object prefabs. */
foreach (string item in objectPaths)
{
//This will skip hidden unity types.
if (!item.EndsWith(".asset"))
continue;
if (fishNetAssembly)
{
bool found = false;
foreach (string path in fishNetPaths)
{
if (item.Contains(path))
{
found = true;
break;
}
}
if (!found)
continue;
}
UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath(item, tType);
if (obj != null && tType != null && obj.GetType() == tType)
{
results.Add(obj);
if (breakOnFirst)
return results;
}
}
return results;
}
}
}
#endif