Skip to content

Commit

Permalink
better install/injection docs, and switch to recommending sheltupdate
Browse files Browse the repository at this point in the history
  • Loading branch information
yellowsink committed Nov 30, 2024
1 parent f9028b5 commit d0825c8
Show file tree
Hide file tree
Showing 4 changed files with 268 additions and 69 deletions.
6 changes: 4 additions & 2 deletions packages/shelter-docs/docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import UnoCSS from "unocss/vite";

// https://vitepress.dev/reference/site-config
export default defineConfig({
title: "shelter docs",
description: "Documentation for the shelter client mod",
title: "shelter",
description: "an attempt to prepare for the worst",
vite: {
plugins: [UnoCSS(fileURLToPath(new URL("./unocss.config.ts", import.meta.url)))],
optimizeDeps: { exclude: ["@vueuse/integrations"] },
},
head: [["link", { rel: "icon", type: "image/svg+xml", href: "/logo.svg" }]],
themeConfig: {
// https://vitepress.dev/reference/default-theme-config
logo: "https://github.com/uwu/shelter/raw/main/packages/shelter-assets/svg/banner.svg",
Expand All @@ -36,6 +37,7 @@ export default defineConfig({
{ text: "Ideals", link: "/guides/ideals" },
{ text: "Background", link: "/guides/background" },
{ text: "Injector Integration", link: "/guides/injectors" },
{ text: "How Injectors Work", link: "/guides/injection" },
],
},
],
Expand Down
158 changes: 158 additions & 0 deletions packages/shelter-docs/docs/guides/injection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# How shelter Injection Works

This page explains *how* shelter injection methods work.

The requirements to successfully inject shelter are simply that you run it in the web context AS SOON AS POSSIBLE -
before any of Discord's code loads, and that you remove the Content Security Policy from the page.
This is necessary to ensure we can find all flux stores and react.

## Desktop: sheltupdate

sheltupdate is the current main injection mechanism for shelter. It works by proxying Discord's module update servers.

When Discord asks for the module version registry, we tell it that there's a new version of `discord_desktop_core`
(versus stock, if its already installed it won't need to redownload), and then serve it a patched version that has the
shelter injector code put into it.

You install sheltupdate by editing your `settings.json` file as so:
```json
{
"IS_MAXIMIZED": true,
"IS_MINIMIZED": false,
"MIN_HEIGHT": 500,
"MIN_WIDTH": 940,
"UPDATE_ENDPOINT": "https://inject.shelter.uwu.network/shelter",
"NEW_UPDATE_ENDPOINT": "https://inject.shelter.uwu.network/shelter/"
}
```

and uninstall it by just removing those lines.

You can choose between many branches, e.g. `/shelter`, `/vencord+reactdevtools`, any combo
of the branches listed in the [sheltupdate readme](https://github.com/uwu/sheltupdate) will work.

Note that this introduces a dependency on a server, https://inject.shelter.uwu.network, but you can self host, and we
do endeavour to keep the uptime and reliability of this service as good as we can possibly manage.
If this server is down, your app may not open.

The paths of these settings.json files are:

| OS | Path |
|-----------------|------------------------------------------------------------------|
| Windows | `%AppData%\discord\settings.json` |
| macOS | `~/Library/Application Support/discord/settings.json` |
| Linux | `~/.config/discord/settings.json` |
| Linux (Flatpak) | `~/.var/app/com.discordapp.Discord/config/discord/settings.json` |

The `index.js` and `preload.js` files patched into `discord_desktop_core` are reused from those in the
traditional installer, but with a few tweaks:
- preload injection is handled by sheltupdate for you (but using exactly the same mechanism)
- chainloading is handled by sheltupdate for you (and uses a different mechanism)
* don't bother chainloading in preload, as sheltupdate also does that for you (using the same mechanism)
- you are running AFTER `app.whenReady()`, which is fine for shelter but not some other mods
- you need not bother with host update resistance

## Desktop: traditional

The traditional injection method works by manually replacing the `app.asar` file that is the electron entrypoint for
the application.

This method of injection is a real classic of client mods, and works well, but has many drawbacks:
- Impossible to resist host updates on macOS
- Resisting host updates on Windows is complex and often unreliable
- Resisting host updates on Linux is possible only via package management hooks
- Requires root access on Linux, or "application management" permissions on macOS
- Installs system-wide on Linux or macOS instead of being user-specific.
* Note that unlike many other mods, shelter did not rely on user-specific files for this injection,
whereas mods like vencord, kernel, etc. would straight up break discord for other users. That's fun.
shelter just made it so that all users would have shelter.

Instead of a `resources` directory that looks like this:

```
πŸ— resources
β”œβ”€β”€ πŸ—‹ app.asar
β”œβ”€β”€ πŸ— bootstrap
└── πŸ—‹ build_info.json
```

it looks like this:
```
πŸ— resources
β”œβ”€β”€ πŸ— app
β”‚ β”œβ”€β”€ πŸ—‹ index.js
β”‚ β”œβ”€β”€ πŸ—‹ preload.js
β”‚ └── πŸ—‹ package.json
β”œβ”€β”€ πŸ— bootstrap
β”œβ”€β”€ πŸ—‹ build_info.json
└── πŸ—‹ original.asar
```

where `index.js` will run first, inject `preload.js`, and then chainload `original.asar`.

The paths of these resources folders are:

| OS | Path |
|-----------------|--------------------------------------------------------------------------------------------|
| Windows | `%LocalAppData%\discord\resources` |
| macOS | `/Applications/Discord.app/Contents/Resources` |
| Linux | `/opt/discord/resources` |
| Linux | `/usr/share/discord/resources` |
| Linux | `/usr/lib/discord/resources` |
| Linux (Flatpak) | `/var/lib/flatpak/app/com.discordapp.Discord/x86_64/stable/active/files/discord/resources` |

The steps followed for the `index.js` generally look like this:
- Either fetch shelter from the network, or from disk
- Setup an electron IPC endpoint to make it available to preload
- Remove content security policy
- Make sure no other client mods can come along later and mess with that patch
- If we're running on Windows, and we care enough, put complicated patches in place to attempt to
persist ourselves after a host update
- (optional) force devtools on, because that's probably more useful to our users than not
- Modify `electron.BrowserWindow` using CommonJS bullshit hacks to get Discord's preload, and then replace it with ours
- Setup an electron IPC endpoint to send Discord's stock preload to our custom preload
- Find and chainload `../original.asar`

Then this `preload.js` we injected needs to:
- Use IPC to ask the node side for the shelter JS, and then execute that in the webFrame
- Use IPC to ask the node side for the original Discord preload, then chainload it.

## Desktop: `alpm-hooks`

On Linux, some package managers support scripts that run upon certain operations.

We have a set of scripts that can install, uninstall, etc. shelter automatically, and provide hooks for Arch Linux's
pacman to automatically reinject shelter after a host update.

These inject the traditional installer automatically, to provide host update resistance.

They are provided by [the `shelter` AUR package](https://aur.archlinux.org/packages/shelter).

## Desktop: Kernel

[Kernel](https://kernel.fish) is a generic electron mod.

Once setup, you can install the [shelter loader package](https://github.com/uwu/shelter/tree/main/injectors/kernel),
which works almost identically to the traditional installer,
but kernel manages loading our preload and chainloading the original preload for us.

## Browser: MV2

On the browser, we can inject shelter from a content script.

We store shelter in extension storage, and at page load, grab it out of extension storage and run it.

Then, we fetch shelter, and if its different, store it and reload.
This usually happens very quickly and isn't noticeable, but is necessary as if we fetch then run, we're too late.

Finally, we use a background script to remove CSP.

## Browser: MV3

This works similarly but subtly differently to the MV2 injector.

First, we use declarative net request to remove CSP as necessary.

Then, we use a content script to inject a script tag to the page that does the actual injection.

That then uses localStorage pretty much identically to the MV2 content script.
172 changes: 105 additions & 67 deletions packages/shelter-docs/docs/install.md
Original file line number Diff line number Diff line change
@@ -1,95 +1,133 @@
<script setup>
import Pill from "./components/Pill.vue";
</script>
---
outline: [2, 3]
---

# Install shelter

There are multiple ways to install shelter, depending on which platform you are installing on.

Click the links in the sidebar to skip to the relevant section.

---

Watch this space! We are currently working on an improved desktop injection method that will:
- be host-update resistant on all platforms (currently not supported on non-Arch Linuxes and macOS),
- be simpler,
- not require root access on Linux,
- allow for running alongside other mods, such as Vencord.

Once this is complete, it will be added into the installer, which should streamline the process.
Information on the technical details of injection can be found on [this page](/guides/injection),
but this page will simply include instructions relevant to the end user to get shelter up and running.

## Desktop

There are multiple ways to install shelter on desktop. We will try to guide you to the best one for you.

If you are using [Kernel](https://kernel.fish), follow these instructions:
::: details Kernel installation
::: details I am using [Kernel](https://kernel.fish)
We will not cover how to install Kernel itself. We expect you to know how Kernel works if you are using it.

Install the kernel package from [here](https://github.com/uwu/shelter/tree/main/injectors/kernel).
:::

If you are using Arch Linux, follow these instructions:
::: details Arch Linux installation
Install the [`shelter` AUR package](https://aur.archlinux.org/packages/shelter).
This method is resistant to being overwritten during updates.
:::
Assuming you are not using Kernel,
[download the shelter installer](https://github.com/uwu/shelter-installer/releases/latest) and run that.

Otherwise, [download the shelter installer](https://github.com/uwu/shelter-installer/releases/latest),
and run that.
This method is resistant to being overwritten during updates on Windows, but not on macOS or Linux.

You will need to run the installer as root if you are on Linux, which will not be possible for users on Wayland,
so those users may need to follow the manual installation process, instead.

If you encounter issues with Discord (e.g. not starting) after using the installer,
you may have to do a manual installation instead.

::: details Manual Installation

If you cannot use the shelter installer for any reason, here are the steps to do exactly what it does, yourself.

The end result will be identical to that of running the installer, but you have to work for it.

1. Download the shelter repository [here](https://github.com/uwu/shelter/archive/refs/heads/main.zip)
2. Locate your Discord `resources` folder.
- On Windows, `%LocalAppData%/discord/resources`
- On Linux, locations include `/opt/discord/resources` and `/usr/share/discord/resources`
- On macOS, `/Applications/Discord.app/Contents/resources`
3. From the shelter repo, copy the `injectors/desktop/app` folder into `resources/`
4. Close Discord if it is running, and rename `app.asar` to `original.asar`
The folder should look something like this when you are done:
```
πŸ— resources
β”œβ”€β”€ πŸ— app
β”‚ β”œβ”€β”€ πŸ—‹ index.js
β”‚ β”œβ”€β”€ πŸ—‹ preload.js
β”‚ └── πŸ—‹ package.json
β”œβ”€β”€ πŸ— bootstrap
β”œβ”€β”€ πŸ—‹ build_info.json
└── πŸ—‹ original.asar
```
- You may like to take this opportunity to replace the stock asar with [OpenAsar](https://openasar.dev).
It will install shelter using an injection method called sheltupdate.
This works on all platforms and channels, does not require root access, and should never break due to a discord update.

:::
![Screenshot of the shelter installer](https://i.uwu.network/61318cfbc.png)

## Chromium Browsers
If you previously installed shelter on desktop, you will have the legacy injector installed,
and the installer will remove it for you as part of the update process, if it is able to.

Do not follow these instructions if you are using Microsoft Edge, [follow this instead](#microsoft-edge).
In the very unlikely event that you encounter issues with Discord (e.g. not starting) after using the installer,
you may have to do a manual installation instead, please see [this page](/guides/injection) for more info.

As these extensions fetch the latest build of shelter, it is not allowed on the Chrome Webstore (we got kicked off!),
and as there is no easy way to comply with this, you will have to manually install the extension.
If the installer is unable to remove your existing legacy injector installation,
it may ask you to do a manual uninstall. The instructions for this are [below](#manual-legacy-uninstall).

1. Download the latest version of the extension [here](https://github.com/uwu/shelter/releases?q=mv3&expanded=true)
2. Unpack the zip to a folder somewhere safe. If you delete this folder, the extension will be uninstalled.
3. Head to [chrome://extensions](chrome://extensions), and enable Developer Mode in the top-right corner
4. Click "Load Unpacked Extension", and select the folder you unpacked the zip into
### Switching Branches

sheltupdate supports multiple "branches", which is the mods that are injected into Discord. These are currently:

| Branch Name | Description |
|-----------------|-------------------------------------------------------------------------------------------------------|
| `shelter` | Injects shelter |
| `vencord` | Injects Vencord; do not expect support from the Vencord authors while using this |
| `betterdiscord` | Injects BetterDiscord |
| `reactdevtools` | Adds the [React Developer Tools](https://github.com/facebook/react/tree/main/packages/react-devtools) |

In the future, we plan to add a UI to toggle these on and off, either within the app or installer.
Watch this space for information on that, when it becomes available. For now, you'll need to do it yourself.

You can install multiple branches by concatenating the names with `+`s,
like: `shelter+vencord`, `vencord+shelter+reactdevtools`.

To change these branches, you need to find your `settings.json` file,
and modify the `UPDATE_ENDPOINT` and `NEW_UPDATE_ENDPOINT` keys:

| OS | Path |
|-----------------|------------------------------------------------------------------|
| Windows | `%AppData%\discord\settings.json` |
| macOS | `~/Library/Application Support/discord/settings.json` |
| Linux | `~/.config/discord/settings.json` |
| Linux (Flatpak) | `~/.var/app/com.discordapp.Discord/config/discord/settings.json` |

You should be able to identify that you are in the right place quite easily, it should look like
```json
"UPDATE_ENDPOINT": "https://inject.shelter.uwu.network/shelter",
"NEW_UPDATE_ENDPOINT": "https://inject.shelter.uwu.network/shelter/"
```

Ensure you leave a `/` on the end of the new endpoint, and do not put one on the old endpoint.

### Manual Legacy Uninstall

If you have been asked by the shelter installer to manually uninstall the traditional/legacy injector, here are the
steps to do that.

First, find your resources folder:

| OS | Path |
|-----------------|--------------------------------------------------------------------------------------------|
| Windows | `%LocalAppData%\discord\resources` |
| macOS | `/Applications/Discord.app/Contents/Resources` |
| Linux | `/opt/discord/resources` |
| Linux | `/usr/share/discord/resources` |
| Linux | `/usr/lib/discord/resources` |
| Linux (Flatpak) | `/var/lib/flatpak/app/com.discordapp.Discord/x86_64/stable/active/files/discord/resources` |

It should look like so:

```
πŸ— resources
β”œβ”€β”€ πŸ— app
β”‚ β”œβ”€β”€ πŸ—‹ index.js
β”‚ β”œβ”€β”€ πŸ—‹ preload.js
β”‚ └── πŸ—‹ package.json
β”œβ”€β”€ πŸ— bootstrap
β”œβ”€β”€ πŸ—‹ build_info.json
└── πŸ—‹ original.asar
```

Rename `original.asar` to `app.asar`, and delete the `app` folder. It should look like this:

```
πŸ— resources
β”œβ”€β”€ πŸ—‹ app.asar
β”œβ”€β”€ πŸ— bootstrap
└── πŸ—‹ build_info.json
```

You're done! Go back to the shelter installer to install sheltupdate, if you were trying to do that.

## Firefox

Install this extension: https://addons.mozilla.org/firefox/addon/shelter-injector/

## Microsoft Edge

Install this extension:
https://microsoftedge.microsoft.com/addons/detail/shelter-mv3-inj/okemjpeidkmhjpmdcpaibakdhnheblib

## Firefox
## Other Chromium Browsers

Do not follow these instructions if you are using Microsoft Edge.

As these extensions fetch the latest build of shelter, it is not allowed on the Chrome Webstore (we got kicked off!),
and as there is no easy way to comply with this, you will have to manually install the extension.

Install this extension: https://addons.mozilla.org/firefox/addon/shelter-injector/
1. Download the latest version of the extension [here](https://github.com/uwu/shelter/releases?q=mv3&expanded=true)
2. Unpack the zip to a folder somewhere safe. If you delete this folder, the extension will be uninstalled.
3. Head to [chrome://extensions](chrome://extensions), and enable Developer Mode in the top-right corner
4. Click "Load Unpacked Extension", and select the folder you unpacked the zip into
Loading

0 comments on commit d0825c8

Please sign in to comment.