this repo has no description

Compare changes

Choose any two refs to compare.

Changed files
+182 -59
.github
workflows
nix
packages
browser
core
core-extensions
src
componentEditor
experiments
moonbase
quietLoggers
types
+16
.github/workflows/nix.yml
···
+
name: Check Nix flake
+
on: [push, pull_request]
+
+
permissions:
+
checks: write
+
+
jobs:
+
nix:
+
name: Check Nix flake
+
runs-on: ubuntu-latest
+
steps:
+
- uses: actions/checkout@v4
+
- uses: DeterminateSystems/nix-installer-action@main
+
+
- name: Build default flake output
+
run: nix build
+1 -8
CHANGELOG.md
···
## Core
-
- Fixed the Nix flake (thanks @sersorrel!)
- Updated mappings
-
-
## Core extensions
-
-
- Common: Added new "icons" Webpack module library
-
- Commands: Fixed for latest Discord
-
- Settings: Fixed for latest Discord
-
- Moonbase: Fixed for latest Discord
+
- Fixed using remapped paths as patch finds not working
+7 -1
nix/default.nix
···
src = ./..;
+
outputs = [ "out" "firefox" ];
+
nativeBuildInputs = [
nodejs_22
pnpm_10.configHook
···
pnpmDeps = pnpm_10.fetchDeps {
inherit (finalAttrs) pname version src;
-
hash = "sha256-uCuA4Fuquv1qXqSY+kDP2Jp01yZDYG2H3ruOBQMhYtw=";
+
hash = "sha256-I+zRCUqJabpGJRFBGW0NrM9xzyzeCjioF54zlCpynBU=";
};
env = {
···
runHook preBuild
pnpm run build
+
pnpm run browser-mv2
runHook postBuild
'';
···
runHook preInstall
cp -r dist $out
+
+
mkdir -p $firefox/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}/
+
mv $out/browser-mv2 $firefox/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}/{0fb6d66f-f22d-4555-a87b-34ef4bea5e2a}
runHook postInstall
'';
+1 -1
package.json
···
{
"name": "moonlight",
-
"version": "1.3.13",
+
"version": "1.3.14",
"packageManager": "pnpm@10.7.1",
"description": "Yet another Discord mod",
"license": "LGPL-3.0-or-later",
+1 -1
packages/browser/manifest.json
···
"manifest_version": 3,
"name": "moonlight",
"description": "Yet another Discord mod",
-
"version": "1.3.13",
+
"version": "1.3.14",
"permissions": ["declarativeNetRequestWithHostAccess", "webRequest", "scripting", "webNavigation"],
"host_permissions": [
"https://moonlight-mod.github.io/*",
+7 -2
packages/browser/manifestv2.json
···
"manifest_version": 2,
"name": "moonlight",
"description": "Yet another Discord mod",
-
"version": "1.3.13",
+
"version": "1.3.14",
"permissions": [
"webRequest",
"webRequestBlocking",
···
"run_at": "document_start",
"world": "MAIN"
}
-
]
+
],
+
"browser_specific_settings": {
+
"gecko": {
+
"id": "{0fb6d66f-f22d-4555-a87b-34ef4bea5e2a}"
+
}
+
}
}
+4
packages/browser/src/index.ts
···
dirname(path) {
const parts = getParts(path);
return "/" + parts.slice(0, parts.length - 1).join("/");
+
},
+
basename(path) {
+
const parts = getParts(path);
+
return parts[parts.length - 1];
}
},
// TODO
+3
packages/core/src/fs.ts
···
},
dirname(dir) {
return path.dirname(dir);
+
},
+
basename(dir) {
+
return path.basename(dir);
}
};
}
+1 -1
packages/core/src/patch.ts
···
const origModuleString = moduleCache[id];
let moduleString = origModuleString;
const patchedStr = [];
-
const mappedName = moonlight.moonmap.modules[id];
+
const mappedName = Object.entries(moonlight.moonmap.modules).find((m) => m[1] === id)?.[0];
let modified = false;
let swappedModule = false;
+2 -1
packages/core-extensions/src/componentEditor/index.ts
···
find: ".lostPermission",
replace: [
{
-
match: /(?<=\(0,\i\.jsxs\)\(\i\.Fragment,{)children:(\[\i\(\),.+?\i\(\)])/,
+
match:
+
/(?<=\(0,\i\.jsxs\)\(\i\.Fragment,{)children:(\[\(0,\i\.jsx\)\(\i,{user:\i}\),.+?onClickPremiumGuildIcon:\i}\)])/,
replacement: (_, decorators) =>
`children:require("componentEditor_memberList").default._patchDecorators(${decorators},arguments[0])`
},
+4 -4
packages/core-extensions/src/experiments/index.ts
···
{
find: ".HEADER_BAR)",
replace: {
-
match: /&&\((.)\?\(0,/,
+
match: /&&\((\i)\?\(0,/,
replacement: (_, isStaff) =>
`&&(((moonlight.getConfigOption("experiments","devtools")??false)?true:${isStaff})?(0,`
}
···
{
find: "shouldShowLurkerModeUpsellPopout:",
replace: {
-
match: /\.useReducedMotion,isStaff:(.),/,
-
replacement: (_, isStaff) =>
-
`.useReducedMotion,isStaff:(moonlight.getConfigOption("experiments","staffSettings")??false)?true:${isStaff},`
+
match: /\.useReducedMotion,isStaff:(\i)(,|})/,
+
replacement: (_, isStaff, trail) =>
+
`.useReducedMotion,isStaff:(moonlight.getConfigOption("experiments","staffSettings")??false)?true:${isStaff}${trail}`
}
}
];
+2 -2
packages/core-extensions/src/moonbase/webpackModules/crashScreen.tsx
···
}
function ExtensionDisableCard({ ext }: { ext: DetectedExtension }) {
-
function disableWithDependents() {
+
async function disableWithDependents() {
const disable = new Set<string>();
disable.add(ext.id);
for (const [id, dependencies] of moonlightNode.processedExtensions.dependencyGraph) {
···
msg += "?";
if (confirm(msg)) {
-
moonlightNode.writeConfig(config);
+
await moonlightNode.writeConfig(config);
window.location.reload();
}
}
+2 -2
packages/core-extensions/src/moonbase/webpackModules/settings.tsx
···
onReset={() => {
MoonbaseSettingsStore.reset();
}}
-
onSave={() => {
-
MoonbaseSettingsStore.writeConfig();
+
onSave={async () => {
+
await MoonbaseSettingsStore.writeConfig();
}}
/>
);
+30 -10
packages/core-extensions/src/moonbase/webpackModules/stores.ts
···
import { mainRepo } from "@moonlight-mod/types/constants";
import { checkExtensionCompat, ExtensionCompat } from "@moonlight-mod/core/extension/loader";
import { CustomComponent } from "@moonlight-mod/types/coreExtensions/moonbase";
+
import { NodeEventType } from "@moonlight-mod/types/core/event";
import { getConfigOption, setConfigOption } from "@moonlight-mod/core/util/config";
import diff from "microdiff";
···
};
}
+
// This is async but we're calling it without
this.checkUpdates();
+
+
// Update our state if another extension edited the config programatically
+
moonlightNode.events.addEventListener(NodeEventType.ConfigSaved, (config) => {
+
if (!this.submitting) {
+
this.config = this.clone(config);
+
// NOTE: This is also async but we're calling it without
+
this.processConfigChanged();
+
}
+
});
}
async checkUpdates() {
···
let val = this.config.extensions[ext.id];
if (val == null) {
-
this.config.extensions[ext.id] = { enabled };
+
this.config.extensions[ext.id] = enabled;
this.modified = this.isModified();
this.emitChange();
return;
···
return returnedAdvice;
}
-
writeConfig() {
-
this.submitting = true;
-
this.restartAdvice = this.#computeRestartAdvice();
-
const modifiedRepos = diff(this.savedConfig.repositories, this.config.repositories);
+
async writeConfig() {
+
try {
+
this.submitting = true;
+
this.emitChange();
-
moonlightNode.writeConfig(this.config);
-
this.savedConfig = this.clone(this.config);
+
await moonlightNode.writeConfig(this.config);
+
await this.processConfigChanged();
+
} finally {
+
this.submitting = false;
+
this.emitChange();
+
}
+
}
-
this.submitting = false;
+
private async processConfigChanged() {
+
this.savedConfig = this.clone(this.config);
+
this.restartAdvice = this.#computeRestartAdvice();
this.modified = false;
-
this.emitChange();
-
if (modifiedRepos.length !== 0) this.checkUpdates();
+
const modifiedRepos = diff(this.savedConfig.repositories, this.config.repositories);
+
if (modifiedRepos.length !== 0) await this.checkUpdates();
+
+
this.emitChange();
}
reset() {
+82 -14
packages/core-extensions/src/quietLoggers/index.ts
···
{
find: '("GatewaySocket")',
replace: {
-
match: /.\.(info|log)(\(.+?\))(;|,)/g,
-
replacement: (_, type, body, trail) => `(()=>{})${body}${trail}`
+
match: /\i\.(log|info)\(/g,
+
replacement: "(()=>{})("
+
}
+
},
+
{
+
find: '"_connect called with already existing websocket"',
+
replace: {
+
match: /\i\.(log|info|verbose)\(/g,
+
replacement: "(()=>{})("
}
}
];
···
// Patches to simply remove a logger call
const stubPatches = [
// "sh" is not a valid locale.
-
["is not a valid locale", /void (.)\.error\(""\.concat\((.)," is not a valid locale\."\)\)/g],
-
['"[BUILD INFO] Release Channel: "', /new .{1,2}\.Z\(\)\.log\("\[BUILD INFO\] Release Channel: ".+?\)\),/],
-
['.APP_NATIVE_CRASH,"Storage"', /console\.log\("AppCrashedFatalReport lastCrash:",.,.\);/],
+
["is not a valid locale", /void \i\.error\(""\.concat\(\i," is not a valid locale\."\)\)/g],
+
['"[BUILD INFO] Release Channel: "', /new \i\.Z\(\)\.log\("\[BUILD INFO\] Release Channel: ".+?\)\),/],
+
['.APP_NATIVE_CRASH,"Storage"', /console\.log\("AppCrashedFatalReport lastCrash:",\i,\i\);/],
['.APP_NATIVE_CRASH,"Storage"', 'void console.log("AppCrashedFatalReport: getLastCrash not supported.")'],
-
['"[NATIVE INFO] ', /new .{1,2}\.Z\(\)\.log\("\[NATIVE INFO] .+?\)\);/],
-
['"Spellchecker"', /.\.info\("Switching to ".+?"\(unavailable\)"\);?/g],
-
['throw Error("Messages are still loading.");', /console\.warn\("Unsupported Locale",.\),/],
-
["}_dispatchWithDevtools(", /.\.totalTime>.{1,2}&&.\.verbose\(.+?\);/],
-
['"NativeDispatchUtils"', /null==.&&.\.warn\("Tried getting Dispatch instance before instantiated"\),/],
-
['("DatabaseManager")', /.\.log\("removing database \(user: ".+?\)\),/],
+
['"[NATIVE INFO] ', /new \i\.Z\(\)\.log\("\[NATIVE INFO] .+?\)\);/],
+
['"Spellchecker"', /\i\.info\("Switching to ".+?"\(unavailable\)"\);?/g],
+
['throw Error("Messages are still loading.");', /console\.warn\("Unsupported Locale",\i\),/],
+
["}_dispatchWithDevtools(", /\i\.totalTime>\i&&\i\.verbose\(.+?\);/],
+
['"NativeDispatchUtils"', /null==\i&&\i\.warn\("Tried getting Dispatch instance before instantiated"\),/],
[
'"Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch. Action: "',
-
/.\.has\(.\.type\)&&.\.log\(.+?\.type\)\),/
+
/\i\.has\(\i\.type\)&&\i\.log\(.+?\.type\)\),/
],
-
['console.warn("Window state not initialized"', /console\.warn\("Window state not initialized",.\),/]
+
['console.warn("Window state not initialized"', /console\.warn\("Window state not initialized",\i\),/],
+
['.name="MaxListenersExceededWarning",', /(?<=\.length),\i\(\i\)/],
+
[
+
'"The answer for life the universe and everything is:"',
+
/\i\.info\("The answer for life the universe and everything is:",\i\),/
+
],
+
[
+
'"isLibdiscoreBlockedDomainsEnabled called but libdiscore is not loaded"',
+
/,\i\.verbose\("isLibdiscoreBlockedDomainsEnabledThisSession: ".concat\(\i\)\)/
+
],
+
[
+
'"Unable to determine render window for element"',
+
/console\.warn\("Unable to determine render window for element",\i\),/
+
],
+
[
+
'"Unable to determine render window for element"',
+
/console\.warn\('Unable to find element constructor "'\.concat\(\i,'" in'\),\i\),/
+
],
+
[
+
'"[PostMessageTransport] Protocol error: event data should be an Array!"',
+
/void console\.warn\("\[PostMessageTransport] Protocol error: event data should be an Array!"\)/
+
],
+
[
+
'("ComponentDispatchUtils")',
+
/new \i\.Z\("ComponentDispatchUtils"\)\.warn\("ComponentDispatch\.resubscribe: Resubscribe without existing subscription",\i\),/
+
]
+
];
+
+
const stripLoggers = [
+
'("OverlayRenderStore")',
+
'("FetchBlockedDomain")',
+
'="UserSettingsProtoLastWriteTimes",',
+
'("MessageActionCreators")',
+
'("Routing/Utils")',
+
'("DatabaseManager")',
+
'("KeyboardLayoutMapUtils")',
+
'("ChannelMessages")',
+
'("MessageQueue")',
+
'("RTCLatencyTestManager")',
+
'("OverlayStoreV3")',
+
'("OverlayBridgeStore")',
+
'("AuthenticationStore")',
+
'("ConnectionStore")',
+
'"Dispatched INITIAL_GUILD "',
+
'"handleIdentify called"',
+
'("Spotify")'
];
const simplePatches = [
···
{
find: ".Messages.SELF_XSS_HEADER",
replace: {
-
match: /\(null!=.{1,2}&&"0\.0\.0"===.{1,2}\.remoteApp\.getVersion\(\)\)/,
+
match: /\(null!=\i&&"0\.0\.0"===\i\.remoteApp\.getVersion\(\)\)/,
replacement: "(true)"
}
},
+
{
+
find: '("ComponentDispatchUtils")',
+
replace: {
+
match:
+
/new \i\.Z\("ComponentDispatchUtils"\)\.warn\("ComponentDispatch\.subscribe: Attempting to add a duplicate listener",\i\)/,
+
replacement: "void 0"
+
},
+
prerequisite: notXssDefensesOnly
+
},
// Highlight.js deprecation warnings
{
find: "Deprecated as of",
···
replace: {
match: patch[0],
replacement: patch[1]
+
},
+
prerequisite: notXssDefensesOnly
+
})),
+
...stripLoggers.map((find) => ({
+
find,
+
replace: {
+
match: /(\i|this\.logger)\.(log|warn|error|info|verbose)\(/g,
+
replacement: "(()=>{})("
},
prerequisite: notXssDefensesOnly
}))
+2 -2
packages/types/package.json
···
{
"name": "@moonlight-mod/types",
-
"version": "1.3.16",
+
"version": "1.3.17",
"exports": {
".": "./src/index.ts",
"./import": "./src/import.d.ts",
···
},
"dependencies": {
"@moonlight-mod/lunast": "^1.0.1",
-
"@moonlight-mod/mappings": "^1.1.24",
+
"@moonlight-mod/mappings": "^1.1.25",
"@moonlight-mod/moonmap": "^1.0.5",
"@types/react": "^18.3.10",
"csstype": "^3.1.3",
+1
packages/types/src/fs.ts
···
join: (...parts: string[]) => string;
dirname: (path: string) => string;
+
basename: (path: string) => string;
};
+15 -9
pnpm-lock.yaml
···
specifier: ^1.0.1
version: 1.0.1
'@moonlight-mod/mappings':
-
specifier: ^1.1.24
-
version: 1.1.24
+
specifier: ^1.1.25
+
version: 1.1.25
'@moonlight-mod/moonmap':
specifier: ^1.0.5
version: 1.0.5
···
specifier: ^1.0.1
version: 1.0.1
'@moonlight-mod/mappings':
-
specifier: ^1.1.24
-
version: 1.1.24(@moonlight-mod/lunast@1.0.1)(@moonlight-mod/moonmap@1.0.5)
+
specifier: ^1.1.25
+
version: 1.1.25(@moonlight-mod/lunast@1.0.1)(@moonlight-mod/moonmap@1.0.5)
'@moonlight-mod/moonmap':
specifier: ^1.0.5
version: 1.0.5
···
version: 1.0.1
'@moonlight-mod/mappings':
specifier: catalog:prod
-
version: 1.1.24(@moonlight-mod/lunast@1.0.1)(@moonlight-mod/moonmap@1.0.5)
+
version: 1.1.25(@moonlight-mod/lunast@1.0.1)(@moonlight-mod/moonmap@1.0.5)
'@moonlight-mod/moonmap':
specifier: catalog:prod
version: 1.0.5
···
'@moonlight-mod/lunast@1.0.1':
resolution: {integrity: sha512-K3vxzDlfFuYKjciIW2FMlcZ1qrrkAGDGpSBlNqYGtJ0sMt9bRCd2lpSpg6AX/giSljDtmAUXa/5mOfUoDQxjBA==}
-
'@moonlight-mod/mappings@1.1.24':
-
resolution: {integrity: sha512-tcZSD8S+twjNq1Wp4wnHbc38BfLeHB/9MMLhk8YNqTGMMr5swaKcMOmvGjqd50vRPBRgAi/ss180cIX2uYWrOg==}
+
'@moonlight-mod/mappings@1.1.25':
+
resolution: {integrity: sha512-bgnSN9H/IBdMGxGev6RQKXuzhQxwo1090NhIDHnflguZnjiu2pg/usPfh76bqyhxRuX4SS7tiZSNTwBoSflCLg==}
engines: {node: '>=22', npm: pnpm, pnpm: '>=10', yarn: pnpm}
peerDependencies:
'@moonlight-mod/lunast': ^1.0.1
···
'@types/estree@1.0.6':
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
+
+
'@types/estree@1.0.7':
+
resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==}
'@types/fbemitter@2.0.35':
resolution: {integrity: sha512-Xem6d7qUfmouCHntCrRYgDBwbf+WWRd6G+7WEFlEZFZ67LZXiYRvT2LV8wcZa6mIaAil95+ABQdKgB6hPIsnng==}
···
estree-toolkit: 1.7.8
meriyah: 6.0.1
-
'@moonlight-mod/mappings@1.1.24(@moonlight-mod/lunast@1.0.1)(@moonlight-mod/moonmap@1.0.5)':
+
'@moonlight-mod/mappings@1.1.25(@moonlight-mod/lunast@1.0.1)(@moonlight-mod/moonmap@1.0.5)':
dependencies:
'@moonlight-mod/lunast': 1.0.1
'@moonlight-mod/moonmap': 1.0.5
···
'@types/eslint@9.6.1':
dependencies:
-
'@types/estree': 1.0.6
+
'@types/estree': 1.0.7
'@types/json-schema': 7.0.15
optional: true
···
'@types/estree': 1.0.6
'@types/estree@1.0.6': {}
+
+
'@types/estree@1.0.7':
+
optional: true
'@types/fbemitter@2.0.35': {}
+1 -1
pnpm-workspace.yaml
···
taze: ^19.0.4
prod:
"@moonlight-mod/lunast": ^1.0.1
-
"@moonlight-mod/mappings": ^1.1.24
+
"@moonlight-mod/mappings": ^1.1.25
"@moonlight-mod/moonmap": ^1.0.5
microdiff: ^1.5.0
nanotar: ^0.1.1