this repo has no description

Compare changes

Choose any two refs to compare.

Changed files
+142 -34
nix
packages
browser
core
src
core-extensions
src
componentEditor
experiments
moonbase
quietLoggers
types
src
+6
nix/default.nix
··· 11 12 src = ./..; 13 14 nativeBuildInputs = [ 15 nodejs_22 16 pnpm_10.configHook ··· 30 runHook preBuild 31 32 pnpm run build 33 34 runHook postBuild 35 ''; ··· 38 runHook preInstall 39 40 cp -r dist $out 41 42 runHook postInstall 43 '';
··· 11 12 src = ./..; 13 14 + outputs = [ "out" "firefox" ]; 15 + 16 nativeBuildInputs = [ 17 nodejs_22 18 pnpm_10.configHook ··· 32 runHook preBuild 33 34 pnpm run build 35 + pnpm run browser-mv2 36 37 runHook postBuild 38 ''; ··· 41 runHook preInstall 42 43 cp -r dist $out 44 + 45 + mkdir -p $firefox/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}/ 46 + mv $out/browser-mv2 $firefox/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}/{0fb6d66f-f22d-4555-a87b-34ef4bea5e2a} 47 48 runHook postInstall 49 '';
+6 -1
packages/browser/manifestv2.json
··· 24 "run_at": "document_start", 25 "world": "MAIN" 26 } 27 - ] 28 }
··· 24 "run_at": "document_start", 25 "world": "MAIN" 26 } 27 + ], 28 + "browser_specific_settings": { 29 + "gecko": { 30 + "id": "{0fb6d66f-f22d-4555-a87b-34ef4bea5e2a}" 31 + } 32 + } 33 }
+4
packages/browser/src/index.ts
··· 90 dirname(path) { 91 const parts = getParts(path); 92 return "/" + parts.slice(0, parts.length - 1).join("/"); 93 } 94 }, 95 // TODO
··· 90 dirname(path) { 91 const parts = getParts(path); 92 return "/" + parts.slice(0, parts.length - 1).join("/"); 93 + }, 94 + basename(path) { 95 + const parts = getParts(path); 96 + return parts[parts.length - 1]; 97 } 98 }, 99 // TODO
+3
packages/core/src/fs.ts
··· 48 }, 49 dirname(dir) { 50 return path.dirname(dir); 51 } 52 }; 53 }
··· 48 }, 49 dirname(dir) { 50 return path.dirname(dir); 51 + }, 52 + basename(dir) { 53 + return path.basename(dir); 54 } 55 }; 56 }
+2 -1
packages/core-extensions/src/componentEditor/index.ts
··· 27 find: ".lostPermission", 28 replace: [ 29 { 30 - match: /(?<=\(0,\i\.jsxs\)\(\i\.Fragment,{)children:(\[\i\(\),.+?\i\(\)])/, 31 replacement: (_, decorators) => 32 `children:require("componentEditor_memberList").default._patchDecorators(${decorators},arguments[0])` 33 },
··· 27 find: ".lostPermission", 28 replace: [ 29 { 30 + match: 31 + /(?<=\(0,\i\.jsxs\)\(\i\.Fragment,{)children:(\[\(0,\i\.jsx\)\(\i,{user:\i}\),.+?onClickPremiumGuildIcon:\i}\)])/, 32 replacement: (_, decorators) => 33 `children:require("componentEditor_memberList").default._patchDecorators(${decorators},arguments[0])` 34 },
+4 -4
packages/core-extensions/src/experiments/index.ts
··· 20 { 21 find: ".HEADER_BAR)", 22 replace: { 23 - match: /&&\((.)\?\(0,/, 24 replacement: (_, isStaff) => 25 `&&(((moonlight.getConfigOption("experiments","devtools")??false)?true:${isStaff})?(0,` 26 } ··· 47 { 48 find: "shouldShowLurkerModeUpsellPopout:", 49 replace: { 50 - match: /\.useReducedMotion,isStaff:(.),/, 51 - replacement: (_, isStaff) => 52 - `.useReducedMotion,isStaff:(moonlight.getConfigOption("experiments","staffSettings")??false)?true:${isStaff},` 53 } 54 } 55 ];
··· 20 { 21 find: ".HEADER_BAR)", 22 replace: { 23 + match: /&&\((\i)\?\(0,/, 24 replacement: (_, isStaff) => 25 `&&(((moonlight.getConfigOption("experiments","devtools")??false)?true:${isStaff})?(0,` 26 } ··· 47 { 48 find: "shouldShowLurkerModeUpsellPopout:", 49 replace: { 50 + match: /\.useReducedMotion,isStaff:(\i)(,|})/, 51 + replacement: (_, isStaff, trail) => 52 + `.useReducedMotion,isStaff:(moonlight.getConfigOption("experiments","staffSettings")??false)?true:${isStaff}${trail}` 53 } 54 } 55 ];
+2 -2
packages/core-extensions/src/moonbase/webpackModules/crashScreen.tsx
··· 84 } 85 86 function ExtensionDisableCard({ ext }: { ext: DetectedExtension }) { 87 - function disableWithDependents() { 88 const disable = new Set<string>(); 89 disable.add(ext.id); 90 for (const [id, dependencies] of moonlightNode.processedExtensions.dependencyGraph) { ··· 105 msg += "?"; 106 107 if (confirm(msg)) { 108 - moonlightNode.writeConfig(config); 109 window.location.reload(); 110 } 111 }
··· 84 } 85 86 function ExtensionDisableCard({ ext }: { ext: DetectedExtension }) { 87 + async function disableWithDependents() { 88 const disable = new Set<string>(); 89 disable.add(ext.id); 90 for (const [id, dependencies] of moonlightNode.processedExtensions.dependencyGraph) { ··· 105 msg += "?"; 106 107 if (confirm(msg)) { 108 + await moonlightNode.writeConfig(config); 109 window.location.reload(); 110 } 111 }
+2 -2
packages/core-extensions/src/moonbase/webpackModules/settings.tsx
··· 19 onReset={() => { 20 MoonbaseSettingsStore.reset(); 21 }} 22 - onSave={() => { 23 - MoonbaseSettingsStore.writeConfig(); 24 }} 25 /> 26 );
··· 19 onReset={() => { 20 MoonbaseSettingsStore.reset(); 21 }} 22 + onSave={async () => { 23 + await MoonbaseSettingsStore.writeConfig(); 24 }} 25 /> 26 );
+30 -10
packages/core-extensions/src/moonbase/webpackModules/stores.ts
··· 13 import { mainRepo } from "@moonlight-mod/types/constants"; 14 import { checkExtensionCompat, ExtensionCompat } from "@moonlight-mod/core/extension/loader"; 15 import { CustomComponent } from "@moonlight-mod/types/coreExtensions/moonbase"; 16 import { getConfigOption, setConfigOption } from "@moonlight-mod/core/util/config"; 17 import diff from "microdiff"; 18 ··· 78 }; 79 } 80 81 this.checkUpdates(); 82 } 83 84 async checkUpdates() { ··· 239 let val = this.config.extensions[ext.id]; 240 241 if (val == null) { 242 - this.config.extensions[ext.id] = { enabled }; 243 this.modified = this.isModified(); 244 this.emitChange(); 245 return; ··· 499 return returnedAdvice; 500 } 501 502 - writeConfig() { 503 - this.submitting = true; 504 - this.restartAdvice = this.#computeRestartAdvice(); 505 - const modifiedRepos = diff(this.savedConfig.repositories, this.config.repositories); 506 507 - moonlightNode.writeConfig(this.config); 508 - this.savedConfig = this.clone(this.config); 509 510 - this.submitting = false; 511 this.modified = false; 512 - this.emitChange(); 513 514 - if (modifiedRepos.length !== 0) this.checkUpdates(); 515 } 516 517 reset() {
··· 13 import { mainRepo } from "@moonlight-mod/types/constants"; 14 import { checkExtensionCompat, ExtensionCompat } from "@moonlight-mod/core/extension/loader"; 15 import { CustomComponent } from "@moonlight-mod/types/coreExtensions/moonbase"; 16 + import { NodeEventType } from "@moonlight-mod/types/core/event"; 17 import { getConfigOption, setConfigOption } from "@moonlight-mod/core/util/config"; 18 import diff from "microdiff"; 19 ··· 79 }; 80 } 81 82 + // This is async but we're calling it without 83 this.checkUpdates(); 84 + 85 + // Update our state if another extension edited the config programatically 86 + moonlightNode.events.addEventListener(NodeEventType.ConfigSaved, (config) => { 87 + if (!this.submitting) { 88 + this.config = this.clone(config); 89 + // NOTE: This is also async but we're calling it without 90 + this.processConfigChanged(); 91 + } 92 + }); 93 } 94 95 async checkUpdates() { ··· 250 let val = this.config.extensions[ext.id]; 251 252 if (val == null) { 253 + this.config.extensions[ext.id] = enabled; 254 this.modified = this.isModified(); 255 this.emitChange(); 256 return; ··· 510 return returnedAdvice; 511 } 512 513 + async writeConfig() { 514 + try { 515 + this.submitting = true; 516 + this.emitChange(); 517 518 + await moonlightNode.writeConfig(this.config); 519 + await this.processConfigChanged(); 520 + } finally { 521 + this.submitting = false; 522 + this.emitChange(); 523 + } 524 + } 525 526 + private async processConfigChanged() { 527 + this.savedConfig = this.clone(this.config); 528 + this.restartAdvice = this.#computeRestartAdvice(); 529 this.modified = false; 530 531 + const modifiedRepos = diff(this.savedConfig.repositories, this.config.repositories); 532 + if (modifiedRepos.length !== 0) await this.checkUpdates(); 533 + 534 + this.emitChange(); 535 } 536 537 reset() {
+82 -14
packages/core-extensions/src/quietLoggers/index.ts
··· 18 { 19 find: '("GatewaySocket")', 20 replace: { 21 - match: /.\.(info|log)(\(.+?\))(;|,)/g, 22 - replacement: (_, type, body, trail) => `(()=>{})${body}${trail}` 23 } 24 } 25 ]; ··· 30 // Patches to simply remove a logger call 31 const stubPatches = [ 32 // "sh" is not a valid locale. 33 - ["is not a valid locale", /void (.)\.error\(""\.concat\((.)," is not a valid locale\."\)\)/g], 34 - ['"[BUILD INFO] Release Channel: "', /new .{1,2}\.Z\(\)\.log\("\[BUILD INFO\] Release Channel: ".+?\)\),/], 35 - ['.APP_NATIVE_CRASH,"Storage"', /console\.log\("AppCrashedFatalReport lastCrash:",.,.\);/], 36 ['.APP_NATIVE_CRASH,"Storage"', 'void console.log("AppCrashedFatalReport: getLastCrash not supported.")'], 37 - ['"[NATIVE INFO] ', /new .{1,2}\.Z\(\)\.log\("\[NATIVE INFO] .+?\)\);/], 38 - ['"Spellchecker"', /.\.info\("Switching to ".+?"\(unavailable\)"\);?/g], 39 - ['throw Error("Messages are still loading.");', /console\.warn\("Unsupported Locale",.\),/], 40 - ["}_dispatchWithDevtools(", /.\.totalTime>.{1,2}&&.\.verbose\(.+?\);/], 41 - ['"NativeDispatchUtils"', /null==.&&.\.warn\("Tried getting Dispatch instance before instantiated"\),/], 42 - ['("DatabaseManager")', /.\.log\("removing database \(user: ".+?\)\),/], 43 [ 44 '"Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch. Action: "', 45 - /.\.has\(.\.type\)&&.\.log\(.+?\.type\)\),/ 46 ], 47 - ['console.warn("Window state not initialized"', /console\.warn\("Window state not initialized",.\),/] 48 ]; 49 50 const simplePatches = [ ··· 56 { 57 find: ".Messages.SELF_XSS_HEADER", 58 replace: { 59 - match: /\(null!=.{1,2}&&"0\.0\.0"===.{1,2}\.remoteApp\.getVersion\(\)\)/, 60 replacement: "(true)" 61 } 62 }, 63 // Highlight.js deprecation warnings 64 { 65 find: "Deprecated as of", ··· 92 replace: { 93 match: patch[0], 94 replacement: patch[1] 95 }, 96 prerequisite: notXssDefensesOnly 97 }))
··· 18 { 19 find: '("GatewaySocket")', 20 replace: { 21 + match: /\i\.(log|info)\(/g, 22 + replacement: "(()=>{})(" 23 + } 24 + }, 25 + { 26 + find: '"_connect called with already existing websocket"', 27 + replace: { 28 + match: /\i\.(log|info|verbose)\(/g, 29 + replacement: "(()=>{})(" 30 } 31 } 32 ]; ··· 37 // Patches to simply remove a logger call 38 const stubPatches = [ 39 // "sh" is not a valid locale. 40 + ["is not a valid locale", /void \i\.error\(""\.concat\(\i," is not a valid locale\."\)\)/g], 41 + ['"[BUILD INFO] Release Channel: "', /new \i\.Z\(\)\.log\("\[BUILD INFO\] Release Channel: ".+?\)\),/], 42 + ['.APP_NATIVE_CRASH,"Storage"', /console\.log\("AppCrashedFatalReport lastCrash:",\i,\i\);/], 43 ['.APP_NATIVE_CRASH,"Storage"', 'void console.log("AppCrashedFatalReport: getLastCrash not supported.")'], 44 + ['"[NATIVE INFO] ', /new \i\.Z\(\)\.log\("\[NATIVE INFO] .+?\)\);/], 45 + ['"Spellchecker"', /\i\.info\("Switching to ".+?"\(unavailable\)"\);?/g], 46 + ['throw Error("Messages are still loading.");', /console\.warn\("Unsupported Locale",\i\),/], 47 + ["}_dispatchWithDevtools(", /\i\.totalTime>\i&&\i\.verbose\(.+?\);/], 48 + ['"NativeDispatchUtils"', /null==\i&&\i\.warn\("Tried getting Dispatch instance before instantiated"\),/], 49 [ 50 '"Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch. Action: "', 51 + /\i\.has\(\i\.type\)&&\i\.log\(.+?\.type\)\),/ 52 ], 53 + ['console.warn("Window state not initialized"', /console\.warn\("Window state not initialized",\i\),/], 54 + ['.name="MaxListenersExceededWarning",', /(?<=\.length),\i\(\i\)/], 55 + [ 56 + '"The answer for life the universe and everything is:"', 57 + /\i\.info\("The answer for life the universe and everything is:",\i\),/ 58 + ], 59 + [ 60 + '"isLibdiscoreBlockedDomainsEnabled called but libdiscore is not loaded"', 61 + /,\i\.verbose\("isLibdiscoreBlockedDomainsEnabledThisSession: ".concat\(\i\)\)/ 62 + ], 63 + [ 64 + '"Unable to determine render window for element"', 65 + /console\.warn\("Unable to determine render window for element",\i\),/ 66 + ], 67 + [ 68 + '"Unable to determine render window for element"', 69 + /console\.warn\('Unable to find element constructor "'\.concat\(\i,'" in'\),\i\),/ 70 + ], 71 + [ 72 + '"[PostMessageTransport] Protocol error: event data should be an Array!"', 73 + /void console\.warn\("\[PostMessageTransport] Protocol error: event data should be an Array!"\)/ 74 + ], 75 + [ 76 + '("ComponentDispatchUtils")', 77 + /new \i\.Z\("ComponentDispatchUtils"\)\.warn\("ComponentDispatch\.resubscribe: Resubscribe without existing subscription",\i\),/ 78 + ] 79 + ]; 80 + 81 + const stripLoggers = [ 82 + '("OverlayRenderStore")', 83 + '("FetchBlockedDomain")', 84 + '="UserSettingsProtoLastWriteTimes",', 85 + '("MessageActionCreators")', 86 + '("Routing/Utils")', 87 + '("DatabaseManager")', 88 + '("KeyboardLayoutMapUtils")', 89 + '("ChannelMessages")', 90 + '("MessageQueue")', 91 + '("RTCLatencyTestManager")', 92 + '("OverlayStoreV3")', 93 + '("OverlayBridgeStore")', 94 + '("AuthenticationStore")', 95 + '("ConnectionStore")', 96 + '"Dispatched INITIAL_GUILD "', 97 + '"handleIdentify called"', 98 + '("Spotify")' 99 ]; 100 101 const simplePatches = [ ··· 107 { 108 find: ".Messages.SELF_XSS_HEADER", 109 replace: { 110 + match: /\(null!=\i&&"0\.0\.0"===\i\.remoteApp\.getVersion\(\)\)/, 111 replacement: "(true)" 112 } 113 }, 114 + { 115 + find: '("ComponentDispatchUtils")', 116 + replace: { 117 + match: 118 + /new \i\.Z\("ComponentDispatchUtils"\)\.warn\("ComponentDispatch\.subscribe: Attempting to add a duplicate listener",\i\)/, 119 + replacement: "void 0" 120 + }, 121 + prerequisite: notXssDefensesOnly 122 + }, 123 // Highlight.js deprecation warnings 124 { 125 find: "Deprecated as of", ··· 152 replace: { 153 match: patch[0], 154 replacement: patch[1] 155 + }, 156 + prerequisite: notXssDefensesOnly 157 + })), 158 + ...stripLoggers.map((find) => ({ 159 + find, 160 + replace: { 161 + match: /(\i|this\.logger)\.(log|warn|error|info|verbose)\(/g, 162 + replacement: "(()=>{})(" 163 }, 164 prerequisite: notXssDefensesOnly 165 }))
+1
packages/types/src/fs.ts
··· 15 16 join: (...parts: string[]) => string; 17 dirname: (path: string) => string; 18 };
··· 15 16 join: (...parts: string[]) => string; 17 dirname: (path: string) => string; 18 + basename: (path: string) => string; 19 };