From aaaff1fabacc2b85d32c7850b68f20f0ee770ffc Mon Sep 17 00:00:00 2001 From: Nytra <14206961+Nytra@users.noreply.github.com> Date: Fri, 6 Sep 2024 12:35:43 +0100 Subject: [PATCH] Initial commit --- ...Loader.ModTemplate.sln => ArrayEditing.sln | 8 +- ArrayEditing/ArrayEditing.cs | 460 ++++++++++++++++++ .../ArrayEditing.csproj | 43 +- .../Locale/de.json | 0 .../Locale/en.json | 0 .../Locale/jp.json | 0 Directory.Build.props | 1 + .../BasicPrePatcher.cs | 42 -- ...MonkeyLoader.ModTemplate.PrePatcher.csproj | 27 - .../MyConfig.cs | 29 -- MonkeyLoader.ModTemplate/BasicPatcher.cs | 29 -- 11 files changed, 475 insertions(+), 164 deletions(-) rename MonkeyLoader.ModTemplate.sln => ArrayEditing.sln (62%) create mode 100644 ArrayEditing/ArrayEditing.cs rename MonkeyLoader.ModTemplate/MonkeyLoader.ModTemplate.csproj => ArrayEditing/ArrayEditing.csproj (57%) rename {MonkeyLoader.ModTemplate => ArrayEditing}/Locale/de.json (100%) rename {MonkeyLoader.ModTemplate => ArrayEditing}/Locale/en.json (100%) rename {MonkeyLoader.ModTemplate => ArrayEditing}/Locale/jp.json (100%) delete mode 100644 MonkeyLoader.ModTemplate.PrePatcher/BasicPrePatcher.cs delete mode 100644 MonkeyLoader.ModTemplate.PrePatcher/MonkeyLoader.ModTemplate.PrePatcher.csproj delete mode 100644 MonkeyLoader.ModTemplate.PrePatcher/MyConfig.cs delete mode 100644 MonkeyLoader.ModTemplate/BasicPatcher.cs diff --git a/MonkeyLoader.ModTemplate.sln b/ArrayEditing.sln similarity index 62% rename from MonkeyLoader.ModTemplate.sln rename to ArrayEditing.sln index c426db3..5e0f3b9 100644 --- a/MonkeyLoader.ModTemplate.sln +++ b/ArrayEditing.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.5.33516.290 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonkeyLoader.ModTemplate", "MonkeyLoader.ModTemplate\MonkeyLoader.ModTemplate.csproj", "{40835522-1978-431B-A395-0870583B80F5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArrayEditing", "ArrayEditing\ArrayEditing.csproj", "{40835522-1978-431B-A395-0870583B80F5}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{07124CF9-EE3D-4A7E-A2F8-8FD07966E423}" ProjectSection(SolutionItems) = preProject @@ -11,8 +11,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution README.md = README.md EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonkeyLoader.ModTemplate.PrePatcher", "MonkeyLoader.ModTemplate.PrePatcher\MonkeyLoader.ModTemplate.PrePatcher.csproj", "{F500B1A2-B913-4D93-941D-9BB5ABBDC800}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -23,10 +21,6 @@ Global {40835522-1978-431B-A395-0870583B80F5}.Debug|Any CPU.Build.0 = Debug|Any CPU {40835522-1978-431B-A395-0870583B80F5}.Release|Any CPU.ActiveCfg = Release|Any CPU {40835522-1978-431B-A395-0870583B80F5}.Release|Any CPU.Build.0 = Release|Any CPU - {F500B1A2-B913-4D93-941D-9BB5ABBDC800}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F500B1A2-B913-4D93-941D-9BB5ABBDC800}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F500B1A2-B913-4D93-941D-9BB5ABBDC800}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F500B1A2-B913-4D93-941D-9BB5ABBDC800}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ArrayEditing/ArrayEditing.cs b/ArrayEditing/ArrayEditing.cs new file mode 100644 index 0000000..9053599 --- /dev/null +++ b/ArrayEditing/ArrayEditing.cs @@ -0,0 +1,460 @@ +using Elements.Core; +using FrooxEngine.UIX; +using FrooxEngine; +using HarmonyLib; +using MonkeyLoader.Patching; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using EnumerableToolkit; +using MonkeyLoader.Resonite; + +namespace ArrayEditing +{ + [HarmonyPatchCategory(nameof(SyncArrayEditor))] + [HarmonyPatch(typeof(SyncMemberEditorBuilder), nameof(SyncMemberEditorBuilder.BuildArray))] + internal sealed class SyncArrayEditor : ResoniteMonkey + { + private static readonly MethodInfo _addLinearValueProxying = AccessTools.Method(typeof(SyncArrayEditor), nameof(AddLinearValueProxying)); + private static readonly MethodInfo _addListReferenceProxying = AccessTools.Method(typeof(SyncArrayEditor), nameof(AddListReferenceProxying)); + private static readonly MethodInfo _addListValueProxying = AccessTools.Method(typeof(SyncArrayEditor), nameof(AddListValueProxying)); + private static readonly MethodInfo _addCurveValueProxying = AccessTools.Method(typeof(SyncArrayEditor), nameof(AddCurveValueProxying)); + private static readonly Type _iWorldElementType = typeof(IWorldElement); + private static readonly Type _particleBurstType = typeof(ParticleBurst); + + public override bool CanBeDisabled => true; + + protected override IEnumerable GetFeaturePatches() => Enumerable.Empty(); + + private static void AddLinearValueProxying(SyncArray> array, SyncElementList.Point> list) + where T : IEquatable + { + foreach (var key in array) + { + var point = list.Add(); + point.Position.Value = key.time; + point.Value.Value = key.value; + } + + AddUpdateProxies(array, list, list.Elements); + + list.ElementsAdded += (list, startIndex, count) => + { + var addedElements = list.Elements.Skip(startIndex).Take(count).ToArray(); + var buffer = addedElements.Select(point => new LinearKey(point.Position, point.Value)).ToArray(); + + array.Insert(buffer, startIndex); + AddUpdateProxies(array, list, addedElements); + }; + + list.ElementsRemoved += (list, startIndex, count) => array.Remove(startIndex, count); + } + + private static void AddListReferenceProxying(SyncArray array, SyncElementList> list) + where T : class, IEquatable, IWorldElement + { + foreach (var reference in array) + { + var syncRef = list.Add(); + syncRef.Target = reference; + } + + AddUpdateProxies(array, list, list.Elements); + + list.ElementsAdded += (list, startIndex, count) => + { + var addedElements = list.Elements.Skip(startIndex).Take(count).ToArray(); + var buffer = addedElements.Select(syncRef => syncRef.Target).ToArray(); + + array.Insert(buffer, startIndex); + AddUpdateProxies(array, list, addedElements); + }; + + list.ElementsRemoved += (list, startIndex, count) => array.Remove(startIndex, count); + } + + private static void AddListValueProxying(SyncArray array, SyncElementList> list) + where T : IEquatable + { + foreach (var value in array) + { + var sync = list.Add(); + sync.Value = value; + } + + AddUpdateProxies(array, list, list.Elements); + + list.ElementsAdded += (list, startIndex, count) => + { + var addedElements = list.Elements.Skip(startIndex).Take(count).ToArray(); + var buffer = addedElements.Select(sync => sync.Value).ToArray(); + + array.Insert(buffer, startIndex); + AddUpdateProxies(array, list, addedElements); + }; + + list.ElementsRemoved += (list, startIndex, count) => array.Remove(startIndex, count); + } + + private static void AddParticleBurstListProxying(SyncArray> array, SyncElementList.Point> list) + { + foreach (var burst in array) + { + var point = list.Add(); + point.Position.Value = burst.time; + point.Value.Value = new int2(burst.value.minCount, burst.value.maxCount); + } + + AddUpdateProxies(array, list, list.Elements); + + list.ElementsAdded += (list, startIndex, count) => + { + var addedElements = list.Elements.Skip(startIndex).Take(count).ToArray(); + var buffer = addedElements.Select(point => new LinearKey(point.Position, new ParticleBurst() { minCount = point.Value.Value.x, maxCount = point.Value.Value.y })).ToArray(); + + array.Insert(buffer, startIndex); + AddUpdateProxies(array, list, addedElements); + }; + + list.ElementsRemoved += (list, startIndex, count) => array.Remove(startIndex, count); + } + + private static void AddTubePointProxying(SyncArray array, SyncElementList.Point> list) + { + foreach (var tubePoint in array) + { + var point = list.Add(); + point.Position.Value = tubePoint.radius; + point.Value.Value = tubePoint.position; + } + + AddUpdateProxies(array, list, list.Elements); + + list.ElementsAdded += (list, startIndex, count) => + { + var addedElements = list.Elements.Skip(startIndex).Take(count).ToArray(); + var buffer = addedElements.Select(point => new TubePoint(point.Value.Value, point.Position.Value)).ToArray(); + + array.Insert(buffer, startIndex); + AddUpdateProxies(array, list, addedElements); + }; + + list.ElementsRemoved += (list, startIndex, count) => array.Remove(startIndex, count); + } + + private static void AddCurveValueProxying(SyncArray> array, SyncElementList.Point> list) + where T : IEquatable + { + foreach (var key in array) + { + var point = list.Add(); + point.Position.Value = key.time; + point.Value.Value = key.value; + } + + AddUpdateProxies(array, list, list.Elements); + + list.ElementsAdded += (list, startIndex, count) => + { + var addedElements = list.Elements.Skip(startIndex).Take(count).ToArray(); + var buffer = addedElements.Select(point => new CurveKey(point.Position, point.Value)).ToArray(); + + array.Insert(buffer, startIndex); + AddUpdateProxies(array, list, addedElements); + }; + + list.ElementsRemoved += (list, startIndex, count) => array.Remove(startIndex, count); + } + + private static void AddUpdateProxies(SyncArray> array, + SyncElementList.Point> list, IEnumerable.Point> elements) + where T : IEquatable + { + foreach (var point in elements) + { + point.Changed += syncObject => + { + var index = list.IndexOfElement(point); + array[index] = new LinearKey(point.Position, point.Value); + }; + } + } + + private static void AddUpdateProxies(SyncArray> array, + SyncElementList.Point> list, IEnumerable.Point> elements) + { + foreach (var point in elements) + { + point.Changed += field => + { + var index = list.IndexOfElement(point); + var key = new LinearKey(point.Position, new ParticleBurst() { minCount = point.Value.Value.x, maxCount = point.Value.Value.y }); + array[index] = key; + }; + } + } + + private static void AddUpdateProxies(SyncArray array, SyncElementList> list, IEnumerable> elements) + where T : IEquatable + { + foreach (var sync in elements) + { + sync.OnValueChange += field => + { + var index = list.IndexOfElement(sync); + array[index] = sync.Value; + }; + } + } + + private static void AddUpdateProxies(SyncArray array, SyncElementList> list, IEnumerable> elements) + where T : class, IEquatable, IWorldElement + { + foreach (var sync in elements) + { + sync.OnValueChange += field => + { + var index = list.IndexOfElement(sync); + array[index] = sync.Target; + }; + } + } + + private static void AddUpdateProxies(SyncArray array, SyncElementList.Point> list, IEnumerable.Point> elements) + { + foreach (var point in elements) + { + point.Changed += field => + { + var index = list.IndexOfElement(point); + var tubePoint = new TubePoint(point.Value.Value, point.Position.Value); + array[index] = tubePoint; + }; + } + } + + private static void AddUpdateProxies(SyncArray> array, + SyncElementList.Point> list, IEnumerable.Point> elements) + where T : IEquatable + { + foreach (var point in elements) + { + point.Changed += syncObject => + { + var index = list.IndexOfElement(point); + array[index] = new CurveKey(point.Position, point.Value, array[index].leftTangent, array[index].rightTangent); + }; + } + } + + private static Component GetOrAttachComponent(Slot targetSlot, Type type, out bool attachedNew) + { + attachedNew = false; + if (targetSlot.GetComponent(type) is not Component comp) + { + comp = targetSlot.AttachComponent(type); + attachedNew = true; + } + return comp; + } + + private static bool Prefix(ISyncArray array, string name, FieldInfo fieldInfo, UIBuilder ui, float labelSize) + { + if (!Enabled) return true; + + if (!TryGetGenericParameters(typeof(SyncArray<>), array.GetType(), out var genericParameters)) + return true; + + var isSyncLinear = TryGetGenericParameters(typeof(SyncLinear<>), array.GetType(), out var syncLinearGenericParameters); + + var isSyncCurve = TryGetGenericParameters(typeof(SyncCurve<>), array.GetType(), out var syncCurveGenericParameters); + + var arrayType = genericParameters!.Value.First(); + var syncLinearType = syncLinearGenericParameters?.First(); + var syncCurveType = syncCurveGenericParameters?.First(); + + var isParticleBurst = syncLinearType == _particleBurstType; + + if (isSyncLinear && isParticleBurst) + syncLinearType = typeof(int2); + + var proxySlotName = $"{name}-{array.ReferenceID}-Proxy"; + var proxiesSlot = ui.World.AssetsSlot; + if (proxiesSlot.FindChild(proxySlotName) is not Slot proxySlot) + { + proxySlot = proxiesSlot.AddSlot(proxySlotName); + array.FindNearestParent().Destroyed += (IDestroyable _) => proxySlot.Destroy(); + } + proxySlot.DestroyWhenLocalUserLeaves(); + + ISyncList list; + FieldInfo listField; + + if (isSyncLinear && SupportsLerp(syncLinearType!)) + { + var gradientType = typeof(ValueGradientDriver<>).MakeGenericType(syncLinearType); + var gradient = GetOrAttachComponent(proxySlot, gradientType, out bool attachedNew); + + list = (ISyncList)gradient.GetSyncMember(nameof(ValueGradientDriver.Points)); + listField = gradient.GetSyncMemberFieldInfo(nameof(ValueGradientDriver.Points)); + + if (attachedNew) + { + if (isParticleBurst) + AddParticleBurstListProxying((SyncArray>)array, (SyncElementList.Point>)list); + else + _addLinearValueProxying.MakeGenericMethod(syncLinearType).Invoke(null, new object[] { array, list }); + } + } + else if (isSyncCurve && SupportsLerp(syncCurveType!)) + { + var gradientType = typeof(ValueGradientDriver<>).MakeGenericType(syncCurveType); + var gradient = GetOrAttachComponent(proxySlot, gradientType, out bool attachedNew); + + list = (ISyncList)gradient.GetSyncMember(nameof(ValueGradientDriver.Points)); + listField = gradient.GetSyncMemberFieldInfo(nameof(ValueGradientDriver.Points)); + + if (attachedNew) + { + _addCurveValueProxying.MakeGenericMethod(syncCurveType).Invoke(null, new object[] { array, list }); + } + } + else + { + if (arrayType == typeof(TubePoint)) + { + var gradient = GetOrAttachComponent(proxySlot, typeof(ValueGradientDriver), out bool attachedNew); + + list = (ISyncList)gradient.GetSyncMember(nameof(ValueGradientDriver.Points)); + listField = gradient.GetSyncMemberFieldInfo(nameof(ValueGradientDriver.Points)); + + if (attachedNew) + { + AddTubePointProxying((SyncArray)array, (SyncElementList.Point>)list); + } + } + else if (Coder.IsEnginePrimitive(arrayType)) + { + var multiplexerType = typeof(ValueMultiplexer<>).MakeGenericType(arrayType); + var multiplexer = GetOrAttachComponent(proxySlot, multiplexerType, out bool attachedNew); + list = (ISyncList)multiplexer.GetSyncMember(nameof(ValueMultiplexer.Values)); + listField = multiplexer.GetSyncMemberFieldInfo(nameof(ValueMultiplexer.Values)); + + if (attachedNew) + _addListValueProxying.MakeGenericMethod(arrayType).Invoke(null, new object[] { array, list }); + } + else if (_iWorldElementType.IsAssignableFrom(arrayType)) + { + var multiplexerType = typeof(ReferenceMultiplexer<>).MakeGenericType(arrayType); + var multiplexer = GetOrAttachComponent(proxySlot, multiplexerType, out bool attachedNew); + list = (ISyncList)multiplexer.GetSyncMember(nameof(ReferenceMultiplexer.References)); + listField = multiplexer.GetSyncMemberFieldInfo(nameof(ReferenceMultiplexer.References)); + + if (attachedNew) + _addListReferenceProxying.MakeGenericMethod(arrayType).Invoke(null, new object[] { array, list }); + } + else + { + proxySlot.Destroy(); + return true; + } + } + + ui.Panel().Slot.GetComponent(); + var memberFieldSlot = SyncMemberEditorBuilder.GenerateMemberField(array, name, ui, labelSize); + ui.NestOut(); + if (!array.IsDriven) + { + SyncMemberEditorBuilder.BuildList(list, name, listField, ui); + var listSlot = ui.Current; + listSlot.DestroyWhenLocalUserLeaves(); + void ArrayChanged(IChangeable changeable) + { + if (((ISyncArray)changeable).IsDriven) + { + listSlot.DestroyChildren(); + listSlot.Components.ToArray().Do((Component c) => c.Destroy()); + listSlot.AttachComponent().MinHeight.Value = 24f; + var newUi = new UIBuilder(listSlot, listSlot); + RadiantUI_Constants.SetupEditorStyle(newUi); + newUi.Text("(array is driven)"); + proxySlot?.Destroy(); + array.Changed -= ArrayChanged; + } + } + array.Changed += ArrayChanged; + } + else + { + LocaleString text = "(array is driven)"; + ui.Text(in text); + } + + return false; + } + + private static bool SupportsLerp(Type type) + { + var coderType = typeof(Coder<>).MakeGenericType(type); + return Traverse.Create(coderType).Property(nameof(Coder.SupportsLerp)).Value; + } + + private static bool TryGetGenericParameters(Type baseType, Type concreteType, [NotNullWhen(true)] out Sequence? genericParameters) + { + genericParameters = null; + + if (concreteType is null || baseType is null || !baseType.IsGenericType) + return false; + + if (concreteType.IsGenericType && concreteType.GetGenericTypeDefinition() == baseType) + { + genericParameters = concreteType.GetGenericArguments(); + return true; + } + + return TryGetGenericParameters(baseType, concreteType.BaseType, out genericParameters); + } + } + + internal sealed class ListUI_Improvements : ResoniteMonkey + { + public override bool CanBeDisabled => true; + + protected override IEnumerable GetFeaturePatches() => Enumerable.Empty(); + + [HarmonyPatchCategory(nameof(ListUI_Improvements))] + [HarmonyPatch(typeof(SyncMemberEditorBuilder), "GenerateMemberField")] + class SyncMemberEditorBuilder_GenerateMemberField_Patch + { + private static bool Prefix(ISyncMember member, string name, UIBuilder ui, float labelSize) + { + if (Enabled && member.Parent is ISyncList && member is SyncObject) + { + ui.CurrentRect.Slot.AttachComponent(); + if (ui.CurrentRect.Slot.GetComponent() is LayoutElement layoutElement) + { + layoutElement.MinWidth.Value = 48f; + layoutElement.FlexibleWidth.Value = -1f; + } + } + return true; + } + } + + [HarmonyPatchCategory(nameof(ListUI_Improvements))] + [HarmonyPatch(typeof(ListEditor), "BuildListElement")] + class ListEditor_BuildListElement_Patch + { + private static bool Prefix(ISyncList list, ISyncMember member, string name, UIBuilder ui) + { + if (Enabled) + { + ui.Style.MinHeight = 24f; + } + return true; + } + } + } +} \ No newline at end of file diff --git a/MonkeyLoader.ModTemplate/MonkeyLoader.ModTemplate.csproj b/ArrayEditing/ArrayEditing.csproj similarity index 57% rename from MonkeyLoader.ModTemplate/MonkeyLoader.ModTemplate.csproj rename to ArrayEditing/ArrayEditing.csproj index d67f18a..4f0c1ef 100644 --- a/MonkeyLoader.ModTemplate/MonkeyLoader.ModTemplate.csproj +++ b/ArrayEditing/ArrayEditing.csproj @@ -1,20 +1,20 @@  - MonkeyLoader.ModTemplate - MonkeyLoader.ModTemplate + ArrayEditing + ArrayEditing True - MonkeyLoader.ModTemplate.Resonite - MonkeyLoader Resonite Mod Template - Banane9 - 0.4.0 - This is a template for a Resonite MonkeyLoader mod. + ArrayEditing + Array Editing + Banane9, Nytra + 1.0.0 + Adds proxy list UI for editing arrays in inspectors. Also improves the look of list UI a bit. LGPL-3.0-or-later - https://github.com/ResoniteModdingGroup/MonkeyLoader.ModTemplate + https://github.com/Nytra/ResoniteArrayEditing mod; mods; monkeyloader; resonite - $(TargetsForTfmSpecificContentInPackage);AddExtraFilesToPackage + $(TargetsForTfmSpecificContentInPackage) @@ -24,12 +24,6 @@ 0.1.0-beta --> - - - - - - @@ -41,29 +35,18 @@ - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - $(PkgMonkeyLoader_GamePacks_Resonite)\lib\net462\pre-patchers\MonkeyLoader.Resonite.Data.dll - - - - - - diff --git a/MonkeyLoader.ModTemplate/Locale/de.json b/ArrayEditing/Locale/de.json similarity index 100% rename from MonkeyLoader.ModTemplate/Locale/de.json rename to ArrayEditing/Locale/de.json diff --git a/MonkeyLoader.ModTemplate/Locale/en.json b/ArrayEditing/Locale/en.json similarity index 100% rename from MonkeyLoader.ModTemplate/Locale/en.json rename to ArrayEditing/Locale/en.json diff --git a/MonkeyLoader.ModTemplate/Locale/jp.json b/ArrayEditing/Locale/jp.json similarity index 100% rename from MonkeyLoader.ModTemplate/Locale/jp.json rename to ArrayEditing/Locale/jp.json diff --git a/Directory.Build.props b/Directory.Build.props index c4ce13b..a06a6c5 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -39,5 +39,6 @@ C:\Program Files (x86)\Steam\steamapps\common\Resonite $(HOME)/.steam/steam/steamapps/common/Resonite D:/Files/Games/Resonite/app + G:\SteamLibrary\steamapps\common\Resonite diff --git a/MonkeyLoader.ModTemplate.PrePatcher/BasicPrePatcher.cs b/MonkeyLoader.ModTemplate.PrePatcher/BasicPrePatcher.cs deleted file mode 100644 index ef5e25e..0000000 --- a/MonkeyLoader.ModTemplate.PrePatcher/BasicPrePatcher.cs +++ /dev/null @@ -1,42 +0,0 @@ -using MonkeyLoader.Patching; -using MonkeyLoader.Resonite.Features.FrooxEngine; -using Mono.Cecil.Cil; -using Mono.Cecil.Rocks; -using MonoMod.Utils; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MonkeyLoader.ModTemplate -{ - internal sealed class BasicPrePatcher : ConfiguredEarlyMonkey - { - public static void HelloMethod() - => Logger.Info(() => $"Hello {ConfigSection.TargetName} from pre-patched-in SomeNameSpace.SomeType static constructor!"); - - // The options for these should be provided by your game's game pack. - protected override IEnumerable GetFeaturePatches() - { - yield return new FeaturePatch(PatchCompatibility.HookOnly); - } - - protected override IEnumerable GetPrePatchTargets() - { - yield return new PrePatchTarget(Feature.Assembly, "FrooxEngine.Engine"); - } - - protected override bool Patch(PatchJob patchJob) - { - var engine = patchJob.Types.First(); - var engineCCtor = engine.GetStaticConstructor(); - - var processor = engineCCtor.Body.GetILProcessor(); // using MonoMod.Utils; is important for this to work v - processor.InsertBefore(engineCCtor.Body.Instructions.First(), processor.Create(OpCodes.Call, typeof(BasicPrePatcher).GetMethod(nameof(HelloMethod)))); - - patchJob.Changes = true; - return true; - } - } -} \ No newline at end of file diff --git a/MonkeyLoader.ModTemplate.PrePatcher/MonkeyLoader.ModTemplate.PrePatcher.csproj b/MonkeyLoader.ModTemplate.PrePatcher/MonkeyLoader.ModTemplate.PrePatcher.csproj deleted file mode 100644 index 463c34f..0000000 --- a/MonkeyLoader.ModTemplate.PrePatcher/MonkeyLoader.ModTemplate.PrePatcher.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - MonkeyLoader.ModTemplate.PrePatcher - MonkeyLoader.ModTemplate - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - $(PkgMonkeyLoader_GamePacks_Resonite)\lib\net462\pre-patchers\MonkeyLoader.Resonite.Data.dll - - - diff --git a/MonkeyLoader.ModTemplate.PrePatcher/MyConfig.cs b/MonkeyLoader.ModTemplate.PrePatcher/MyConfig.cs deleted file mode 100644 index 6d43841..0000000 --- a/MonkeyLoader.ModTemplate.PrePatcher/MyConfig.cs +++ /dev/null @@ -1,29 +0,0 @@ -using MonkeyLoader.Configuration; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MonkeyLoader.ModTemplate -{ - internal sealed class MyConfig : ConfigSection - { - private readonly DefiningConfigKey _targetNameKey = new("TargetName", "Your name.", () => "World"); - - public override string Description => "This section contains my very useful config options."; - - public override string Id => "Main"; - - /// - /// Gets or sets the name. Not strictly necessary, but makes it a little nicer to use. - /// - public string TargetName - { - get => _targetNameKey.GetValue()!; - set => _targetNameKey.SetValue(value); - } - - public override Version Version { get; } = new Version(1, 0, 0); - } -} \ No newline at end of file diff --git a/MonkeyLoader.ModTemplate/BasicPatcher.cs b/MonkeyLoader.ModTemplate/BasicPatcher.cs deleted file mode 100644 index 41422ec..0000000 --- a/MonkeyLoader.ModTemplate/BasicPatcher.cs +++ /dev/null @@ -1,29 +0,0 @@ -using FrooxEngine.ProtoFlux; -using HarmonyLib; -using MonkeyLoader.Patching; -using MonkeyLoader.Resonite; -using MonkeyLoader.Resonite.Features.FrooxEngine; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MonkeyLoader.ModTemplate -{ - [HarmonyPatchCategory(nameof(BasicPatcher))] - [HarmonyPatch(typeof(ProtoFluxTool), nameof(ProtoFluxTool.OnAttach))] - internal class BasicPatcher : ResoniteMonkey - { - // The options for these should be provided by your game's game pack. - protected override IEnumerable GetFeaturePatches() - { - yield return new FeaturePatch(PatchCompatibility.HookOnly); - } - - private static void Postfix() - { - Logger.Info(() => "Postfix for ProtoFluxTool.OnAttach()!"); - } - } -} \ No newline at end of file