diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..a3c7dea --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,17 @@ +version: 2 +updates: + - package-ecosystem: github-actions + cooldown: + default-days: 7 + directory: / + schedule: + interval: daily + open-pull-requests-limit: 5 + labels: + - internal + commit-message: + prefix: chore + groups: + github-actions: + patterns: + - "*" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 91d942d..467d395 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,47 +2,42 @@ name: Build on: push: - branches: [ '**' ] + branches: [master] pull_request: - branches: [ '**' ] + branches: ['**'] workflow_dispatch: jobs: build: runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: - fetch-depth: 0 # Need to fetch all for proper history - - name: Collect build info - id: info - run: | - # Get short SHA - SHA_SHORT=$(git rev-parse --short HEAD) - echo "sha_short=$SHA_SHORT" >> $GITHUB_OUTPUT - - # Extract version from csproj - VERSION=$(grep -oP '(?<=)[^<]+' BepInExResoniteShim.csproj) - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "Version found: $VERSION" - - uses: actions/setup-dotnet@v4 + fetch-depth: 0 + persist-credentials: false + - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: - dotnet-version: "10.0.x" - - name: Build + global-json-file: global.json + - name: Build and create Thunderstore package + id: build run: | - dotnet build -c Release + dotnet build -c Release -t:PackTS dotnet pack -c Release --no-build -o ./bin/dist - # Copy the built DLL to dist folder - cp ./bin/Release/BepInExResoniteShim.dll ./bin/dist/ - - name: Create Thunderstore Package + cp ./BepInExResoniteShim/bin/Release/BepInExResoniteShim.dll ./bin/dist/ + - name: Show version + id: info + env: + VERSION: '${{ steps.build.outputs.version }}' run: | - dotnet tool restore - dotnet tcli build --package-version ${{ steps.info.outputs.version }} + echo "Version found: $VERSION" + echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - name: Upload artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: BepInExResoniteShim-${{ steps.info.outputs.version }}-${{ steps.info.outputs.sha_short }} + name: 'BepInExResoniteShim-${{ steps.build.outputs.version }}-${{ steps.info.outputs.sha_short }}' path: | ./bin/dist/*.nupkg ./bin/dist/*.dll - ./build/*.zip \ No newline at end of file + ./build/*.zip diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 59cc5d5..9ff7f09 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,34 +6,17 @@ on: jobs: release: runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: - fetch-depth: 0 # Need to fetch all for proper history - - name: Collect build info - id: info - run: | - # Get short SHA - SHA_SHORT=$(git rev-parse --short HEAD) - echo "sha_short=$SHA_SHORT" >> $GITHUB_OUTPUT - - # Extract version from csproj - VERSION=$(grep -oP '(?<=)[^<]+' BepInExResoniteShim.csproj) - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "Version found: $VERSION" - - uses: actions/setup-dotnet@v4 + fetch-depth: 0 + persist-credentials: false + - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: - dotnet-version: "10.0.x" - - name: Build - run: | - dotnet build -c Release - - name: Create Thunderstore Package - run: | - dotnet tool restore - dotnet tcli build --package-version ${{ steps.info.outputs.version }} - - name: Publish to Thunderstore - run: | - ZIP_FILE=$(ls ./build/*.zip | head -1) - dotnet tcli publish --file "$ZIP_FILE" + global-json-file: global.json + - name: Build and publish Thunderstore package env: - TCLI_AUTH_TOKEN: ${{ secrets.TCLI_AUTH_TOKEN }} \ No newline at end of file + TCLI_AUTH_TOKEN: ${{ secrets.TCLI_AUTH_TOKEN }} + run: dotnet build -c Release -t:PackTS -P:PublishTS=true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2f5b33d..d6eb9df 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,64 +18,45 @@ on: jobs: release: runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + attestations: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: - fetch-depth: 0 # Need to fetch all for proper history - - name: Collect build info - id: info - run: | - # Get short SHA - SHA_SHORT=$(git rev-parse --short HEAD) - echo "sha_short=$SHA_SHORT" >> $GITHUB_OUTPUT - - # Extract version from csproj - VERSION=$(grep -oP '(?<=)[^<]+' BepInExResoniteShim.csproj) - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "Version found: $VERSION" - - uses: actions/setup-dotnet@v4 + fetch-depth: 0 + persist-credentials: false + - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: - dotnet-version: "10.0.x" - - name: Build + global-json-file: global.json + - name: Build and create Thunderstore package + id: build run: | - dotnet build -c Release + dotnet build -c Release -t:PackTS dotnet pack -c Release --no-build -o ./bin/dist - # Copy the built DLL to dist folder for release - cp ./bin/Release/BepInExResoniteShim.dll ./bin/dist/ - - name: Create Thunderstore Package - run: | - dotnet tool restore - dotnet tcli build --package-version ${{ steps.info.outputs.version }} - - name: Create Git Tag (if needed) - if: ${{ github.event_name == 'workflow_dispatch' }} - run: | - TAG_NAME="${{ steps.info.outputs.version }}" - # Check if tag already exists - if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then - echo "Tag $TAG_NAME already exists" - else - echo "Creating tag $TAG_NAME" - git config user.name github-actions - git config user.email github-actions@github.com - git tag -a "$TAG_NAME" -m "Release $TAG_NAME" - git push origin "$TAG_NAME" - fi - - name: Publish to Nuget - run: | - dotnet nuget push ./bin/dist/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://nuget-modding.resonite.net/v3/index.json --skip-duplicate - - name: Create GitHub Release - if: ${{ (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) || (github.event_name == 'workflow_dispatch' && github.event.inputs.create_release == 'true') }} - uses: softprops/action-gh-release@v2 + cp ./BepInExResoniteShim/bin/Release/BepInExResoniteShim.dll ./bin/dist/ + - name: Attest artifacts + uses: actions/attest@f7c74d28b9d84cb8768d0b8ca14a4bac6ef463e6 # v4.2.0 with: - draft: true - prerelease: false - generate_release_notes: false - name: ${{ steps.info.outputs.version }} - tag_name: ${{ steps.info.outputs.version }} - target_commitish: ${{ github.sha }} - files: | + subject-path: | ./bin/dist/*.nupkg ./bin/dist/*.dll ./build/*.zip + - name: Publish to Nuget env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} + run: | + dotnet nuget push ./bin/dist/*.nupkg --api-key "$NUGET_API_KEY" --source https://nuget-modding.resonite.net/v3/index.json --skip-duplicate + - name: Create GitHub Release + if: ${{ (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) || (github.event_name == 'workflow_dispatch' && github.event.inputs.create_release == 'true') }} + env: + TAG_NAME: ${{ steps.build.outputs.version }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release create "$TAG_NAME" \ + --draft \ + --title "$TAG_NAME" \ + ./bin/dist/*.nupkg \ + ./bin/dist/*.dll \ + ./build/*.zip diff --git a/BepInExResoniteShim.cs b/BepInExResoniteShim.cs deleted file mode 100644 index e8a7e9a..0000000 --- a/BepInExResoniteShim.cs +++ /dev/null @@ -1,217 +0,0 @@ -using BepInEx; -using BepInEx.Configuration; -using BepInEx.Logging; -using BepInEx.NET.Common; -using Elements.Core; -using FrooxEngine; -using HarmonyLib; -using Renderite.Shared; -using System.Reflection; -using System.Reflection.Emit; - -namespace BepInExResoniteShim; - -public class ResonitePlugin : BepInPlugin -{ - public ResonitePlugin(string GUID, string Name, string Version, string Author, string Link) : base(GUID, Name, Version) - { - this.Author = Author; - this.Link = Link; - } - public string Author { get; protected set; } - public string Link { get; protected set; } -} - - -[ResonitePlugin(PluginMetadata.GUID, PluginMetadata.NAME, PluginMetadata.VERSION, PluginMetadata.AUTHORS, PluginMetadata.REPOSITORY_URL)] -class BepInExResoniteShim : BasePlugin -{ - internal static new ManualLogSource Log = null!; - static ConfigEntry ShowWatermark = null!; - - internal static string? GetBepisLoaderVersion() - { - try - { - var bepisLoaderAssembly = AppDomain.CurrentDomain.GetAssemblies() - .FirstOrDefault(a => a.GetName().Name == "BepisLoader"); - - if (bepisLoaderAssembly != null) - { - var version = bepisLoaderAssembly.GetName().Version; - if (version != null) - { - return $"v{version.Major}.{version.Minor}.{version.Build}"; - } - } - } - catch (Exception e) - { - Log.LogWarning($"Failed to get BepisLoader version: {e.Message}"); - } - - return null; - } - - public override void Load() - { - Log = base.Log; - - var bepisLoaderVersion = GetBepisLoaderVersion(); - Log.LogInfo(bepisLoaderVersion != null - ? $"Loader: BepisLoader {bepisLoaderVersion}" - : "Loader: BepisLoader not found, version unknown"); - ShowWatermark = Config.Bind("General", "ShowWatermark", true, "Shows 'BepisLoader' watermark in the window title"); - - Type? lastAttempted = null; - try - { - var types = GenericTypesAttribute.GetTypes(GenericTypesAttribute.Group.EnginePrimitives); - foreach (var type in types) - { - lastAttempted = type; - if (TomlTypeConverter.CanConvert(type)) continue; - TomlTypeConverter.AddConverter(type, new TypeConverter - { - ConvertToString = (obj, type) => (string)typeof(Coder<>).MakeGenericType(type).GetMethod("EncodeToString")!.Invoke(null, [obj])!, - ConvertToObject = (str, type) => typeof(Coder<>).MakeGenericType(type).GetMethod("DecodeFromString")!.Invoke(null, [str])!, - }); - } - - lastAttempted = typeof(dummy); - TomlTypeConverter.AddConverter(typeof(dummy), new TypeConverter - { - ConvertToString = (_, _) => "dummy", - ConvertToObject = (_, _) => default(dummy), - }); - } - catch (Exception e) - { - Log.LogError($"Failed to register generic type converters (Last attempted = {lastAttempted?.ToString() ?? "NULL"}): " + e); - } - - RunPatches(HarmonyInstance); - } - - internal static bool AnyPatchFailed { get; private set; } - - /// - /// Apply all patches, incompatible patches are skipped gracefully. - /// - static void RunPatches(Harmony harmony) - { - var assembly = Assembly.GetExecutingAssembly(); - foreach (var type in AccessTools.GetTypesFromAssembly(assembly)) - { - try - { - harmony.CreateClassProcessor(type).Patch(); - } - catch (Exception e) - { - Log.LogDebug($"Skipped patching {type.Name}: {e.Message}"); - AnyPatchFailed = true; - } - } - } - - [HarmonyPatch] - class LocationFixer - { - public static MethodBase TargetMethod() - { - return AccessTools.FirstConstructor(typeof(AssemblyTypeRegistry), (x) => x.GetParameters().Length > 3); - } - public static IEnumerable Transpiler(IEnumerable codes) - { - int killCount = 0; - var cachePath = AccessTools.PropertyGetter(typeof(GlobalTypeRegistry), nameof(GlobalTypeRegistry.MetadataCachePath)); - var asmLoc = AccessTools.PropertyGetter(typeof(Assembly), nameof(Assembly.Location)); - - foreach (var code in codes) - { - if (killCount > 0) - { - killCount--; - continue; - } - if (code.Calls(asmLoc)) - { - Log.LogDebug("Patched AsmLoc"); - - yield return new(OpCodes.Call, AccessTools.Method(typeof(LocationFixer), nameof(ProcessCacheTime))); - killCount = 2; // skip next code - } - else - { - yield return code; - } - if (code.Calls(cachePath)) - { - Log.LogDebug("Patched CachePath"); - - yield return new(OpCodes.Ldarg_1); // assembly - yield return new(OpCodes.Call, AccessTools.Method(typeof(LocationFixer), nameof(ProcessCachePath))); - } - } - } - - public static string? ProcessCachePath(string cachePath, Assembly asm) - { - if (string.IsNullOrWhiteSpace(asm.Location)) return null; - return cachePath; - } - - public static DateTime ProcessCacheTime(Assembly asm) - { - if (string.IsNullOrWhiteSpace(asm.Location)) return DateTime.UtcNow; - return new FileInfo(asm.Location).LastWriteTimeUtc; - } - } - - [HarmonyPatch(typeof(EngineInitializer), nameof(EngineInitializer.InitializeFrooxEngine), MethodType.Async)] - class AssemblyLoadFixer - { - public static IEnumerable Transpiler(IEnumerable codes) - { - var loadFrom = AccessTools.Method(typeof(Assembly), nameof(Assembly.LoadFrom), [typeof(string)]); - foreach (var code in codes) - { - if (code.Calls(loadFrom)) - { - yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(AssemblyLoadFixer), nameof(LoadFrom))); - } - else - { - yield return code; - } - } - } - - public static Assembly? LoadFrom(string path) - { - Log.LogDebug("Bypassing LoadFrom: " + path); - return null; - } - } - - [HarmonyPatch(typeof(RendererInitData), "Pack")] - class WindowTitlePatcher - { - public static void Prefix(RendererInitData __instance) - { - if (!ShowWatermark.Value) - { - return; - } - - if (__instance.windowTitle == "Resonite") - { - var version = GetBepisLoaderVersion(); - var newTitle = $"Resonite - BepisLoader {version ?? ""}"; - __instance.windowTitle = newTitle; - Log.LogInfo($"Successfully patched window title to: {newTitle}"); - } - } - } -} diff --git a/BepInExResoniteShim.sln b/BepInExResoniteShim.sln deleted file mode 100644 index 97cd80c..0000000 --- a/BepInExResoniteShim.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.13.35825.156 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BepInExResoniteShim", "BepInExResoniteShim.csproj", "{1E65DF6A-E53B-4EC2-88B4-83800D69B42C}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1E65DF6A-E53B-4EC2-88B4-83800D69B42C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1E65DF6A-E53B-4EC2-88B4-83800D69B42C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1E65DF6A-E53B-4EC2-88B4-83800D69B42C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1E65DF6A-E53B-4EC2-88B4-83800D69B42C}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {C29B6C3D-13EC-447C-A56C-A99BE722A036} - EndGlobalSection -EndGlobal diff --git a/BepInExResoniteShim.slnx b/BepInExResoniteShim.slnx new file mode 100644 index 0000000..c9c55e0 --- /dev/null +++ b/BepInExResoniteShim.slnx @@ -0,0 +1,3 @@ + + + diff --git a/BepInExResoniteShim.csproj b/BepInExResoniteShim/BepInExResoniteShim.csproj similarity index 91% rename from BepInExResoniteShim.csproj rename to BepInExResoniteShim/BepInExResoniteShim.csproj index 6998273..eb224af 100644 --- a/BepInExResoniteShim.csproj +++ b/BepInExResoniteShim/BepInExResoniteShim.csproj @@ -1,4 +1,4 @@ - + 0.9.3 @@ -19,6 +19,7 @@ true true embedded + true $(ResonitePath)/ $(MSBuildProgramFiles32)\Steam\steamapps\common\Resonite\ $(HOME)/.steam/steam/steamapps/common/Resonite/ @@ -41,7 +42,7 @@ - + @@ -58,6 +59,10 @@ $(GamePath)Renderite.Host.dll False + + $(GamePath)SkyFrost.Base.Models.dll + False + $(GamePath)Renderite.Shared.dll False @@ -82,4 +87,4 @@ true - + \ No newline at end of file diff --git a/BepInExResoniteShim/Patches/AssemblyLoadFixer.cs b/BepInExResoniteShim/Patches/AssemblyLoadFixer.cs new file mode 100644 index 0000000..9095718 --- /dev/null +++ b/BepInExResoniteShim/Patches/AssemblyLoadFixer.cs @@ -0,0 +1,33 @@ +using BepInEx; +using FrooxEngine; +using HarmonyLib; +using System.Reflection; +using System.Reflection.Emit; + +namespace BepInExResoniteShim; + +[HarmonyPatch(typeof(EngineInitializer), nameof(EngineInitializer.InitializeFrooxEngine), MethodType.Async)] +class AssemblyLoadFixer +{ + public static IEnumerable Transpiler(IEnumerable codes) + { + var loadFrom = AccessTools.Method(typeof(Assembly), nameof(Assembly.LoadFrom), [typeof(string)]); + foreach (var code in codes) + { + if (code.Calls(loadFrom)) + { + yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(AssemblyLoadFixer), nameof(LoadFrom))); + } + else + { + yield return code; + } + } + } + + public static Assembly? LoadFrom(string path) + { + BepInExResoniteShim.Log.LogDebug("Bypassing LoadFrom: " + path); + return null; + } +} \ No newline at end of file diff --git a/GraphicalClientPatches.cs b/BepInExResoniteShim/Patches/GraphicalClientPatch.cs similarity index 93% rename from GraphicalClientPatches.cs rename to BepInExResoniteShim/Patches/GraphicalClientPatch.cs index bfddf4d..354d328 100644 --- a/GraphicalClientPatches.cs +++ b/BepInExResoniteShim/Patches/GraphicalClientPatch.cs @@ -1,4 +1,4 @@ -using BepInEx; +using BepInEx; using HarmonyLib; using Renderite.Host; @@ -11,4 +11,4 @@ public static void Postfix(ref string ___AssemblyDirectory) { ___AssemblyDirectory = Paths.GameRootPath; } -} +} \ No newline at end of file diff --git a/BepInExResoniteShim/Patches/LocationFixer.cs b/BepInExResoniteShim/Patches/LocationFixer.cs new file mode 100644 index 0000000..ae0599c --- /dev/null +++ b/BepInExResoniteShim/Patches/LocationFixer.cs @@ -0,0 +1,61 @@ +using BepInEx; +using FrooxEngine; +using HarmonyLib; +using System.Reflection; +using System.Reflection.Emit; + +namespace BepInExResoniteShim; + +[HarmonyPatch] +class LocationFixer +{ + public static MethodBase TargetMethod() + { + return AccessTools.FirstConstructor(typeof(AssemblyTypeRegistry), (x) => x.GetParameters().Length > 3); + } + public static IEnumerable Transpiler(IEnumerable codes) + { + int killCount = 0; + var cachePath = AccessTools.PropertyGetter(typeof(GlobalTypeRegistry), nameof(GlobalTypeRegistry.MetadataCachePath)); + var asmLoc = AccessTools.PropertyGetter(typeof(Assembly), nameof(Assembly.Location)); + + foreach (var code in codes) + { + if (killCount > 0) + { + killCount--; + continue; + } + if (code.Calls(asmLoc)) + { + BepInExResoniteShim.Log.LogDebug("Patched AsmLoc"); + + yield return new(OpCodes.Call, AccessTools.Method(typeof(LocationFixer), nameof(ProcessCacheTime))); + killCount = 2; + } + else + { + yield return code; + } + if (code.Calls(cachePath)) + { + BepInExResoniteShim.Log.LogDebug("Patched CachePath"); + + yield return new(OpCodes.Ldarg_1); + yield return new(OpCodes.Call, AccessTools.Method(typeof(LocationFixer), nameof(ProcessCachePath))); + } + } + } + + public static string? ProcessCachePath(string cachePath, Assembly asm) + { + if (string.IsNullOrWhiteSpace(asm.Location)) return null; + return cachePath; + } + + public static DateTime ProcessCacheTime(Assembly asm) + { + if (string.IsNullOrWhiteSpace(asm.Location)) return DateTime.UtcNow; + return new FileInfo(asm.Location).LastWriteTimeUtc; + } +} \ No newline at end of file diff --git a/LogAlerter.cs b/BepInExResoniteShim/Patches/LogAlerter.cs similarity index 96% rename from LogAlerter.cs rename to BepInExResoniteShim/Patches/LogAlerter.cs index 136e965..fd8f498 100644 --- a/LogAlerter.cs +++ b/BepInExResoniteShim/Patches/LogAlerter.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using Elements.Core; using HarmonyLib; @@ -25,4 +25,4 @@ static void Postfix(Action value) else value($"[BepisLoader] BepInExResoniteShim loaded successfully."); }); } -} +} \ No newline at end of file diff --git a/RelativePathFixer.cs b/BepInExResoniteShim/Patches/RelativePathFixer.cs similarity index 92% rename from RelativePathFixer.cs rename to BepInExResoniteShim/Patches/RelativePathFixer.cs index bfb8e15..8d1ce0f 100644 --- a/RelativePathFixer.cs +++ b/BepInExResoniteShim/Patches/RelativePathFixer.cs @@ -25,7 +25,7 @@ public static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable codes) - { + { foreach (var code in codes) { - if(code.Is(OpCodes.Ldstr, "Renderer")) + if (code.Is(OpCodes.Ldstr, "Renderer")) { yield return new(OpCodes.Ldstr, Path.Combine(Paths.GameRootPath, "Renderer")); continue; @@ -60,4 +60,4 @@ public static IEnumerable Transpiler(IEnumerable ShowWatermark = null!; + + internal static string? GetBepisLoaderVersion() + { + try + { + var bepisLoaderAssembly = AppDomain.CurrentDomain.GetAssemblies() + .FirstOrDefault(a => a.GetName().Name == "BepisLoader"); + + if (bepisLoaderAssembly != null) + { + var version = bepisLoaderAssembly.GetName().Version; + if (version != null) + { + return $"v{version.Major}.{version.Minor}.{version.Build}"; + } + } + } + catch (Exception e) + { + Log.LogWarning($"Failed to get BepisLoader version: {e.Message}"); + } + + return null; + } + + public override void Load() + { + Log = base.Log; + + var bepisLoaderVersion = GetBepisLoaderVersion(); + Log.LogInfo(bepisLoaderVersion != null + ? $"Loader: BepisLoader {bepisLoaderVersion}" + : "Loader: BepisLoader not found, version unknown"); + ShowWatermark = Config.Bind("General", "ShowWatermark", true, "Shows 'BepisLoader' watermark in the window title"); + + Type? lastAttempted = null; + try + { + var types = GenericTypesAttribute.GetTypes(GenericTypesAttribute.Group.EnginePrimitives); + foreach (var type in types) + { + lastAttempted = type; + if (TomlTypeConverter.CanConvert(type)) continue; + TomlTypeConverter.AddConverter(type, new TypeConverter + { + ConvertToString = (obj, type) => (string)typeof(Coder<>).MakeGenericType(type).GetMethod("EncodeToString")!.Invoke(null, [obj])!, + ConvertToObject = (str, type) => typeof(Coder<>).MakeGenericType(type).GetMethod("DecodeFromString")!.Invoke(null, [str])!, + }); + } + + lastAttempted = typeof(dummy); + TomlTypeConverter.AddConverter(typeof(dummy), new TypeConverter + { + ConvertToString = (_, _) => "dummy", + ConvertToObject = (_, _) => default(dummy), + }); + } + catch (Exception e) + { + Log.LogError($"Failed to register generic type converters (Last attempted = {lastAttempted?.ToString() ?? "NULL"}): " + e); + } + + RunPatches(HarmonyInstance); + } + + internal static bool AnyPatchFailed { get; private set; } + + static void RunPatches(Harmony harmony) + { + var assembly = Assembly.GetExecutingAssembly(); + foreach (var type in AccessTools.GetTypesFromAssembly(assembly)) + { + try + { + harmony.CreateClassProcessor(type).Patch(); + } + catch (Exception e) + { + Log.LogDebug($"Skipped patching {type.Name}: {e.Message}"); + AnyPatchFailed = true; + } + } + } +} \ No newline at end of file diff --git a/BepInExResoniteShim/PluginAttribute.cs b/BepInExResoniteShim/PluginAttribute.cs new file mode 100644 index 0000000..46f81ad --- /dev/null +++ b/BepInExResoniteShim/PluginAttribute.cs @@ -0,0 +1,14 @@ +using BepInEx; + +namespace BepInExResoniteShim; + +public class ResonitePlugin : BepInPlugin +{ + public ResonitePlugin(string GUID, string Name, string Version, string Author, string Link) : base(GUID, Name, Version) + { + this.Author = Author; + this.Link = Link; + } + public string Author { get; protected set; } + public string Link { get; protected set; } +} \ No newline at end of file diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 0000000..9ce823d --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,19 @@ + + + + + + + + build + publish + + + + + + + + + + diff --git a/global.json b/global.json new file mode 100644 index 0000000..f071a74 --- /dev/null +++ b/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "10.0.301" + } +} diff --git a/thunderstore.toml b/thunderstore.toml index 7a8751f..6013eae 100644 --- a/thunderstore.toml +++ b/thunderstore.toml @@ -6,7 +6,7 @@ schemaVersion = "0.0.1" [package] namespace = "ResoniteModding" name = "BepInExResoniteShim" # Change this to your mod's name, no spaces or special characters, max 128 characters -versionNumber = "0.8.2" # Change this to your mod's version, must be in semantic versioning format (e.g. 1.0.0, 2.1.3, 0.1.0-alpha.1) +versionNumber = "0.9.3" # Change this to your mod's version, must be in semantic versioning format (e.g. 1.0.0, 2.1.3, 0.1.0-alpha.1) description = "Patches which allow the game to run with BepInEx loaded" websiteUrl = "https://github.com/ResoniteModding/BepInExResoniteShim" containsNsfwContent = false @@ -21,14 +21,9 @@ outdir = "./build" # Copy the compiled DLL to the plugins folder in the mod package [[build.copy]] -source = "./bin/Release/BepInExResoniteShim.dll" +source = "./BepInExResoniteShim/bin/Release/BepInExResoniteShim.dll" target = "plugins/BepInExResoniteShim/" -# Include the PDB file for better debugging support -# [[build.copy]] -# source = "./bin/Release/BepInExResoniteShim.pdb" -# target = "plugins/BepInExResoniteShim/" - # Uncomment the following lines to include CHANGELOG file in your mod package. https://wiki.thunderstore.io/mods/updating-a-package#changelog # [[build.copy]] # source = "./CHANGELOG.md"