Skip to content

Commit

Permalink
feat: support moonlight mod loading
Browse files Browse the repository at this point in the history
  • Loading branch information
MeguminSama committed Dec 6, 2023
1 parent b3abe33 commit 15db21b
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
edition = "2021"
name = "modhook"
version = "1.0.1"
version = "1.0.2"

[lib]
crate-type = ["cdylib"]
Expand Down
122 changes: 103 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@

An in-memory mod loader for Discord.

# Note about 64-bit vs 32-bit Discord.
# Note about 64-bit & 32-bit Discord.

Discord recently released x64 builds of all their clients.
For this program to work, it must be compiled for the same architecture that your Discord runs on.
This modloader currently only supports 64-bit Discord. If you aren't currently using the 64-bit version of Discord, make sure you download the 64-bit version from the Discord website.

If you go into account settings and scroll to the bottom of the sidebar, you should see `Host x.x.xxx x64` or `Host x.x.xxx x86`.

Make sure to get the right build for this architecture.
You can check your architecture in Discord settings. Scroll to the bottom of the sidebar and look at "Host".
If it's 64-bit, it'll say x64.

# Usage

Expand All @@ -19,28 +17,114 @@ Make sure this directory doesn't change, as any shortcuts you make need to point
If you right-click and drag `modhook.exe`, when you release the mouse button there will be an option to create a shortcut.
Alternatively, you can always make a shortcut manually.

## Commandline Arguments
If you are using a shortcut, the "Start In" directory must be the folder the ModHook executable is in.

## Example Usage: Vencord

As an example of what I use...
Change the `-d` flag if you want to use a different Discord branch.

```
"C:\Users\megu\Workspace\Discord\ModHook\ModHook-RS\target\release\modhook.exe" -d "C:\Users\megu\AppData\Local\Discord" -m "c:\users\megu\workspace\discord\vencord\dist\patcher.js"
"C:\path\to\modhook.exe"
-d "C:\Users\megu\AppData\Local\Discord"
-m "c:\path\to\vencord\dist\patcher.js"
```

And here's the documentation of all the flags...
## Example Usage: Moonlight

```
C:\path\to\modhook.exe
-d "c:\users\megu\appdata\local\discord" # This is the path to the folder Discord is installed to.
-m "c:\users\megu\downloads\vencord\dist\patcher.js" # This is the path to your mod's entrypoint file.
-f "_app.asar" # This isn't needed if you're using Vencord, Replugged, or any mod that uses "_app.asar" or "app.orig.asar"
# Below are optional, and probably not needed.
-t "c:\users\megu\downloads\vencord\dist\patcher.js" # This is the query used to see if the mod is loaded. This defaults to the value of `-m`
-c "MyAlternativeProfile" # A unique name that lets you have multiple instances of discord with unique profiles
-a "c:\users\megu\downloads\ModHook\app.asar" # The path to the custom app.asar loader.
-h # This just shows a help command in case you get lost.
"C:\path\to\modhook.exe"
-d "C:\Users\megu\AppData\Local\Discord"
-m "c:\path\to\moonlight\dist\injector.js"
```

## All configuration flags

Names prefixed with a \* are required.

| Flag | Name | Purpose | Example |
| ----------- | ---------------- | -------------------------------------------------------- | ---------------------------------------- |
| -d | \*Directory | The path to the Discord AppData folder | -d "c:\Users\megu\AppData\Local\Discord" |
| -m | \*Mod Entrypoint | The path to the Mod Entrypoint | -m "c:\path\to\vencord\dist\patcher.js" |
| --moonlight | Moonlight | Support for the Moonlight Mod | --moonlight |
| -f | ASAR Filename | The name of the _modded_ ASAR | -f "\_app.asar" |
| -t | Toggle Query | Toggle asar redirection when this query is hit | -t "\injector.js" |
| -a | Custom ASAR | Use a custom ASAR instead of the modhook-provided one | -a c:\path\to\my_app.asar |
| -c | Custom UserDir | Use a custom user directory. Helpful for multi-instances | -c "my-custom-userdir" |
| -h | Help | Shows the Help command | -h |

### -d (\*Directory)

This is the path to your Discord AppData folder.

Usage: `-d <path>`

Common values are:

- `C:\Users\<username>\AppData\Local\Discord`
- `C:\Users\<username>\AppData\Local\DiscordPTB`
- `C:\Users\<username>\AppData\Local\DiscordCanary`
- `C:\Users\<username>\AppData\Local\DiscordDevelopment`

### -m (\*Mod Entrypoint)

This is the path to the entrypoint of the Discord mod.

Usage: `-m <path>`

Common values are:

- `C:\path\to\vencord\dist\patcher.js`
- `C:\path\to\moonlight\dist\injector.js`

### --moonlight (Moonlight)

Use this flag if you're loading Moonlight.

Moonlight's entrypoint works slightly differently to most, so this is needed to load it.

Usage: `--moonlight`

### -f (ASAR Filename)

The name of the modded ASAR.

Many mods rename the original ASAR to `_app.asar` or `app.orig.asar` or similar.
If your mod does not use one of these, you need to provide it with this flag.

Usage: `-f <asar name>`

### -t (Toggle Query)

The query to use to toggle ASAR redirection.

ModHook redirects all calls to `app.asar/index.js` to a custom asar that load the mod.

Once the mod is loaded, we want to disable this redirection so that Discord can load.

This is only needed if for some reason, the query should be something different to the mod entrypoint (-m).

Usage: `-t c:\my\custom\query`

### -a (Custom ASAR)

Custom ASAR to laod, instead of the default ModHook one.

If you want to use your own ASAR instead of the ModHook one, use this flag.

Usage: `-a c:\path\to\custom.asar`

### -c (Custom User Directory)

Allows you to have a custom User Directory for your instance.

This means that instead of being in `%AppData%\Discord`, it'll be in `%AppData%\DiscordModHook\AppData\<custom user dir>`.

This allows two things:

- Each custom directory will have it's own profile, so you can have multiple accounts on the same branch.
- This means that you will have to log in for each custom User Directory you use.
- Each directory stores all the electron cache - this makes it safe to run multiple instances of the same branch.

# Setup

You'll need rust...
Expand Down
12 changes: 10 additions & 2 deletions asar/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
/// BEGIN MODHOOK INFO ///
const CUSTOM_DATA_DIR = process.env.MODHOOK_CUSTOM_DATA_DIR;
const MOD_ENTRYPOINT = process.env.MODHOOK_MOD_ENTRYPOINT;
const IS_MOONLIGHT = process.env.MODHOOK_IS_MOONLIGHT;
/// END MODHOOK INFO ///

if (CUSTOM_DATA_DIR) {
const { app } = require("electron");
const customAppDir = app.getPath("appData") + "\\DiscordModHook\\AppData\\" + CUSTOM_DATA_DIR;
const customAppDir =
app.getPath("appData") + "\\DiscordModHook\\AppData\\" + CUSTOM_DATA_DIR;
const _setPath = app.setPath;

app.setPath = function (name, path) {
Expand All @@ -19,4 +21,10 @@ if (CUSTOM_DATA_DIR) {
app.setPath("userData", customAppDir);
}

require(MOD_ENTRYPOINT);
if (IS_MOONLIGHT) {
require(MOD_ENTRYPOINT).inject(
require("path").resolve(__dirname, "..\\_app.asar")
);
} else {
require(MOD_ENTRYPOINT);
}
15 changes: 15 additions & 0 deletions src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ pub struct Environment {
///
/// e.g. "_app.asar"
pub modded_asar_filename: Option<String>,

/// Whether or not the mod is the moonlight mod.
///
/// Moonlight uses `require(entrypoint).inject(asarPath);`
/// instead of the usual `require(entrypoint);`
pub is_moonlight: bool,
}

#[allow(dead_code)]
Expand All @@ -43,6 +49,7 @@ impl Environment {
toggle_query: None,
custom_data_dir: None,
modded_asar_filename: None,
is_moonlight: false,
};

if let Ok(path) = std::env::var("MODHOOK_ASAR_PATH") {
Expand All @@ -68,6 +75,10 @@ impl Environment {
env.modded_asar_filename = Some("_app.asar".to_string());
}

if let Ok(is_moonlight) = std::env::var("MODHOOK_IS_MOONLIGHT") {
env.is_moonlight = is_moonlight == "true";
}

env
}

Expand Down Expand Up @@ -99,5 +110,9 @@ impl Environment {
// Currently supported mods:
// - Vencord
std::env::set_var("DISABLE_UPDATER_AUTO_PATCHING", "true");

if self.is_moonlight {
std::env::set_var("MODHOOK_IS_MOONLIGHT", "true");
}
}
}
8 changes: 8 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ pub struct Args {
/// Example: --asar-path "c:\users\megu\vencord\app.asar"
#[arg(short, long, verbatim_doc_comment)]
pub asar_path: Option<String>,

/// Whether or not the mod is the moonlight mod.
/// Example: --moonlight
/// Moonlight uses `require(entrypoint).inject(asarPath);`
/// instead of the usual `require(entrypoint);`
#[arg(value_enum, long = "moonlight", verbatim_doc_comment)]
pub is_moonlight: bool,
}

fn main() {
Expand All @@ -77,6 +84,7 @@ fn main() {
toggle_query: args.toggle_query,
custom_data_dir: args.custom_data_dir,
modded_asar_filename: args.modded_asar_filename,
is_moonlight: args.is_moonlight,
};

unsafe {
Expand Down

0 comments on commit 15db21b

Please sign in to comment.