/// <summary> /// Makes a mod from a manifest file without an assetbundle for debug. /// </summary> /// <param name="manifestPath">Path to manifest file.</param> /// <param name="modInfo">Content of manifest file.</param> internal Mod(string manifestPath, ModInfo modInfo) : this() { if (!manifestPath.EndsWith(ModManager.MODINFOEXTENSION)) { throw new ArgumentException(string.Format("Path is rejected because it doesn't end with {0}", ModManager.MODINFOEXTENSION), "manifestPath"); } if (modInfo == null) { throw new ArgumentNullException("modInfo"); } IsVirtual = true; ModInfo = modInfo; types = GetTypesInEditor(); FileName = Path.GetFileName(manifestPath.Remove(manifestPath.IndexOf(ModManager.MODINFOEXTENSION))).ToLower(); DirPath = ModManager.Instance.ModDirectory; HasSettings = ModSettings.ModSettingsData.HasSettings(this); }
/// <summary> /// Makes a mod from a manifest file without an assetbundle for debug. /// </summary> /// <param name="manifestPath">Path to manifest file.</param> /// <param name="modInfo">Content of manifest file.</param> internal Mod(string manifestPath, ModInfo modInfo) : this() { if (!manifestPath.EndsWith(ModManager.MODINFOEXTENSION)) { throw new ArgumentException(string.Format("Path is rejected because it doesn't end with {0}", ModManager.MODINFOEXTENSION), "manifestPath"); } if (modInfo == null) { throw new ArgumentNullException("modInfo"); } IsVirtual = true; ModInfo = modInfo; types = modInfo.Files.Where(x => x.EndsWith(".cs")) .Select(x => AssetDatabase.LoadAssetAtPath <MonoScript>(x)) .Where(x => x != null).Select(x => x.GetClass()).Where(x => x != null).ToArray(); FileName = Path.GetFileName(manifestPath.Remove(manifestPath.IndexOf(ModManager.MODINFOEXTENSION))); DirPath = ModManager.Instance.ModDirectory; HasSettings = ModSettings.ModSettingsData.HasSettings(this); }
void OnEnable() { if (EditorPrefs.HasKey("modOutPutPath")) { modOutPutPath = EditorPrefs.GetString("modOutPutPath", GetTempModDirPath()); } else { modOutPutPath = GetTempModDirPath(); } if (EditorPrefs.HasKey("lastModFile")) { currentFilePath = EditorPrefs.GetString("lastModFile"); } modInfo = ReadModInfoFile(currentFilePath); titleStyle.fontSize = 15; fieldStyle.fontSize = 12; minSize = new Vector2(1280, 600); documentationGUIContent = new GUIContent(EditorGUIUtility.IconContent("_Help")); documentationGUIContent.text = " Mod System Documentation"; }
void OnGUI() { EditorGUI.indentLevel++; GUILayoutHelper.Horizontal(() => { if (GUILayout.Button("Create New Mod")) { modInfo = new ModInfo(); modInfo.GUID = System.Guid.NewGuid().ToString(); fileOpen = SaveModFile(); if (modInfo != null) { modInfo.DFUnity_Version = VersionInfo.DaggerfallUnityVersion; } } else if (GUILayout.Button("Open Existing Mod Settings File")) { try { currentFilePath = EditorUtility.OpenFilePanelWithFilters("", ModManager.EditorModsDirectory, new string[] { "JSON", "dfmod.json" }); if (!File.Exists(currentFilePath)) { Debug.Log("Invalid file selection"); currentFilePath = null; fileOpen = false; return; } modInfo = ReadModInfoFile(currentFilePath); Debug.Log(string.Format("opened mod file for: {0}", modInfo.ModTitle)); } catch (Exception ex) { Debug.Log(string.Format("Error while trying to open mod file at: {0} \n {1}", currentFilePath, ex.Message)); currentFilePath = null; fileOpen = false; return; } fileOpen = true; } if (GUILayout.Button(documentationGUIContent)) { Help.BrowseURL("https://www.dfworkshop.net/projects/daggerfall-unity/modding/"); } }); if (!isSupportedEditorVersion) { EditorGUILayout.HelpBox("Unsupported version of Unity Editor: generated mods may not be compatible with release builds!", MessageType.Warning); } if (modInfo == null) { fileOpen = false; modInfo = new ModInfo(); } if (!fileOpen) // if no fileopen, hide rest of UI { EditorGUILayout.HelpBox("Open a manifest file or create a new one to edit or build a mod.", MessageType.Info); return; } GUILayoutHelper.Vertical(() => { EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Current File: "), titleStyle); GUILayout.Space(-1000); EditorGUILayout.LabelField(new GUIContent(currentFilePath), fieldStyle); }); EditorGUILayout.TextArea("", GUI.skin.horizontalSlider); EditorGUI.indentLevel++; GUILayoutHelper.Vertical(() => { EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Mod Title:"), titleStyle); modInfo.ModTitle = EditorGUILayout.TextField(modInfo.ModTitle, GUILayout.MinWidth(1000)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Mod Version:"), titleStyle); modInfo.ModVersion = EditorGUILayout.TextField(modInfo.ModVersion, GUILayout.MinWidth(1000)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Mod Creator:"), titleStyle); modInfo.ModAuthor = EditorGUILayout.TextField(modInfo.ModAuthor, GUILayout.MinWidth(1000)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Contact Info:"), titleStyle); modInfo.ContactInfo = EditorGUILayout.TextField(modInfo.ContactInfo, GUILayout.MinWidth(1000)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("DFUnity Version:"), titleStyle); modInfo.DFUnity_Version = EditorGUILayout.TextField(modInfo.DFUnity_Version, GUILayout.MinWidth(1000)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Mod Description:"), titleStyle); modInfo.ModDescription = EditorGUILayout.TextArea(modInfo.ModDescription, GUILayout.MinWidth(1000)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Mod GUID: "), titleStyle); EditorGUILayout.LabelField(new GUIContent(modInfo.GUID)); if (GUILayout.Button("Generate New GUID")) { modInfo.GUID = System.Guid.NewGuid().ToString(); } GUILayout.Space(300); }); }); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUI.indentLevel--; GUILayoutHelper.Horizontal(() => { if (GUILayout.Button("Add Selected Asset(s)")) { AddSelectedAssetsToMod(); } else if (GUILayout.Button("Remove Selected Asset(s)")) { if (Assets == null || Assets.Count < 1) { return; } else if (assetSelection < 0 || assetSelection > Assets.Count) { return; } else { Assets.RemoveAt(assetSelection); } } else if (GUILayout.Button("Clear ALL Asset(s)")) { if (Assets != null) { Assets = new List <string>(); } } }); }); EditorGUILayout.Space(); ShowFileFoldOut = GUILayoutHelper.Foldout(ShowFileFoldOut, new GUIContent("Files"), () => { scrollPos = GUILayoutHelper.ScrollView(scrollPos, () => { assetSelection = GUILayout.SelectionGrid(assetSelection, modInfo.Files.ToArray(), 1); }); }); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.TextArea("", GUI.skin.horizontalSlider); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical(); GUILayout.Label("\tBuild Targets:\n", titleStyle); for (int i = 0; i < buildTargetsToggles.Length; i++) { buildTargetsToggles[i] = EditorGUILayout.Toggle(buildTargets[i].ToString(), buildTargetsToggles[i], GUILayout.ExpandWidth(false)); } EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(); GUILayout.Label("Compression Type:\n", titleStyle); compressionOption = (ModCompressionOptions)EditorGUILayout.EnumPopup("", compressionOption, GUILayout.MaxWidth(125)); EditorGUILayout.EndVertical(); if (GUILayout.Button("Collect Dependencies", GUILayout.MaxWidth(200)) && ModInfoReady) { foreach (var assetPath in Assets.ToArray()) { var depends = AssetDatabase.GetDependencies(assetPath); foreach (var d in depends) { AddAssetToMod(d); } } } GUILayout.Space(100); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.TextArea("", GUI.skin.horizontalSlider); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField("Build Path:", titleStyle); GUILayout.Space(-1000); EditorGUILayout.LabelField(modOutPutPath, fieldStyle); if (GUILayout.Button("Set", GUILayout.Width(50))) { modOutPutPath = EditorUtility.SaveFolderPanel("Select Destination,", Application.dataPath, ""); Debug.Log("build path: " + modOutPutPath); } }); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.TextArea("", GUI.skin.horizontalSlider); GUILayoutHelper.Horizontal(() => { if (GUILayout.Button("Save Mod Settings to File")) { SaveModFile(File.Exists(currentFilePath)); Debug.Log("got path: " + currentFilePath); } else if (GUILayout.Button("Build Mod")) { SaveModFile(true); BuildMod(); } }); }
void OnGUI() { EditorGUI.indentLevel++; GUILayoutHelper.Horizontal(() => { if (GUILayout.Button("Create New Mod")) { fileOpen = true; if (modInfo != null) { modInfo.DFUnity_Verion = VersionInfo.DaggerfallUnityVersion; } } else if (GUILayout.Button("Open Existing Mod Settings File")) { try { currentFilePath = EditorUtility.OpenFilePanelWithFilters("", Application.dataPath, new string[] { "JSON", "dfmod.json" }); if (!File.Exists(currentFilePath)) { Debug.Log("Invalid file selection"); currentFilePath = null; fileOpen = false; return; } string inPut = File.ReadAllText(currentFilePath); modInfo = (ModInfo)JsonUtility.FromJson(inPut, typeof(ModInfo)); Debug.Log(string.Format("opened mod file for: {0}", modInfo.ModTitle)); } catch (Exception ex) { Debug.Log(string.Format("Error while trying to open mod file at: {0} \n {1}", currentFilePath, ex.Message)); currentFilePath = null; fileOpen = false; return; } fileOpen = true; } }); if (modInfo == null) { fileOpen = false; modInfo = new ModInfo(); } if (!fileOpen) // if no fileopen, hide rest of UI { return; } GUILayoutHelper.Vertical(() => { EditorGUILayout.LabelField(new GUIContent("Mod File Path:" + currentFilePath)); EditorGUI.indentLevel++; GUILayoutHelper.Vertical(() => { EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Mod File Name:")); modInfo.ModFileName = EditorGUILayout.TextField(modInfo.ModFileName.ToLower(), GUILayout.MinWidth(600)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Mod Title:")); modInfo.ModTitle = EditorGUILayout.TextField(modInfo.ModTitle, GUILayout.MinWidth(600)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Mod Version:")); modInfo.ModVersion = EditorGUILayout.TextField(modInfo.ModVersion, GUILayout.MinWidth(600)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Mod Creator:")); modInfo.ModAuthor = EditorGUILayout.TextField(modInfo.ModAuthor, GUILayout.MinWidth(600)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Contact Info:")); modInfo.ContactInfo = EditorGUILayout.TextField(modInfo.ContactInfo, GUILayout.MinWidth(600)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("DFUnity Version:")); modInfo.DFUnity_Verion = EditorGUILayout.TextField(modInfo.DFUnity_Verion, GUILayout.MinWidth(600)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Mod Description:")); modInfo.ModDescription = EditorGUILayout.TextArea(modInfo.ModDescription, GUILayout.MinWidth(600)); }); }); EditorGUILayout.Space(); EditorGUI.indentLevel--; GUILayoutHelper.Horizontal(() => { if (GUILayout.Button("Add Selected Asset(s)")) { AddAssetToMod(); } else if (GUILayout.Button("Remove Selected Asset(s)")) { if (Assets == null || Assets.Count < 1) { return; } else if (assetSelection < 0 || assetSelection > Assets.Count) { return; } else { Assets.RemoveAt(assetSelection); } } else if (GUILayout.Button("Clear ALL Asset(s)")) { if (Assets != null) { Assets = new List <string>(); } } }); }); EditorGUILayout.Space(); ShowFileFoldOut = GUILayoutHelper.Foldout(ShowFileFoldOut, new GUIContent("Files"), () => { scrollPos = GUILayoutHelper.ScrollView(scrollPos, () => { assetSelection = GUILayout.SelectionGrid(assetSelection, modInfo.Files.ToArray(), 1); }); }); EditorGUILayout.Space(); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { if (GUILayout.Button("Save Mod Settings to File")) { SaveModFile(); Debug.Log("got path: " + currentFilePath); } else if (GUILayout.Button("Build Mod")) { SaveModFile(); BuildMod(); } }); }
/// <summary> /// Locates all the .dfmod files in the mod path /// </summary> /// <param name="refresh">Checks for mods to unload.</param> private void FindModsFromDirectory(bool refresh = false) { if (!Directory.Exists(ModDirectory)) { Debug.Log("invalid mod directory: " + ModDirectory); return; } var modFiles = Directory.GetFiles(ModDirectory, "*" + MODEXTENSION, SearchOption.AllDirectories); var modFileNames = new string[modFiles.Length]; var loadedModNames = GetAllModFileNames(); for (int i = 0; i < modFiles.Length; i++) { string modFilePath = modFiles[i]; string DirPath = modFilePath.Substring(0, modFilePath.LastIndexOf(Path.DirectorySeparatorChar)); modFileNames[i] = GetModNameFromPath(modFilePath); if (string.IsNullOrEmpty(modFileNames[i])) { Debug.Log("failed to get name of mod"); continue; } //prevent trying to re-load same asset bundles on refresh if (loadedModNames.Length > 0) { if (loadedModNames.Contains(modFileNames[i])) { continue; } } AssetBundle ab; if (!LoadModAssetBundle(modFilePath, out ab)) { continue; } Mod mod = new Mod(modFileNames[i], DirPath, ab); mod.LoadPriority = i; int index = GetModIndex(mod.Title); if (index < 0) { mods.Add(mod); } } if (refresh) { for (int j = 0; j < loadedModNames.Length; j++) { if (!modFileNames.Contains(loadedModNames[j])) { Debug.Log(string.Format("mod {0} no longer loaded", loadedModNames[j])); UnloadMod(loadedModNames[j], true); } } } #if UNITY_EDITOR if (LoadVirtualMods) { foreach (string manifestPath in Directory.GetFiles(EditorModsDirectory, "*" + MODINFOEXTENSION, SearchOption.AllDirectories)) { ModInfo modInfo = null; if (ModManager._serializer.TryDeserialize(fsJsonParser.Parse(File.ReadAllText(manifestPath)), ref modInfo).Failed) { Debug.LogErrorFormat("Failed to deserialize manifest file {0}", manifestPath); continue; } if (string.IsNullOrWhiteSpace(modInfo.ModTitle)) { Debug.LogError($"Discarded {manifestPath} because it doesn't have a valid title."); continue; } if (mods.Any(x => x.ModInfo.GUID == modInfo.GUID)) { Debug.LogWarningFormat("Ignoring virtual mod {0} because release mod is already loaded.", modInfo.ModTitle); continue; } mods.Add(new Mod(manifestPath, modInfo)); } } #endif }
void OnGUI() { EditorGUI.indentLevel++; GUILayoutHelper.Horizontal(() => { if (GUILayout.Button("Create New Mod")) { modInfo = new ModInfo(); modInfo.GUID = System.Guid.NewGuid().ToString(); fileOpen = SaveModFile(); //currentFilePath = EditorUtility.SaveFilePanel("", GetTempModDirPath(), "", "dfmod.json"); if (modInfo != null) { modInfo.DFUnity_Version = VersionInfo.DaggerfallUnityVersion; } } else if (GUILayout.Button("Open Existing Mod Settings File")) { try { currentFilePath = EditorUtility.OpenFilePanelWithFilters("", GetTempModDirPath(), new string[] { "JSON", "dfmod.json" }); if (!File.Exists(currentFilePath)) { Debug.Log("Invalid file selection"); currentFilePath = null; fileOpen = false; return; } modInfo = ReadModInfoFile(currentFilePath); Debug.Log(string.Format("opened mod file for: {0}", modInfo.ModTitle)); } catch (Exception ex) { Debug.Log(string.Format("Error while trying to open mod file at: {0} \n {1}", currentFilePath, ex.Message)); currentFilePath = null; fileOpen = false; return; } fileOpen = true; } }); if (modInfo == null) { fileOpen = false; modInfo = new ModInfo(); } if (!fileOpen) // if no fileopen, hide rest of UI { return; } GUILayoutHelper.Vertical(() => { EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Current File: " + currentFilePath)); }); EditorGUILayout.TextArea("", GUI.skin.horizontalSlider); EditorGUI.indentLevel++; GUILayoutHelper.Vertical(() => { EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Mod Title:")); modInfo.ModTitle = EditorGUILayout.TextField(modInfo.ModTitle, GUILayout.MinWidth(600)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Mod Version:")); modInfo.ModVersion = EditorGUILayout.TextField(modInfo.ModVersion, GUILayout.MinWidth(600)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Mod Creator:")); modInfo.ModAuthor = EditorGUILayout.TextField(modInfo.ModAuthor, GUILayout.MinWidth(600)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Contact Info:")); modInfo.ContactInfo = EditorGUILayout.TextField(modInfo.ContactInfo, GUILayout.MinWidth(600)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("DFUnity Version:")); modInfo.DFUnity_Version = EditorGUILayout.TextField(modInfo.DFUnity_Version, GUILayout.MinWidth(600)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Mod Description:")); modInfo.ModDescription = EditorGUILayout.TextArea(modInfo.ModDescription, GUILayout.MinWidth(600)); }); EditorGUILayout.Space(); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField(new GUIContent("Mod GUID: ")); EditorGUILayout.LabelField(new GUIContent(modInfo.GUID)); if (GUILayout.Button("Generate New GUID")) { modInfo.GUID = System.Guid.NewGuid().ToString(); } //modInfo.ModDescription = EditorGUILayout.TextArea(modInfo.ModDescription, GUILayout.MinWidth(600)); }); }); EditorGUILayout.Space(); EditorGUI.indentLevel--; GUILayoutHelper.Horizontal(() => { if (GUILayout.Button("Add Selected Asset(s)")) { AddSelectedAssetsToMod(); } else if (GUILayout.Button("Remove Selected Asset(s)")) { if (Assets == null || Assets.Count < 1) { return; } else if (assetSelection < 0 || assetSelection > Assets.Count) { return; } else { Assets.RemoveAt(assetSelection); } } else if (GUILayout.Button("Clear ALL Asset(s)")) { if (Assets != null) { Assets = new List <string>(); } } }); }); EditorGUILayout.Space(); ShowFileFoldOut = GUILayoutHelper.Foldout(ShowFileFoldOut, new GUIContent("Files"), () => { scrollPos = GUILayoutHelper.ScrollView(scrollPos, () => { assetSelection = GUILayout.SelectionGrid(assetSelection, modInfo.Files.ToArray(), 1); }); }); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.TextArea("", GUI.skin.horizontalSlider); GUILayout.Label("Build Targets"); GUILayoutHelper.Horizontal(() => { for (int i = 0; i < buildTargetsToggles.Length; i++) { buildTargetsToggles[i] = EditorGUILayout.Toggle(buildTargets[i].ToString(), buildTargetsToggles[i], GUILayout.ExpandWidth(true)); } }); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.TextArea("", GUI.skin.horizontalSlider); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField("Build Path: " + modOutPutPath); if (GUILayout.Button("Set", GUILayout.Width(50))) { modOutPutPath = EditorUtility.SaveFolderPanel("Select Destination,", Application.dataPath, ""); Debug.Log("build path: " + modOutPutPath); } }); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.TextArea("", GUI.skin.horizontalSlider); GUILayoutHelper.Horizontal(() => { if (GUILayout.Button("Save Mod Settings to File")) { SaveModFile(File.Exists(currentFilePath)); Debug.Log("got path: " + currentFilePath); } else if (GUILayout.Button("Build Mod")) { SaveModFile(true); BuildMod(); } }); }