using FishNet.Managing.Logging; using FishNet.Serializing.Helping; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; namespace FishNet.Managing.Scened { /// /// Extensions for SceneLookupData. /// internal static class SceneLookupDataExtensions { /// /// Returns Names from SceneLookupData. /// /// /// public static string[] GetNames(this SceneLookupData[] datas) { string[] names = new string[datas.Length]; for (int i = 0; i < datas.Length; i++) names[i] = datas[i].Name; return names; } } /// /// Data container for looking up, loading, or unloading a scene. /// public class SceneLookupData { /// /// Handle of the scene. If value is 0, then handle is not used. /// public int Handle; /// /// Name of the scene. /// public string Name = string.Empty; /// /// Returns the scene name without a directory path should one exist. /// public string NameOnly => System.IO.Path.GetFileNameWithoutExtension(Name); /// /// Returns if this data is valid for use. /// Being valid does not mean that the scene exist, rather that there is enough data to try and lookup a scene. /// public bool IsValid => (Name != string.Empty || Handle != 0); #region Const /// /// String to display when scene data is invalid. /// private const string INVALID_SCENE = "One or more scene information entries contain invalid data and have been skipped."; #endregion /// /// /// public SceneLookupData() { } /// /// /// /// Scene to generate from. public SceneLookupData(Scene scene) { Handle = scene.handle; Name = scene.name; } /// /// /// /// Scene name to generate from. public SceneLookupData(string name) { Name = name; } /// /// /// /// Scene handle to generate from. public SceneLookupData(int handle) { Handle = handle; } /// /// /// /// Scene handle to generate from. /// Name to generate from if handle is 0. public SceneLookupData(int handle, string name) { Handle = handle; Name = name; } #region Comparers. public static bool operator ==(SceneLookupData sldA, SceneLookupData sldB) { //One is null while the other is not. if ((sldA is null) != (sldB is null)) return false; /*If here both are either null or have value. */ if (!(sldA is null)) return sldA.Equals(sldB); else if (!(sldB is null)) return sldB.Equals(sldA); //Fall through indicates both are null. return true; } public static bool operator !=(SceneLookupData sldA, SceneLookupData sldB) { //One is null while the other is not. if ((sldA is null) != (sldB is null)) return true; /*If here both are either null or have value. */ if (!(sldA is null)) return !sldA.Equals(sldB); else if (!(sldB is null)) return !sldB.Equals(sldA); //Fall through indicates both are null. return true; } public bool Equals(SceneLookupData sld) { //Comparing instanced against null. if (sld is null) return false; //True if both handles are empty. bool bothHandlesEmpty = ( (this.Handle == 0) && (sld.Handle == 0) ); //If both have handles and they match. if (!bothHandlesEmpty && sld.Handle == this.Handle) return true; //If neither have handles and name matches. else if (bothHandlesEmpty && sld.Name == this.Name) return true; //Fall through. return false; } public override int GetHashCode() { int hashCode = 2053068273; hashCode = hashCode * -1521134295 + Handle.GetHashCode(); hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(Name); return hashCode; } public override bool Equals(object obj) { return base.Equals(obj); } public override string ToString() { return base.ToString(); } #endregion #region CreateData. /// /// Returns a new SceneLookupData. /// /// Scene to create from. /// public static SceneLookupData CreateData(Scene scene) => new SceneLookupData(scene); /// /// Returns a new SceneLookupData. /// /// Scene name to create from. /// public static SceneLookupData CreateData(string name) => new SceneLookupData(name); /// /// Returns a new SceneLookupData. /// /// Scene handle to create from. /// public static SceneLookupData CreateData(int handle) => new SceneLookupData(handle); /// /// Returns a SceneLookupData collection. /// /// Scenes to create from. /// public static SceneLookupData[] CreateData(List scenes) => CreateData(scenes.ToArray()); /// /// Returns a SceneLookupData collection. /// /// Scene names to create from. /// public static SceneLookupData[] CreateData(List names) => CreateData(names.ToArray()); /// /// Returns a SceneLookupData collection. /// /// Scene handles to create from. /// public static SceneLookupData[] CreateData(List handles) => CreateData(handles.ToArray()); /// /// Returns a SceneLookupData collection. /// /// Scenes to create from. /// public static SceneLookupData[] CreateData(Scene[] scenes) { bool invalidFound = false; List result = new List(); foreach (Scene item in scenes) { if (!item.IsValid()) { invalidFound = true; continue; } result.Add(CreateData(item)); } if (invalidFound) NetworkManager.StaticLogWarning(INVALID_SCENE); return result.ToArray(); } /// /// Returns a SceneLookupData collection. /// /// Scene names to create from. /// public static SceneLookupData[] CreateData(string[] names) { bool invalidFound = false; List result = new List(); foreach (string item in names) { if (string.IsNullOrEmpty(item)) { invalidFound = true; continue; } string nameOnly = System.IO.Path.GetFileNameWithoutExtension(item); result.Add(CreateData(nameOnly)); } if (invalidFound) NetworkManager.StaticLogWarning(INVALID_SCENE); return result.ToArray(); } /// /// Returns a SceneLookupData collection. /// /// Scene handles to create from. /// public static SceneLookupData[] CreateData(int[] handles) { bool invalidFound = false; List result = new List(); foreach (int item in handles) { if (item == 0) { invalidFound = true; continue; } result.Add(CreateData(item)); } if (invalidFound) NetworkManager.StaticLogWarning(INVALID_SCENE); return result.ToArray(); } #endregion /// /// Returns the first scene found using Handle or Name, preferring Handle. /// /// /// True if scene was found by handle. Handle is always checked first. public Scene GetScene(out bool foundByHandle) { foundByHandle = false; if (Handle == 0 && string.IsNullOrEmpty(Name)) { NetworkManager.StaticLogWarning("Scene handle and name is unset; scene cannot be returned."); return default; } Scene result = default; //Lookup my handle. if (Handle != 0) { result = SceneManager.GetScene(Handle); if (result.handle != 0) foundByHandle = true; } //If couldnt find handle try by string. if (!foundByHandle) result = SceneManager.GetScene(NameOnly); return result; } } }