diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 149d75c1..34e69521 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,12 +1,5 @@
name: Build artifacts
-env:
- PROJ_NAME: Winch
- MODS_DIR: Winch.Examples
- DISASTER_BUTTON: DisasterButton
- EXAMPLE_ITEMS: ExampleItems
- INTRO_SKIPPER: IntroSkipper
-
on:
workflow_call:
inputs:
@@ -19,40 +12,36 @@ on:
jobs:
build:
name: Create artifacts
- runs-on: windows-latest
+ runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: "actions/checkout@v3"
+ uses: actions/checkout@v3
- name: Setup .NET
- uses: "actions/setup-dotnet@v3"
+ uses: actions/setup-dotnet@v3
- name: Build Winch
run: dotnet build -c ${{ inputs.build_type }}
- - name: Check
- run: ls
-
- name: Upload Winch Artifact
- uses: "actions/upload-artifact@v3"
+ uses: actions/upload-artifact@v3
with:
- name: "${{ env.PROJ_NAME }}"
- path: "${{ env.PROJ_NAME }}/bin"
+ name: Winch
+ path: Winch/bin
- - name: Upload DisasterButton Artifact
- uses: "actions/upload-artifact@v3"
- with:
- name: "${{ env.DISASTER_BUTTON }}"
- path: "${{ env.MODS_DIR }}/${{ env.DISASTER_BUTTON }}/bin"
-
- - name: Upload ExampleItems Artifact
- uses: "actions/upload-artifact@v3"
- with:
- name: "${{ env.EXAMPLE_ITEMS }}"
- path: "${{ env.MODS_DIR }}/${{ env.EXAMPLE_ITEMS }}/bin"
+ - name: Move Example Mods
+ run: |
+ for mod in DisasterButton ExampleItems IntroSkipper
+ do
+ mkdir -p Examples/$mod
+ mv Winch.Examples/$mod/bin/* Examples/$mod/
+ done
- - name: Upload IntroSkipper Artifact
- uses: "actions/upload-artifact@v3"
+ - name: Upload Example Mod Artifact
+ uses: actions/upload-artifact@v3
with:
- name: "${{ env.INTRO_SKIPPER }}"
- path: "${{ env.MODS_DIR }}/${{ env.INTRO_SKIPPER }}/bin"
+ name: Winch Examples
+ path: |
+ Examples/DisasterButton
+ Examples/ExampleItems
+ Examples/IntroSkipper
diff --git a/.github/workflows/release_build.yml b/.github/workflows/release_build.yml
new file mode 100644
index 00000000..f64fdb73
--- /dev/null
+++ b/.github/workflows/release_build.yml
@@ -0,0 +1,98 @@
+name: Release Build
+
+on:
+ push:
+ branches: [master]
+ paths-ignore:
+ - "*.md"
+ - "LICENSE"
+ - ".gitignore"
+ pull_request:
+ branches: [master]
+ types:
+ - synchronize
+ - labeled
+ paths-ignore:
+ - "*.md"
+ - "LICENSE"
+ - ".gitignore"
+
+jobs:
+ Build:
+ if: ${{ github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'update-pr') }}
+ uses: ./.github/workflows/build.yml
+ with:
+ build_type: Release
+ Update_Release:
+ name: 'Create/Update Release Asset'
+ needs: Build
+ outputs:
+ version: ${{ steps.version.outputs.prop }}
+ if: ${{ github.ref != 'refs/heads/master' && contains(github.event.pull_request.labels.*.name, 'update-pr') }}
+ runs-on: ubuntu-latest
+ steps:
+ - name: Download Winch Asset
+ uses: actions/download-artifact@v3
+ with:
+ name: Winch
+ path: Winch
+
+ - name: Zip Winch Asset
+ run: |
+ cd Winch/
+ zip -r Winch.zip *
+ mv Winch.zip ..
+ cd ..
+
+ - name: Download Example Mods
+ uses: actions/download-artifact@v3
+ with:
+ name: Winch Examples
+ path: Examples
+
+ - name: Zip Example Mods
+ run: |
+ for mod in DisasterButton ExampleItems IntroSkipper
+ do
+ cd Examples/$mod/
+ zip -r $mod.zip *
+ mv $mod.zip ../..
+ cd ../..
+ done
+ - name: Upload Asset
+ uses: ncipollo/release-action@v1
+ with:
+ allowUpdates: true
+ commit: master
+ tag: v${{ github.event.pull_request.title }}
+ name: Version ${{ github.event.pull_request.title }}
+ omitBodyDuringUpdate: true
+ artifacts: Winch.zip, DisasterButton.zip, ExampleItems.zip, IntroSkipper.zip
+ draft: true
+ prerelease: false
+ Pack_Nuget:
+ name: Pack nuget
+ needs: Update_Release
+ runs-on: windows-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ - name: Get version
+ id: version
+ uses: notiz-dev/github-action-json-property@release
+ with:
+ path: Winch/mod_meta.json
+ prop_path: Version
+ - name: Set up nuget
+ uses: NuGet/setup-nuget@v1.0.5
+ - name: Download Winch Asset
+ uses: actions/download-artifact@v3
+ with:
+ name: Winch
+ path: Winch/bin
+ - name: Pack nuget
+ run: nuget pack Winch/Winch.nuspec -Properties "version=${{ steps.version.outputs.prop }}"
+ - run: dir
+ - name: Publish nuget
+ run: nuget push "Winch.*.nupkg" -ApiKey ${{ secrets.NUGET_KEY }} -Source https://api.nuget.org/v3/index.json
+
diff --git a/.github/workflows/debug-release.yml b/.github/workflows/release_debug.yml
similarity index 52%
rename from .github/workflows/debug-release.yml
rename to .github/workflows/release_debug.yml
index 55388406..e36cf318 100644
--- a/.github/workflows/debug-release.yml
+++ b/.github/workflows/release_debug.yml
@@ -1,7 +1,13 @@
name: Debug artifact
on:
- [push, pull_request]
+ push:
+ branches-ignore: [master]
+ paths-ignore:
+ - "*.md"
+ - "LICENSE"
+ - ".gitignore"
+ workflow_dispatch:
jobs:
build:
diff --git a/.github/workflows/update_release.yml b/.github/workflows/update_release.yml
new file mode 100644
index 00000000..e77ed7ab
--- /dev/null
+++ b/.github/workflows/update_release.yml
@@ -0,0 +1,29 @@
+name: Create/Update Release
+
+on:
+ pull_request:
+ branches: [master]
+ types:
+ - ready_for_review
+ - edited
+ - labeled
+
+jobs:
+ Update_Release:
+ name: Create/Update Release
+ if: contains(github.event.pull_request.labels.*.name, 'update-pr')
+ runs-on: ubuntu-latest
+ steps:
+ - name: Create/Update Release
+ uses: ncipollo/release-action@v1
+ with:
+ allowUpdates: true
+ name: Version ${{ github.event.pull_request.title }}
+ tag: ${{ github.event.pull_request.title }}
+ commit: master
+ body: |
+ ${{ github.event.pull_request.body }}
+
+ **Generated From PR: ${{ github.event.pull_request.html_url }}**
+ draft: true
+ prerelease: false
diff --git a/README.md b/README.md
index eb1589a0..4750efb9 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,20 @@
![Winch](./banner.png)
[![Discord](https://img.shields.io/discord/1097191320935735346?style=for-the-badge)](https://discord.gg/qFqPuTUAmD)
-[![GitHub issues](https://img.shields.io/github/issues/Hacktix/Winch?style=for-the-badge)](https://github.com/Hacktix/Winch/issues)
-[![GitHub all releases](https://img.shields.io/github/downloads/Hacktix/Winch/total?style=for-the-badge)](https://github.com/Hacktix/Winch/releases)
+[![GitHub all releases](https://img.shields.io/github/downloads/Hacktix/Winch/total?style=for-the-badge)](https://github.com/DREDGE-Mods/Winch/releases)
-**Winch** is intended to be a Mod Loader for the game DREDGE. It is currently heavily under development and there are many improvements to come. As of right now, it's not considered ready for use and there will not be any documentation or instructions until this changes.
+Winch is a mod loader for Dredge made by Hacktix. This is a modified version for use with the Dredge mod manager.
-## Roadmap
+This repo has a few example mods as well:
-- [x] Code Execution when booting DREDGE
-- [x] Basic Configuration Options for Winch
-- [x] Loading separate Mod Assemblies at runtime
-- [x] Standardized Mod Format (Metadata JSON File)
-- [ ] Provide API to Mod Assemblies to interface with the game
-- [ ] Documentation & Examples
+### Disaster button
+
+Press the delete key to trigger a random world event.
+
+### Example Items
+
+An example of using Winch to add items to the game, adds a cod and diamonds from Minecraft.
+
+### Intro Skipper
+
+Self explanatory. Skips the intro cutscene.
diff --git a/Winch.Examples/DisasterButton/DisasterButton.csproj b/Winch.Examples/DisasterButton/DisasterButton.csproj
index 98a20ec7..9feac9f9 100644
--- a/Winch.Examples/DisasterButton/DisasterButton.csproj
+++ b/Winch.Examples/DisasterButton/DisasterButton.csproj
@@ -22,7 +22,7 @@
-
+
diff --git a/Winch.Examples/DisasterButton/mod_meta.json b/Winch.Examples/DisasterButton/mod_meta.json
index f5807ea4..68b3fcae 100644
--- a/Winch.Examples/DisasterButton/mod_meta.json
+++ b/Winch.Examples/DisasterButton/mod_meta.json
@@ -1,9 +1,12 @@
{
- "Version": "1.0",
- "ModAssembly": "DisasterButton.dll",
- "Entrypoint": "DisasterButton.Loader/Initialize",
- "DefaultConfig": {
- "DisasterButtonKey": "delete"
- },
- "MinWinchVersion": "alpha-1.0"
+ "Name": "Disaster Button",
+ "Author": "Hacktix",
+ "ModGUID": "hacktix.disasterbutton",
+ "Version": "1.0",
+ "ModAssembly": "DisasterButton.dll",
+ "Entrypoint": "DisasterButton.Loader/Initialize",
+ "DefaultConfig": {
+ "DisasterButtonKey": "delete"
+ },
+ "MinWinchVersion": "alpha-1.0"
}
\ No newline at end of file
diff --git a/Winch.Examples/ExampleItems/ExampleItems.csproj b/Winch.Examples/ExampleItems/ExampleItems.csproj
index 2777101e..9e7f3064 100644
--- a/Winch.Examples/ExampleItems/ExampleItems.csproj
+++ b/Winch.Examples/ExampleItems/ExampleItems.csproj
@@ -30,7 +30,7 @@
-
+
diff --git a/Winch.Examples/ExampleItems/mod_meta.json b/Winch.Examples/ExampleItems/mod_meta.json
index f5367c50..d586b4bd 100644
--- a/Winch.Examples/ExampleItems/mod_meta.json
+++ b/Winch.Examples/ExampleItems/mod_meta.json
@@ -1,6 +1,9 @@
{
- "Version": "1.0",
- "ModAssembly": "ExampleItems.dll",
- "Entrypoint": "ExampleItems.Loader/Initialize",
- "MinWinchVersion": "alpha-1.1"
+ "Name": "Example Items",
+ "Author": "Hacktix",
+ "ModGUID": "hacktix.exampleitems",
+ "Version": "1.0",
+ "ModAssembly": "ExampleItems.dll",
+ "Entrypoint": "ExampleItems.Loader/Initialize",
+ "MinWinchVersion": "alpha-1.1"
}
\ No newline at end of file
diff --git a/Winch.Examples/IntroSkipper/IntroSkipper.csproj b/Winch.Examples/IntroSkipper/IntroSkipper.csproj
index ac2e7905..aa3654b3 100644
--- a/Winch.Examples/IntroSkipper/IntroSkipper.csproj
+++ b/Winch.Examples/IntroSkipper/IntroSkipper.csproj
@@ -22,7 +22,7 @@
-
+
diff --git a/Winch.Examples/IntroSkipper/mod_meta.json b/Winch.Examples/IntroSkipper/mod_meta.json
index e376f791..d47d7fa6 100644
--- a/Winch.Examples/IntroSkipper/mod_meta.json
+++ b/Winch.Examples/IntroSkipper/mod_meta.json
@@ -1,6 +1,8 @@
{
- "Version": "1.0",
- "ModAssembly": "IntroSkipper.dll",
- "MinWinchVersion": "alpha-1.4",
- "ApplyPatches": true
+ "Name": "Intro Skipper",
+ "ModGUID": "hacktix.introskipper",
+ "Version": "1.0",
+ "ModAssembly": "IntroSkipper.dll",
+ "MinWinchVersion": "alpha-1.4",
+ "ApplyPatches": true
}
\ No newline at end of file
diff --git a/Winch/Core/Initializer.cs b/Winch/Core/Initializer.cs
index ddf7e7bb..9815ab5d 100644
--- a/Winch/Core/Initializer.cs
+++ b/Winch/Core/Initializer.cs
@@ -1,4 +1,5 @@
using CommandTerminal;
+using System;
using System.Net.Http;
using System.Text.RegularExpressions;
using UnityEngine;
@@ -15,20 +16,24 @@ internal static void Initialize()
{
WinchCore.Log.Debug("Initializer started.");
- InitializeAssetLoader();
+ try
+ {
+ InitializeAssetLoader();
- if(WinchConfig.GetProperty("EnableDeveloperConsole", false))
- InitializeDevConsole();
+ if (WinchConfig.GetProperty("EnableDeveloperConsole", false))
+ InitializeDevConsole();
- DredgeEvent.TriggerManagersLoaded();
+ DredgeEvent.TriggerManagersLoaded();
+ }
+ catch (Exception e)
+ {
+ WinchCore.Log.Error($"Failed to initialize mods {e}");
+ }
}
internal static void InitializePostUnityLoad()
{
InitializeVersionLabel();
-
- if (WinchConfig.GetProperty("CheckForUpdates", true))
- CheckForUpdate();
}
private static void InitializeAssetLoader()
@@ -57,29 +62,5 @@ private static void InitializeDevConsole()
term.AddComponent();
UnityEngine.Object.DontDestroyOnLoad(term);
}
-
- private static readonly HttpClient client = new HttpClient();
- private static async void CheckForUpdate()
- {
- string latestPath = "https://github.com/Hacktix/Winch/releases/latest";
- string content = await client.GetStringAsync(latestPath);
-
- Regex titleRegex = new Regex("(?<=)(.*)(?= · Hacktix)");
- Match match = titleRegex.Match(content);
-
- string latest = match.Value.Split(' ')[2];
-
- string updateAvailableString;
- if (VersionUtil.IsSameOrNewer(VersionUtil.GetComparableVersion(), latest))
- {
- updateAvailableString = $"Latest version installed";
- }
- else
- {
- updateAvailableString = $"Update {latest} available";
- }
-
- GameManager.Instance.BuildInfo.BuildNumber += $"\n{updateAvailableString}";
- }
}
}
diff --git a/Winch/Core/ModAssembly.cs b/Winch/Core/ModAssembly.cs
index db8a816b..9392d9ae 100644
--- a/Winch/Core/ModAssembly.cs
+++ b/Winch/Core/ModAssembly.cs
@@ -42,11 +42,16 @@ internal void LoadAssembly()
if(!File.Exists(assemblyPath))
throw new FileNotFoundException($"Could not find mod assembly '{assemblyPath}'");
- LoadedAssembly = Assembly.LoadFrom(assemblyPath);
-
CheckCompatibility();
+ LoadedAssembly = Assembly.LoadFrom(assemblyPath);
+
WinchCore.Log.Debug($"Loaded Assembly '{LoadedAssembly.GetName().Name}'.");
+
+ if (Metadata.ContainsKey("Preload"))
+ {
+ ProcessPreload();
+ }
}
internal void ExecuteAssembly()
@@ -74,12 +79,15 @@ internal void CheckCompatibility()
else if (!VersionUtil.ValidateVersion(Metadata["Version"].ToString()))
throw new FormatException("Mod Version has invalid format.");
+ if (!Metadata.ContainsKey("ModGUID"))
+ throw new MissingFieldException("No 'ModGUID' field found in Mod Metadata.");
+
if (!Metadata.ContainsKey("MinWinchVersion"))
WinchCore.Log.Warn($"No MinWinchVersion defined. Mod will load anyway, but version conflicts may occur!");
else
{
string minVer = Metadata["MinWinchVersion"].ToString();
- string winchVer = VersionUtil.GetComparableVersion();
+ string winchVer = VersionUtil.GetVersion();
if (!VersionUtil.ValidateVersion(minVer))
throw new FormatException("MinWinchVersion not in correct format.");
@@ -127,5 +135,23 @@ private void ProcessEntrypoint()
WinchCore.Log.Debug($"Invoking entrypoint {entrypointType}.{entrypointMethodName}...");
entrypoint.Invoke(null, new object[0]);
}
+
+ private void ProcessPreload()
+ {
+ string preloadSetting = Metadata["Preload"].ToString();
+ if (!preloadSetting.Contains("/"))
+ throw new ArgumentException("Malformed Preload in mod_meta.json");
+
+ string preloadTypeName = preloadSetting.Split('/')[0];
+ string preloadMethodName = preloadSetting.Split('/')[1];
+
+ Type preloaderType = LoadedAssembly?.GetType(preloadTypeName) ??
+ throw new EntryPointNotFoundException($"Could not find type {preloadTypeName} in Mod Assembly");
+ MethodInfo preloader = preloaderType.GetMethod(preloadMethodName) ??
+ throw new EntryPointNotFoundException($"Could not find method {preloadTypeName} in type {preloadTypeName} in Mod Assembly");
+
+ WinchCore.Log.Debug($"Invoking preloader {preloaderType}.{preloadMethodName}...");
+ preloader.Invoke(null, new object[0]);
+ }
}
}
diff --git a/Winch/Core/ModAssemblyLoader.cs b/Winch/Core/ModAssemblyLoader.cs
index 9db5c6bb..7d57273e 100644
--- a/Winch/Core/ModAssemblyLoader.cs
+++ b/Winch/Core/ModAssemblyLoader.cs
@@ -1,27 +1,40 @@
-using System;
+using Newtonsoft.Json;
+using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using Winch.Util;
namespace Winch.Core
{
class ModAssemblyLoader
{
- public static Dictionary RegisteredAssemblies = new Dictionary();
- public static List LoadedMods = new List();
- public static List ErrorMods = new List();
+ public static Dictionary EnabledModAssemblies = new();
+ private static Dictionary _installedAssemblies = new();
+ public static Dictionary EnabledMods = new();
+ public static List LoadedMods = new();
+ public static List ErrorMods = new();
internal static void LoadModAssemblies()
{
-
if (!Directory.Exists("Mods"))
- Directory.CreateDirectory("Mods");
+ {
+ Directory.CreateDirectory("Mods");
+ }
string[] modDirs = Directory.GetDirectories("Mods");
WinchCore.Log.Info($"Loading {modDirs.Length} mod assemblies...");
foreach (string modDir in modDirs)
- RegisterModAssembly(modDir);
- }
+ {
+ RegisterModAssembly(modDir);
+ }
+
+ GetEnabledMods();
+
+ EnabledModAssemblies = EnabledMods == null ? _installedAssemblies
+ : _installedAssemblies.Where(x => EnabledMods[(string)x.Value.Metadata["ModGUID"]])
+ .ToDictionary(x => x.Key, x => x.Value);
+ }
private static void RegisterModAssembly(string path)
{
@@ -31,7 +44,7 @@ private static void RegisterModAssembly(string path)
{
ModAssembly mod = ModAssembly.FromPath(path);
mod.LoadAssembly();
- RegisteredAssemblies.Add(modName, mod);
+ _installedAssemblies.Add(modName, mod);
}
catch(Exception ex)
{
@@ -42,7 +55,7 @@ private static void RegisterModAssembly(string path)
internal static void ExecuteModAssemblies()
{
- foreach (string modName in RegisteredAssemblies.Keys)
+ foreach (string modName in EnabledModAssemblies.Keys)
ExecuteModAssembly(modName);
}
@@ -51,7 +64,7 @@ internal static void ExecuteModAssembly(string modName, string? minVersion = nul
if (LoadedMods.Contains(modName) || ErrorMods.Contains(modName))
return;
- if (!RegisteredAssemblies.ContainsKey(modName))
+ if (!EnabledModAssemblies.ContainsKey(modName))
{
ErrorMods.Add(modName);
WinchCore.Log.Error($"Mod not loaded: {modName}");
@@ -60,13 +73,20 @@ internal static void ExecuteModAssembly(string modName, string? minVersion = nul
if(minVersion != null)
{
- if (!VersionUtil.IsSameOrNewer(RegisteredAssemblies[modName].Metadata["Version"].ToString(), minVersion))
+ if (!VersionUtil.IsSameOrNewer(EnabledModAssemblies[modName].Metadata["Version"].ToString(), minVersion))
throw new Exception($"Cannot satisfy minimum version constraint {minVersion} for {modName}");
}
+ var modGUID = (string)EnabledModAssemblies[modName].Metadata["ModGUID"];
+ if (!EnabledMods[modGUID])
+ {
+ WinchCore.Log.Info($"Mod '{modName}' disabled.");
+ return;
+ }
+
try
{
- RegisteredAssemblies[modName].ExecuteAssembly();
+ EnabledModAssemblies[modName].ExecuteAssembly();
LoadedMods.Add(modName);
WinchCore.Log.Info($"Successfully initialized {modName}.");
}
@@ -76,5 +96,37 @@ internal static void ExecuteModAssembly(string modName, string? minVersion = nul
WinchCore.Log.Error($"Error initializing {modName}: {ex}");
}
}
+
+ internal static void GetEnabledMods()
+ {
+ try
+ {
+ string modListPath = Path.Combine(Directory.GetCurrentDirectory(), "mod_list.json");
+
+ if (File.Exists(modListPath))
+ {
+ string modList = File.ReadAllText(modListPath);
+ EnabledMods = JsonConvert.DeserializeObject>(modList)
+ ?? throw new InvalidOperationException("Unable to parse mod_list.json file.");
+ }
+
+ foreach (string mod in _installedAssemblies.Keys)
+ {
+ string modGUID = (string)_installedAssemblies[mod].Metadata["ModGUID"];
+ if (!EnabledMods.ContainsKey(modGUID))
+ {
+ EnabledMods.Add(modGUID, true);
+ }
+ }
+
+ string serializedEnabledMods = JsonConvert.SerializeObject(EnabledMods, Formatting.Indented);
+ File.WriteAllText(modListPath, serializedEnabledMods);
+ }
+ catch (Exception ex)
+ {
+ WinchCore.Log.Error($"Unable to parse mod_list.json file: {ex}");
+ EnabledMods = null;
+ }
+ }
}
}
diff --git a/Winch/Core/WinchCore.cs b/Winch/Core/WinchCore.cs
index 200c4cff..6ba1d549 100644
--- a/Winch/Core/WinchCore.cs
+++ b/Winch/Core/WinchCore.cs
@@ -1,8 +1,11 @@
using HarmonyLib;
+using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
+using System.Reflection;
using System.Text.RegularExpressions;
+using UnityEngine.Profiling.Memory.Experimental;
using Winch.Config;
using Winch.Logging;
using Winch.Util;
@@ -13,9 +16,30 @@ public class WinchCore
{
public static Logger Log = new Logger();
- public static void Main()
+ public static Dictionary WinchModConfig = new();
+
+ public static string WinchInstallLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+
+ public static void Main()
{
- string version = VersionUtil.GetVersion();
+ try
+ {
+ string metaPath = Path.Combine(WinchInstallLocation, "mod_meta.json");
+ if (!File.Exists(metaPath))
+ {
+ throw new FileNotFoundException($"Missing mod_meta.json file for Winch at {metaPath}. Reinstall the mod.");
+ }
+
+ string metaText = File.ReadAllText(metaPath);
+ WinchModConfig = JsonConvert.DeserializeObject>(metaText)
+ ?? throw new InvalidOperationException($"Unable to parse mod_meta.json file at {metaPath}. Reinstall the mod.");
+ }
+ catch (Exception e)
+ {
+ Log.Error(e);
+ }
+
+ string version = VersionUtil.GetVersion();
Log.Info($"Winch {version} booting up...");
ModAssemblyLoader.LoadModAssemblies();
@@ -24,7 +48,7 @@ public static void Main()
Log.Debug("Created Harmony Instance 'com.dredge.winch'. Patching...");
harmony.PatchAll();
- foreach(ModAssembly modAssembly in ModAssemblyLoader.RegisteredAssemblies.Values)
+ foreach(ModAssembly modAssembly in ModAssemblyLoader.EnabledModAssemblies.Values)
{
try
{
diff --git a/Winch/Patches/GameLoadPatcher.cs b/Winch/Patches/GameLoadPatcher.cs
index 431ef804..954e5a3d 100644
--- a/Winch/Patches/GameLoadPatcher.cs
+++ b/Winch/Patches/GameLoadPatcher.cs
@@ -1,10 +1,27 @@
using HarmonyLib;
+using System.CodeDom.Compiler;
+using System.Threading;
+using UnityEngine.Localization.Settings;
using Winch.Core;
namespace Winch.Patches
{
+
+ ///
+ /// Was on Wait for game managers or whatever before but that gives this error:
+ ///
+ /*
+ Failed to initialize mods UnityEngine.UnityException: Internal_CreateGameObject can only be called from the main thread.
+ Constructors and field initializers will be executed from the loading thread when loading a scene.
+ Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.
+ at(wrapper managed-to-native) UnityEngine.GameObject.Internal_CreateGameObject(UnityEngine.GameObject, string)
+ at UnityEngine.GameObject..ctor()[0x00008] in :0
+ at Winch.Core.Initializer.InitializeAssetLoader() [0x00000] in C:\GitHub\Winch\Winch\Core\Initializer.cs:41
+ at Winch.Core.Initializer.Initialize() [0x0000f] in C:\GitHub\Winch\Winch\Core\Initializer.cs:21
+ */
+ ///
[HarmonyPatch(typeof(GameManager))]
- [HarmonyPatch(nameof(GameManager.WaitForAllAsyncManagers))]
+ [HarmonyPatch(nameof(GameManager.Start))]
class GameLoadPatcher
{
static void Postfix()
diff --git a/Winch/Util/VersionUtil.cs b/Winch/Util/VersionUtil.cs
index 3679771b..fe545751 100644
--- a/Winch/Util/VersionUtil.cs
+++ b/Winch/Util/VersionUtil.cs
@@ -1,30 +1,18 @@
using System;
using System.Linq;
-using System.Reflection;
using System.Text.RegularExpressions;
+using Winch.Core;
namespace Winch.Util
{
- internal class VersionUtil
+ internal class VersionUtil
{
- private static readonly string Prefix = "alpha";
- private static readonly string[] ValidPrefixes = new string[] { "alpha", "beta", "" };
- private static Regex VersionRegex = new Regex(@"(?:([a-z]+)-)?(\d+)\.(\d+)", RegexOptions.Compiled);
+ private static readonly string[] ValidPrefixes = new string[] { "alpha", "" };
+ private static Regex VersionRegex = new Regex(@"(?:([a-z]+)-)?(\d+)\.(\d+)(?:\.(\d+))?", RegexOptions.Compiled);
internal static string GetVersion()
{
- string versionString = Assembly.GetExecutingAssembly().GetName().Version.ToString();
- string[] parts = versionString.Split('.');
-
- return $"{Prefix}-{parts[0]}.{parts[1]} | build {parts[2]}";
- }
-
- internal static string GetComparableVersion()
- {
- string versionString = Assembly.GetExecutingAssembly().GetName().Version.ToString();
- string[] parts = versionString.Split('.');
-
- return $"{Prefix}-{parts[0]}.{parts[1]}";
+ return WinchCore.WinchModConfig["Version"].ToString();
}
internal static bool ValidateVersion(string version)
@@ -45,11 +33,13 @@ internal static bool IsSameOrNewer(string installedVersion, string minVersion)
throw new ArgumentException($"Invalid version comparison: {installedVersion} - {minVersion}");
GroupCollection installedParts = VersionRegex.Match(installedVersion).Groups;
- GroupCollection minParts = VersionRegex.Match(minVersion).Groups;
+ GroupCollection minParts = VersionRegex.Match(minVersion).Groups;
int prefixIndexDiff = Array.IndexOf(ValidPrefixes, installedParts[1].Value) - Array.IndexOf(ValidPrefixes, minParts[1].Value);
int majorDiff = int.Parse(installedParts[2].Value) - int.Parse(minParts[2].Value);
int minorDiff = int.Parse(installedParts[3].Value) - int.Parse(minParts[3].Value);
+ // Old versions had no patch diff in the version
+ int patchDiff = string.IsNullOrEmpty(minParts[4].Value) ? 0 : int.Parse(installedParts[4].Value) - int.Parse(minParts[4].Value);
if (prefixIndexDiff < 0) return false;
else if(prefixIndexDiff > 0) return true;
@@ -59,8 +49,13 @@ internal static bool IsSameOrNewer(string installedVersion, string minVersion)
else if(majorDiff > 0) return true;
else
{
- if (minorDiff < 0) return false;
- else return true;
+ if (minorDiff < 0) return false;
+ else if (minorDiff > 0) return true;
+ else
+ {
+ if (patchDiff < 0) return false;
+ else return true;
+ }
}
}
}
diff --git a/Winch/Winch.csproj b/Winch/Winch.csproj
index a5036629..f6c5d406 100644
--- a/Winch/Winch.csproj
+++ b/Winch/Winch.csproj
@@ -7,17 +7,11 @@
11
false
enable
-
-
-
- none
- ./bin
- 1.4.*
- False
+ Winch.nuspec
-
+
@@ -37,4 +31,22 @@
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Winch/Winch.nuspec b/Winch/Winch.nuspec
new file mode 100644
index 00000000..f507f1e8
--- /dev/null
+++ b/Winch/Winch.nuspec
@@ -0,0 +1,18 @@
+
+
+
+ false
+
+ $version$
+
+ Winch
+ Winch
+ Hacktix, xen-42
+ xen-42
+ A Harmony-based mod loader for the game Dredge.
+ MIT
+
+
+
+
+
diff --git a/Winch/doorstop_config.ini b/Winch/doorstop_config.ini
new file mode 100644
index 00000000..5e0362c5
--- /dev/null
+++ b/Winch/doorstop_config.ini
@@ -0,0 +1,35 @@
+# General Doorstop settings
+[UnityDoorstop]
+# Specifies whether assembly executing is enabled
+enabled=true
+# Specifies the path (absolute, or relative to the game's exe) to the DLL/EXE that should be executed by Doorstop
+targetAssembly=Winch.dll
+# Specifies whether Unity's output log should be redirected to \output_log.txt
+redirectOutputLog=false
+# If enabled, DOORSTOP_DISABLE env var value is ignored
+# USE THIS ONLY WHEN ASKED TO OR YOU KNOW WHAT THIS MEANS
+ignoreDisableSwitch=true
+# Overrides default Mono DLL search path
+# Sometimes it is needed to instruct Mono to seek its assemblies from a different path
+# (e.g. mscorlib is stripped in original game)
+# This option causes Mono to seek mscorlib and core libraries from a different folder before Managed
+# Original Managed folder is added as a secondary folder in the search path
+dllSearchPathOverride=
+
+
+# Settings related to bootstrapping a custom Mono runtime
+# Do not use this in managed games!
+# These options are intended running custom mono in IL2CPP games!
+[MonoBackend]
+# Path to main mono.dll runtime library
+runtimeLib=
+# Path to mono config/etc directory
+configDir=
+# Path to core managed assemblies (mscorlib et al.) directory
+corlibDir=
+# Specifies whether the mono soft debugger is enabled
+debugEnabled=false
+# Specifies whether the mono soft debugger should suspend the process and wait for the remote debugger
+debugSuspend=false
+# Specifies the listening address the soft debugger
+debugAddress=127.0.0.1:10000
\ No newline at end of file
diff --git a/Winch/lib/0Harmony.dll b/Winch/lib/0Harmony.dll
new file mode 100644
index 00000000..e1825353
Binary files /dev/null and b/Winch/lib/0Harmony.dll differ
diff --git a/Winch/lib/winhttp.dll b/Winch/lib/winhttp.dll
new file mode 100644
index 00000000..5a516e5b
Binary files /dev/null and b/Winch/lib/winhttp.dll differ
diff --git a/Winch/mod_meta.json b/Winch/mod_meta.json
new file mode 100644
index 00000000..3366cd4e
--- /dev/null
+++ b/Winch/mod_meta.json
@@ -0,0 +1,6 @@
+{
+ "Name": "Winch",
+ "Author": "Hacktix",
+ "ModGUID": "hacktix.winch",
+ "Version": "0.3.0"
+}