Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 13, 2025

Problem

Users needed to configure MonoMod switches (like DMDDebug and DMDDumpTo for debug assembly dumping) but had to resort to reflection since MonoMod.Switches is internalized in Harmony:

// Users had to write this complex reflection code:
var t = AccessTools.TypeByName("MonoMod.Switches");
var m = AccessTools.Method(t, "SetSwitchValue");
m.Invoke(null, ["DMDDebug", true]);
m.Invoke(null, ["DMDDumpTo", "Path\\To\\Dir\\Where\\Should\\Go"]);
// Patch here
HarmonyInstance.PatchWhatever();
// Deactivate Debug Assembly Dump
m.Invoke(null, ["DMDDebug", false]);
m.Invoke(null, ["DMDDumpTo", ""]);

This approach is brittle, verbose, and not discoverable through IntelliSense.

Solution

Added a clean public API to the Harmony class with four new static methods:

  • SetSwitch(string name, object value) - Sets a MonoMod switch value (e.g., bool, string)
  • ClearSwitch(string name) - Clears a switch value
  • TryGetSwitch(string name, out object value) - Retrieves a switch value
  • TryIsSwitchEnabled(string name, out bool isEnabled) - Checks if a switch is enabled

All methods include XML documentation for IntelliSense support.

Usage

Now users can write clean, discoverable code:

// Activate Debug Assembly Dump
Harmony.SetSwitch("DMDDebug", true);
Harmony.SetSwitch("DMDDumpTo", "Path\\To\\Dir\\Where\\Should\\Go");
// Patch here
HarmonyInstance.PatchWhatever();
// Deactivate Debug Assembly Dump
Harmony.SetSwitch("DMDDebug", false);
Harmony.SetSwitch("DMDDumpTo", "");

Testing

Added comprehensive test coverage in TestSwitches.cs with 6 unit tests covering:

  • Setting and retrieving boolean/string switch values
  • Clearing switch values
  • Checking switch enabled state
  • Handling non-existent switches

All tests pass successfully.

Implementation

The implementation uses direct calls to the MonoMod.Switches API. Since Harmony merges MonoMod into itself during the build process, the internal MonoMod.Switches class is accessible within the same assembly. The methods are simple expression-bodied wrappers (e.g., => MonoMod.Switches.SetSwitchValue(name, value)) that provide a clean, performant interface without reflection overhead.

Original prompt

Some user wrote this code telling me that they had to use reflections since MonoMod is internalized. Add a nice public API to Harmony that allows to set the switch values (using strings) and that internally uses MonoMod.Switches.

// Activate Debug Assembly Dump
var t = AccessTools.TypeByName("MonoMod.Switches");
var m = AccessTools.Method(t, "SetSwitchValue");
m.Invoke(null, ["DMDDebug", true]);
m.Invoke(null, ["DMDDumpTo", "Path\To\Dir\Where\Should\Go"]);
// Patch here
HarmonyInstance.PatchWhatever();
// Deactivate Debug Assembly Dump
m.Invoke(null, ["DMDDebug", false]);
m.Invoke(null, ["DMDDumpTo", ""]);


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Co-authored-by: pardeike <853584+pardeike@users.noreply.github.com>
Copilot AI changed the title [WIP] Add public API to Harmony for setting switch values Add public API for MonoMod switches configuration Oct 13, 2025
Copilot AI requested a review from pardeike October 13, 2025 21:33
@github-actions
Copy link

github-actions bot commented Oct 13, 2025

Test Results

   120 files     120 suites   9m 7s ⏱️
   280 tests    277 ✅   3 💤 0 ❌
33 344 runs  32 792 ✅ 552 💤 0 ❌

Results for commit 5157511.

♻️ This comment has been updated with latest results.

@pardeike
Copy link
Owner

@copilot you used reflection in the harmony code but I think you can simply use their api directly

Co-authored-by: pardeike <853584+pardeike@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Oct 13, 2025

@copilot you used reflection in the harmony code but I think you can simply use their api directly

You're absolutely right! Changed to use MonoMod.Switches API directly instead of reflection. The methods are now simple expression-bodied wrappers: => MonoMod.Switches.SetSwitchValue(name, value). Much cleaner and more performant. All tests still pass. (commit: {{commit_hash}})

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • google.com
    • Triggering command: /usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/Harmony/Harmony/HarmonyTests/bin/Debug/net8.0/HarmonyTests.runtimeconfig.json --depsfile /home/REDACTED/work/Harmony/Harmony/HarmonyTests/bin/Debug/net8.0/HarmonyTests.deps.json /home/REDACTED/work/Harmony/Harmony/HarmonyTests/bin/Debug/net8.0/testhost.dll --port 36449 --endpoint 127.0.0.1:036449 --role client --parentprocessid 4304 --telemetryoptedin false (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@pardeike pardeike marked this pull request as ready for review October 13, 2025 22:49
@pardeike pardeike merged commit 29c8fd8 into master Oct 13, 2025
40 of 41 checks passed
@pardeike pardeike deleted the copilot/add-harmony-api-for-switches branch October 13, 2025 22:50
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting

Comment on lines +337 to +342
/// <summary>Sets a MonoMod switch value (e.g., "DMDDebug", "DMDDumpTo")</summary>
/// <param name="name">The switch name</param>
/// <param name="value">The value to set (bool, string, etc.)</param>
///
public static void SetSwitch(string name, object value)
=> MonoMod.Switches.SetSwitchValue(name, value);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 Badge Use correct namespace for MonoMod switches

The new wrapper methods reference MonoMod.Switches.*, but the Switches type is declared under MonoMod.Utils in MonoMod.Core. Since Harmony.cs does not import MonoMod.Utils, these calls fail to compile (MonoMod has no direct Switches type). All four methods added in this block will generate the same compile-time error, blocking every build that includes this file.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants