{"TotalCount":8,"Files":[{"Ident":"coomzy.projectsettings","Path":"Code/ProjectSetting.cs","FileName":"ProjectSetting.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72213,"Code":"using System;\r\nusing Sandbox;\r\nusing System.Collections.Generic;\r\n\r\npublic abstract partial class ProjectSetting\u003CT\u003E : ProjectSettingNonGenericBase, IHotloadManaged where T : ProjectSetting\u003CT\u003E\r\n{\r\n\tpublic static string fileName =\u003E $@\u0022{typeof(T).ToSimpleString(false)}\u0022;\r\n\tpublic static string filePath =\u003E $@\u0022{filePathWithoutExtension}.{fileExtension}\u0022;\r\n\tpublic static string filePathWithoutExtension =\u003E $@\u0022ProjectSettings\\{fileName}\u0022;\r\n\tpublic static string fullFilePath =\u003E $@\u0022{Project.Current.GetAssetsPath()}\\{filePath}\u0022;\r\n\tpublic static string fullFilePathWithoutExtension =\u003E $@\u0022{Project.Current.GetAssetsPath()}\\{filePathWithoutExtension}\u0022;\r\n\r\n\tpublic static string fileExtension\r\n\t{\r\n\t\tget\r\n\t\t{\r\n\t\t\tvar gameResourceAttribute = (GameResourceAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(GameResourceAttribute));\r\n\t\t\tif (gameResourceAttribute == null)\r\n\t\t\t{\r\n\t\t\t\tLog.Error($\u0022Type \u0027{typeof(T)}\u0027 does not have the required GameResourceAttribute on it!\u0022);\r\n\t\t\t\treturn \u0022\u0022;\r\n\t\t\t}\r\n\r\n\t\t\treturn gameResourceAttribute.Extension;\r\n\t\t}\r\n\t}\r\n\r\n#pragma warning disable SB3000 // Hotloading not supported\r\n\tstatic T _instance;\r\n#pragma warning restore SB3000 // Hotloading not supported\r\n\tpublic static T instance\r\n\t{\r\n\t\tget\r\n\t\t{\r\n\t\t\tif (_instance != null)\r\n\t\t\t{\r\n\t\t\t\treturn _instance;\r\n\t\t\t}\r\n\r\n\t\t\tType type = typeof(T);\r\n\r\n\t\t\tif (ResourceLibrary.TryGet(filePath, out T inst))\r\n\t\t\t{\r\n\t\t\t\t_instance = inst;\r\n\t\t\t\t_instance.Load();\r\n\t\t\t\treturn _instance;\r\n\t\t\t}\r\n\r\n\t\t\tT newInst = Activator.CreateInstance\u003CT\u003E();\r\n\t\t\tnewInst.Load();\r\n\t\t\t_instance = newInst;\r\n\r\n\t\t\tif (Game.IsEditor)\r\n\t\t\t{\r\n\t\t\t\tLog.Error($\u0022ProjectSetting \u0027{type.ToSimpleString(false)}\u0027 need a file in /ProjectSettings/\u0022);\r\n\t\t\t\treturn newInst;\r\n\t\t\t}\r\n\r\n\t\t\treturn newInst;\r\n\t\t}\r\n\t}\r\n\r\n\tvoid Load()\r\n\t{\r\n\t\tOnLoad();\r\n\t}\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// This currently only gets called once in editor\r\n\t/// \u003C/summary\u003E\r\n\tprotected virtual void OnLoad(){}\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// This clears the instance, you probably don\u0027t want to do this unless you\u0027re doing editor code\r\n\t/// \u003C/summary\u003E\r\n\tpublic void Clear()\r\n\t{\r\n\t\t_instance = null;\r\n\t}\r\n}\r\n\r\n/// \u003Csummary\u003E\r\n/// Generic workaround for ProjectSetting\u0026lt;\u0026gt;, use that not this!\r\n/// \u003C/summary\u003E\r\npublic abstract class ProjectSettingNonGenericBase : GameResource\r\n{\r\n\tpublic static Dictionary\u003CType, ProjectSettingNonGenericBase\u003E typeToInst { get; private set; } = new Dictionary\u003CType, ProjectSettingNonGenericBase\u003E();\r\n}"},{"Ident":"coomzy.projectsettings","Path":"__gen_RazorNamespace.cs","FileName":"__gen_RazorNamespace.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72213,"Code":"global using Microsoft.AspNetCore.Components; \nglobal using Microsoft.AspNetCore.Components.Rendering;\n"},{"Ident":"coomzy.projectsettings","Path":"ProjectSetting.cs","FileName":"ProjectSetting.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72213,"Code":"using System;\r\nusing Sandbox;\r\nusing System.Collections.Generic;\r\n\r\npublic abstract partial class ProjectSetting\u003CT\u003E : ProjectSettingNonGenericBase, IHotloadManaged where T : ProjectSetting\u003CT\u003E\r\n{\r\n\tpublic static string fileName =\u003E $@\u0022{typeof(T).ToSimpleString(false)}\u0022;\r\n\tpublic static string filePath =\u003E $@\u0022{filePathWithoutExtension}.{fileExtension}\u0022;\r\n\tpublic static string filePathWithoutExtension =\u003E $@\u0022ProjectSettings\\{fileName}\u0022;\r\n\tpublic static string fullFilePath =\u003E $@\u0022{Project.Current.GetAssetsPath()}\\{filePath}\u0022;\r\n\tpublic static string fullFilePathWithoutExtension =\u003E $@\u0022{Project.Current.GetAssetsPath()}\\{filePathWithoutExtension}\u0022;\r\n\r\n\tpublic static string fileExtension\r\n\t{\r\n\t\tget\r\n\t\t{\r\n\t\t\tvar gameResourceAttribute = (GameResourceAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(GameResourceAttribute));\r\n\t\t\tif (gameResourceAttribute == null)\r\n\t\t\t{\r\n\t\t\t\tLog.Error($\u0022Type \u0027{typeof(T)}\u0027 does not have the required GameResourceAttribute on it!\u0022);\r\n\t\t\t\treturn \u0022\u0022;\r\n\t\t\t}\r\n\r\n\t\t\treturn gameResourceAttribute.Extension;\r\n\t\t}\r\n\t}\r\n\r\n#pragma warning disable SB3000 // Hotloading not supported\r\n\tstatic T _instance;\r\n#pragma warning restore SB3000 // Hotloading not supported\r\n\tpublic static T instance\r\n\t{\r\n\t\tget\r\n\t\t{\r\n\t\t\tif (_instance != null)\r\n\t\t\t{\r\n\t\t\t\treturn _instance;\r\n\t\t\t}\r\n\r\n\t\t\tType type = typeof(T);\r\n\r\n\t\t\tif (ResourceLibrary.TryGet(filePath, out T inst))\r\n\t\t\t{\r\n\t\t\t\t_instance = inst;\r\n\t\t\t\t_instance.Load();\r\n\t\t\t\treturn _instance;\r\n\t\t\t}\r\n\r\n\t\t\tT newInst = Activator.CreateInstance\u003CT\u003E();\r\n\t\t\tnewInst.Load();\r\n\t\t\t_instance = newInst;\r\n\r\n\t\t\tif (Game.IsEditor)\r\n\t\t\t{\r\n\t\t\t\tLog.Error($\u0022ProjectSetting \u0027{type.ToSimpleString(false)}\u0027 need a file in /ProjectSettings/\u0022);\r\n\t\t\t\treturn newInst;\r\n\t\t\t}\r\n\r\n\t\t\treturn newInst;\r\n\t\t}\r\n\t}\r\n\r\n\tvoid Load()\r\n\t{\r\n\t\tOnLoad();\r\n\t}\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// This currently only gets called once in editor\r\n\t/// \u003C/summary\u003E\r\n\tprotected virtual void OnLoad(){}\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// This clears the instance, you probably don\u0027t want to do this unless you\u0027re doing editor code\r\n\t/// \u003C/summary\u003E\r\n\tpublic void Clear()\r\n\t{\r\n\t\t_instance = null;\r\n\t}\r\n}\r\n\r\n/// \u003Csummary\u003E\r\n/// Generic workaround for ProjectSetting\u0026lt;\u0026gt;, use that not this!\r\n/// \u003C/summary\u003E\r\npublic abstract class ProjectSettingNonGenericBase : GameResource\r\n{\r\n\tpublic static Dictionary\u003CType, ProjectSettingNonGenericBase\u003E typeToInst { get; private set; } = new Dictionary\u003CType, ProjectSettingNonGenericBase\u003E();\r\n}"},{"Ident":"coomzy.projectsettings","Path":"Editor/ProjectSettingsDock.cs","FileName":"ProjectSettingsDock.cs","PackageType":"library","CodeKind":"Editor","AssetVersionId":72213,"Code":"using System;\r\nusing Editor;\r\nusing Sandbox;\r\nusing System.Reflection;\r\nusing Sandbox.Internal;\r\nusing static Editor.EditorEvent;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing static Editor.Label;\r\n\r\n[Dock(\u0022Editor\u0022, \u0022Project Settings\u0022, \u0022manage_search\u0022)]\r\npublic class ProjectSettingsDock : Widget\r\n{\r\n\tNavigationView view;\r\n\r\n\tpublic ProjectSettingsDock(Widget parent) : base(parent)\r\n\t{\r\n\t\tLayout = Layout.Column();\r\n\t\tLayout.Margin = 4;\r\n\t\tLayout.Spacing = 4;\r\n\r\n\t\tview = new NavigationView(this);\r\n\t\tview.MinimumSize = 0;\r\n\t\t//Layout.Add(View);\r\n\t\tview.SetSizeMode(SizeMode.Default, SizeMode.Flexible);\r\n\r\n\t\tvar scroller = new ScrollArea(this);\r\n\t\tscroller.Canvas = view;\r\n\t\tscroller.Canvas.SetSizeMode(SizeMode.Default, SizeMode.Flexible);\r\n\t\tscroller.Canvas.Layout = Layout.Column();\r\n\t\tLayout.Add(scroller);\r\n\t\tscroller.Canvas.Layout.AddStretchCell();\r\n\r\n\t\tview.MenuTop.Add(new Label(\u0022Project Settings\u0022));\r\n\t\tview.MenuTop.AddSpacingCell(16);\r\n\r\n\t\tRebuild();\r\n\t}\r\n\r\n\t[Hotload(Priority = 10)]\r\n\tpublic void Rebuild()\r\n\t{\r\n\t\tvar lastOptionTitle = view?.CurrentOption?.Title;\r\n\r\n\t\tview.ClearPages();\r\n\r\n\t\tvar types = GlobalGameNamespace.TypeLibrary.GetTypes\u003CProjectSettingNonGenericBase\u003E();\r\n\t\tvar optionTitleToOption = new Dictionary\u003Cstring, NavigationView.Option\u003E();\r\n\t\ttypes = types.OrderBy(t =\u003E t.TargetType.Name);\r\n\r\n\t\tforeach (var type in types)\r\n\t\t{\r\n\t\t\tif (type.IsAbstract)\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tvar targetType = type.TargetType;\r\n\t\t\tType constructedType = typeof(ProjectSetting\u003C\u003E).MakeGenericType(targetType);\r\n\t\t\tvar instanceProperty = constructedType.GetProperty(\u0022instance\u0022, BindingFlags.Static | BindingFlags.Public);\r\n\r\n\t\t\tvar inst = instanceProperty.GetValue(null);\r\n\t\t\tvar gameResourceInst = inst as GameResource;\r\n\r\n\t\t\tstring title = FormatToReadable(targetType.Name);\r\n\r\n\t\t\tvar option = view.AddPage(title, null, new ProjectSettingsInspector(this, gameResourceInst));\r\n\t\t\toptionTitleToOption[title] = option;\r\n\t\t}\r\n\r\n\t\t// Custom Widget Support\r\n\t\tvar attributesTypes = GlobalToolsNamespace.EditorTypeLibrary.GetTypesWithAttribute\u003CProjectSettingsWidgetAttribute\u003E();\r\n\r\n\t\tforeach (var attributeInst in attributesTypes)\r\n\t\t{\r\n\t\t\tif (attributeInst.Type?.TargetType == null)\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tbool isWidgetType = attributeInst.Type.TargetType.IsSubclassOf(typeof(Widget));\r\n\t\t\tif (!isWidgetType)\r\n\t\t\t{\r\n\t\t\t\tLog.Warning($\u0022ProjectSettingsDock failed to create widget instance for \u0027{attributeInst.Type.TargetType}\u0027 are you use this inherits from Widget?\u0022);\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tvar widgetInst = Activator.CreateInstance(attributeInst.Type.TargetType, this) as Widget;\r\n\t\t\tif (widgetInst == null)\r\n\t\t\t{\r\n\t\t\t\tLog.Error($\u0022ProjectSettingsDock failed to create instance for type \u0027{attributeInst.Type.TargetType}\u0027\u0022);\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tstring title = attributeInst.Attribute.title;\r\n\t\t\tif (string.IsNullOrEmpty(title))\r\n\t\t\t{\r\n\t\t\t\ttitle = FormatToReadable(attributeInst.Type.Name);\r\n\t\t\t}\r\n\r\n\t\t\tvar option = view.AddPage(title, null, widgetInst);\r\n\t\t\toptionTitleToOption[title] = option;\r\n\t\t}\r\n\r\n\t\t// Keeps the select option after a rebuild, this was really annoying me\r\n\t\tif (!string.IsNullOrEmpty(lastOptionTitle))\r\n\t\t{\r\n\t\t\tif (optionTitleToOption.TryGetValue(lastOptionTitle, out var option))\r\n\t\t\t{\r\n\t\t\t\tif (option != null)\r\n\t\t\t\t{\r\n\t\t\t\t\tview.CurrentOption = option;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tpublic static string FormatToReadable(string input)\r\n\t{\r\n\t\t// Add space before each uppercase letter that is followed by a lowercase letter or another uppercase letter group.\r\n\t\tstring formattedInput = System.Text.RegularExpressions.Regex.Replace(input, \u0022(?\u003C=.)([A-Z][a-z])\u0022, \u0022 $1\u0022);\r\n\r\n\t\t// Add space between an acronym and the next capitalized word (e.g., \u0022XMLParser\u0022 becomes \u0022XML Parser\u0022)\r\n\t\tformattedInput = System.Text.RegularExpressions.Regex.Replace(formattedInput, \u0022(?\u003C=[a-z])([A-Z])\u0022, \u0022 $1\u0022);\r\n\r\n\t\t// Capitalize the first letter of the resulting string\r\n\t\treturn Char.ToUpper(formattedInput[0]) \u002B formattedInput.Substring(1);\r\n\t}\r\n}\r\n\r\npublic class ProjectSettingsInspector : Widget\r\n{\r\n\tpublic ProjectSettingsInspector(Widget parent, GameResource gameResource) : base(parent)\r\n\t{\r\n\t\tLayout = Layout.Column();\r\n\t\tSetSizeMode(SizeMode.Default, SizeMode.Flexible);\r\n\r\n\t\tvar sheet = new ControlSheet();\r\n\r\n\t\tvar so = gameResource.GetSerialized();\r\n\r\n\t\tvar scroller = new ScrollArea(this);\r\n\t\tscroller.Canvas = new Widget(this);\r\n\t\tscroller.Canvas.SetSizeMode(SizeMode.Default, SizeMode.Flexible);\r\n\t\tscroller.Canvas.Layout = Layout.Column();\r\n\t\tLayout.Add(scroller);\r\n\r\n\t\tso.OnPropertyChanged \u002B= x =\u003E\r\n\t\t{\r\n\t\t\tvar asset = AssetSystem.FindByPath(gameResource.ResourcePath);\r\n\t\t\tif (asset != null)\r\n\t\t\t{\r\n\t\t\t\tbool saved = asset.SaveToDisk(gameResource);\r\n\t\t\t\tif (!saved)\r\n\t\t\t\t{\r\n\t\t\t\t\tLog.Error($\u0022ProjectSettingsInspector \u0027{gameResource?.ResourceName}\u0027 failed to save, is the file read only? Please report it\u0022);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t{\r\n\t\t\t\tLog.Error($\u0022ProjectSettingsInspector \u0027{gameResource?.ResourceName}\u0027 failed to get asset, this should not happen! Please report it\u0022);\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tsheet.AddObject(so);\r\n\r\n\t\tscroller.Canvas.Layout.Add(sheet);\r\n\t\tscroller.Canvas.Layout.AddStretchCell();\r\n\t}\r\n}\r\n\r\n// Can\u0027t do because you can\u0027t reference library editor projects\r\n/*[AttributeUsage(AttributeTargets.Class)]\r\npublic class ProjectSettingsWidgetAttribute : Attribute\r\n{\r\n\tpublic string group { get; }\r\n\tpublic string title { get; }\r\n\r\n\tpublic ProjectSettingsWidgetAttribute(string group = null, string title = null)\r\n\t{\r\n\t\tthis.group = group;\r\n\t\tthis.title = title;\r\n\t}\r\n}*/"},{"Ident":"coomzy.projectsettings","Path":"Editor/ProjectSettingCreator.cs","FileName":"ProjectSettingCreator.cs","PackageType":"library","CodeKind":"Editor","AssetVersionId":72213,"Code":"using System;\r\nusing System.Reflection;\r\nusing Editor;\r\nusing Sandbox;\r\nusing System.Linq;\r\nusing System.Collections.Generic;\r\nusing static Editor.EditorEvent;\r\nusing Sandbox.Internal;\r\nusing System.IO;\r\n\r\npublic static class ProjectSettingCreator\r\n{\r\n\t[Hotload(Priority = -10)]\r\n\tpublic static void CreateProjectSettingFiles()\r\n\t{\r\n\t\tvar types = GlobalGameNamespace.TypeLibrary.GetTypes\u003CProjectSettingNonGenericBase\u003E();\r\n\r\n\t\tforeach(var type in types)\r\n\t\t{\r\n\t\t\tif (type.IsAbstract)\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tvar targetType = type.TargetType;\r\n\t\t\tvar instance = Activator.CreateInstance(targetType) as GameResource;\r\n\r\n\t\t\tType constructedType = typeof(ProjectSetting\u003C\u003E).MakeGenericType(targetType);\r\n\t\t\tvar filePathProperty = constructedType.GetProperty(\u0022fullFilePathWithoutExtension\u0022, BindingFlags.Static | BindingFlags.Public);\r\n\t\t\tvar fileExtensionProperty = constructedType.GetProperty(\u0022fileExtension\u0022, BindingFlags.Static | BindingFlags.Public);\r\n\r\n\t\t\tstring filePath = filePathProperty != null ? filePathProperty.GetValue(null) as string : null;\r\n\t\t\tstring fileExtension = fileExtensionProperty != null ? fileExtensionProperty.GetValue(null) as string : null;\r\n\r\n\t\t\tif (string.IsNullOrEmpty(filePath) || string.IsNullOrEmpty(fileExtension))\r\n\t\t\t{\r\n\t\t\t\tLog.Error($\u0022Could not retrieve filePath or fileExtension for \u0027{targetType}\u0027\u0022);\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tvar targetDirectory = Path.GetDirectoryName(filePath);\r\n\t\t\tif (!Directory.Exists(targetDirectory))\r\n\t\t\t{\r\n\t\t\t\tDirectory.CreateDirectory(targetDirectory);\r\n\t\t\t}\r\n\t\r\n\t\t\tAssetSystem.CreateResource(fileExtension, filePath);\r\n\t\t\tAssetSystem.RegisterFile($\u0022{filePath}.{fileExtension}\u0022);\r\n\t\t}\r\n\t}\r\n}\r\n"},{"Ident":"coomzy.projectsettings","Path":".obj/__compiler_extra.cs","FileName":"__compiler_extra.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72213,"Code":"global using static Sandbox.Internal.GlobalGameNamespace;\r\n[assembly: global::System.Reflection.AssemblyMetadata( \u0022AddonTitle\u0022, \u0022Project Settings\u0022 )]\r\n[assembly: global::System.Reflection.AssemblyMetadata( \u0022AddonIdent\u0022, \u0022projectsettings\u0022 )]\r\n[assembly: global::System.Reflection.AssemblyMetadata( \u0022OrgIdent\u0022, \u0022coomzy\u0022 )]\r\n[assembly: global::System.Reflection.AssemblyMetadata( \u0022Ident\u0022, \u0022coomzy.projectsettings\u0022 )]\r\n[assembly: global::System.Reflection.AssemblyMetadata( \u0022CompileTime\u0022, \u00229/7/2024 2:14:20 AM\u0022 )]\r\n[assembly: global::System.Reflection.AssemblyMetadata( \u0022EngineVersion\u0022, \u002217\u0022 )]\r\n[assembly: global::System.Reflection.AssemblyMetadata( \u0022EngineMinorVersion\u0022, \u00221\u0022 )]\r\n\r\n[assembly: System.Runtime.Versioning.TargetFramework( \u0022.NETCoreApp,Version=v7.0\u0022, FrameworkDisplayName = \u0022.NET 7.0\u0022 )]\r\n[assembly: global::System.Reflection.AssemblyVersion(\u00220.0.142.0\u0022)]\r\n[assembly: global::System.Reflection.AssemblyFileVersion(\u00220.0.142.0\u0022)]"},{"Ident":"coomzy.projectsettings","Path":"Attributes/ProjectSettingsWidgetAttribute.cs","FileName":"ProjectSettingsWidgetAttribute.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72213,"Code":"using System;\r\n\r\n[AttributeUsage(AttributeTargets.Class)]\r\npublic class ProjectSettingsWidgetAttribute : Attribute\r\n{\r\n\tpublic string title { get; }\r\n\r\n\tpublic ProjectSettingsWidgetAttribute(string title = null)\r\n\t{\r\n\t\tthis.title = title;\r\n\t}\r\n}"},{"Ident":"coomzy.projectsettings","Path":"Code/Attributes/ProjectSettingsWidgetAttribute.cs","FileName":"ProjectSettingsWidgetAttribute.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72213,"Code":"using System;\r\n\r\n[AttributeUsage(AttributeTargets.Class)]\r\npublic class ProjectSettingsWidgetAttribute : Attribute\r\n{\r\n\tpublic string title { get; }\r\n\r\n\tpublic ProjectSettingsWidgetAttribute(string title = null)\r\n\t{\r\n\t\tthis.title = title;\r\n\t}\r\n}"}]}