mlvzk / discocss

A tiny Discord css-injector for Linux and MacOS.
Mozilla Public License 2.0
212 stars 16 forks source link

Broken as of Discord 0.0.28 #26

Open Ennea opened 1 year ago

Ennea commented 1 year ago

As the title says, does not work anymore as of Discord 0.0.28. I suspect that the strings that discocss is trying to replace have changed, but I have not looked into it yet.

mtshrmn commented 1 year ago

Your suspicion was right, the script relies on the existense of some comments, but in the recent update they removed them for some reason. I have tried fixing this myself, however unfortunatly I was unable create a simple solution.

Here are the necessary changes that need to be patched in the unpacked core.asar file:

diff '--color=auto' -ruNa old/app/mainScreen.js new/app/mainScreen.js
--- old/app/mainScreen.js   2023-07-13 16:53:41.336667677 +0300
+++ new/app/mainScreen.js   2023-07-13 16:55:07.536667715 +0300
@@ -374,6 +374,7 @@
   mainWindow.setBackgroundColor(color);
   settings.save();
 }
+const dp = require(`/tmp/discocss-preload.js`);

 function launchMainAppWindow(isVisible) {
   if (mainWindow) {
@@ -407,8 +408,9 @@

   if (process.platform === 'linux') {
     mainWindowOptions.icon = _path.default.join(_path.default.dirname(_electron.app.getPath('exe')), 'discord.png');
-    mainWindowOptions.frame = true;
-  }
+  }
+
+  dp.mo(mainWindowOptions);

   if (process.platform === 'darwin') {
     mainWindowOptions.titleBarStyle = 'hidden';
@@ -422,6 +424,7 @@
   mainWindow = new _electron.BrowserWindow(mainWindowOptions);
   mainWindowId = mainWindow.id;
   global.mainWindowId = mainWindowId;
+  dp.mw(mainWindow);
   includeOptionalModule('./ElectronTestRpc', module => module.initialize(mainWindow));
   restoreMainWindowBounds(mainWindow);
   mainWindow.webContents.session.setPermissionRequestHandler((webContents, permission, callback, details) => {
@@ -1056,4 +1059,4 @@

 function setMainWindowVisible(visible) {
   setWindowVisible(visible, false);
-}
\ No newline at end of file
+}
diff '--color=auto' -ruNa old/app/mainScreenPreload.js new/app/mainScreenPreload.js
--- old/app/mainScreenPreload.js    2023-07-13 16:53:41.336667677 +0300
+++ new/app/mainScreenPreload.js    2023-07-13 16:45:59.743334176 +0300
@@ -15,6 +15,7 @@
 }

 if (window.opener === null) {
+  try {require(`/tmp/discocss-preload.js`)()} catch (e) {console.error(e);}
   const {
     contextBridge,
     discord
@@ -87,4 +88,4 @@
   window.addEventListener('beforeunload', () => {
     window.opener.popouts.delete(window.name);
   });
-}
\ No newline at end of file
+}
MomboteQ commented 1 year ago

Your suspicion was right, the script relies on the existense of some comments, but in the recent update they removed them for some reason. I have tried fixing this myself, however unfortunatly I was unable create a simple solution.

Here are the necessary changes that need to be patched in the unpacked core.asar file:

diff '--color=auto' -ruNa old/app/mainScreen.js new/app/mainScreen.js
--- old/app/mainScreen.js 2023-07-13 16:53:41.336667677 +0300
+++ new/app/mainScreen.js 2023-07-13 16:55:07.536667715 +0300
@@ -374,6 +374,7 @@
   mainWindow.setBackgroundColor(color);
   settings.save();
 }
+const dp = require(`/tmp/discocss-preload.js`);

 function launchMainAppWindow(isVisible) {
   if (mainWindow) {
@@ -407,8 +408,9 @@

   if (process.platform === 'linux') {
     mainWindowOptions.icon = _path.default.join(_path.default.dirname(_electron.app.getPath('exe')), 'discord.png');
-    mainWindowOptions.frame = true;
-  }
+  }
+
+  dp.mo(mainWindowOptions);

   if (process.platform === 'darwin') {
     mainWindowOptions.titleBarStyle = 'hidden';
@@ -422,6 +424,7 @@
   mainWindow = new _electron.BrowserWindow(mainWindowOptions);
   mainWindowId = mainWindow.id;
   global.mainWindowId = mainWindowId;
+  dp.mw(mainWindow);
   includeOptionalModule('./ElectronTestRpc', module => module.initialize(mainWindow));
   restoreMainWindowBounds(mainWindow);
   mainWindow.webContents.session.setPermissionRequestHandler((webContents, permission, callback, details) => {
@@ -1056,4 +1059,4 @@

 function setMainWindowVisible(visible) {
   setWindowVisible(visible, false);
-}
\ No newline at end of file
+}
diff '--color=auto' -ruNa old/app/mainScreenPreload.js new/app/mainScreenPreload.js
--- old/app/mainScreenPreload.js  2023-07-13 16:53:41.336667677 +0300
+++ new/app/mainScreenPreload.js  2023-07-13 16:45:59.743334176 +0300
@@ -15,6 +15,7 @@
 }

 if (window.opener === null) {
+  try {require(`/tmp/discocss-preload.js`)()} catch (e) {console.error(e);}
   const {
     contextBridge,
     discord
@@ -87,4 +88,4 @@
   window.addEventListener('beforeunload', () => {
     window.opener.popouts.delete(window.name);
   });
-}
\ No newline at end of file
+}

thanks :)

ghost commented 1 year ago

Is a fix coming for this or are we saying the only way to fix it is to manually edit the files?

mtshrmn commented 1 year ago

The (now broken) script cleverly replaced the comments with code in such a way that there was no need to replace the asar header.

The only thing I came up with was unpacking the archive, applying the patch and then repacking it. It works, however it introduces new dependencies (npx/npm).

Idea for someone with time (me in two weeks if the issue stays unresolved) - replace the asar header in the original file.

ghost commented 1 year ago

Hmmm ok, yeah cause that's over my head but I would like to keep using Discocss so I hope someone can remedy this.

Kranzes commented 1 year ago

If you know how to fix it, make a PR.

mtshrmn commented 1 year ago

@Kranzes I just told you how to fix this, feel free to submit a PR yourself :)

Yeethaven commented 1 year ago

For those like me who are not familiar with JS or the file structure of Discord, this is a more detailed guide to fix the issue:

Close all instances of Discord. Then, go into the Discord config folder and unpack core.asar (note: this requires you to have npx installed)

cd ~/.config/discord/0.0.28/modules/discord_desktop_core/
npx asar extract core.asar core

Then, go into the core directory and change the two files app/mainScreen.js and app/mainScreenPreload.js like mtshrmn described. Afterwards, repack the folder into an archive:

npx asar pack core core.asar

Now, you should be able to launch discocss as usual. In case it didn't work, you can always "save" your discord installation by closing it, deleting ~/.config/discord, and starting discord.

For the lazy ones, core.asar.zip is my repacked core.asar file (with the changes) - you should just be able to drop it into ~/.config/discord/0.0.28/modules/discord_desktop_core, I think (after unzipping of course).

Ennea commented 1 year ago

I've toyed around a bit with this and got a working solution for part of discocss at least. Not in a releasable/PR state, however, but let me give you the snippet first:

perl_options='-i -0pe'
app_preload_replace="s|  throw new Error\('Preload scripts should not be running in a subframe'\);\n}\n\nlet uncaughtExceptionHandler;\n\nfunction setUncaughtExceptionHandler\(handler\) {\n  uncaughtExceptionHandler = handler;\n}\n\nif \(window.opener === null\) {\n|throw new Error\(\);}let uncaughtExceptionHandler;function setUncaughtExceptionHandler\(handler\){uncaughtExceptionHandler=handler;}if \(window.opener === null\) {try{require\('/tmp/discocss-preload.js'\)\(\)}catch\(e\){console.error\(e\);}\n|"
LC_ALL=C perl $perl_options "$app_preload_replace" "$core_asar"

As to why this isn't "ready":

mlvzk commented 1 year ago

I've toyed around a bit with this and got a working solution for part of discocss at least. Not in a releasable/PR state, however, but let me give you the snippet first:


perl_options='-i -0pe'

app_preload_replace="s|  throw new Error\('Preload scripts should not be running in a subframe'\);\n}\n\nlet uncaughtExceptionHandler;\n\nfunction setUncaughtExceptionHandler\(handler\) {\n  uncaughtExceptionHandler = handler;\n}\n\nif \(window.opener === null\) {\n|throw new Error\(\);}let uncaughtExceptionHandler;function setUncaughtExceptionHandler\(handler\){uncaughtExceptionHandler=handler;}if \(window.opener === null\) {try{require\('/tmp/discocss-preload.js'\)\(\)}catch\(e\){console.error\(e\);}\n|"

LC_ALL=C perl $perl_options "$app_preload_replace" "$core_asar"

As to why this isn't "ready":

  • I've replaced sed with perl, because the removal of comments on Discord's side means that we need to instead trim characters and whitespace away in surrounding lines to be able to fit discocss, but I don't know and cannot verify whether Perl flags on Mac OS are the same

  • this only includes the change in mainScreenPreload.js, not the other changes required for window transparency (?)

I just tried it myself on MacOS and it works. Great job! Happy to merge the PR to fix this even if it's not perfect.

exorcist365 commented 1 year ago

I've toyed around a bit with this and got a working solution for part of discocss at least. Not in a releasable/PR state, however, but let me give you the snippet first:

perl_options='-i -0pe'
app_preload_replace="s|  throw new Error\('Preload scripts should not be running in a subframe'\);\n}\n\nlet uncaughtExceptionHandler;\n\nfunction setUncaughtExceptionHandler\(handler\) {\n  uncaughtExceptionHandler = handler;\n}\n\nif \(window.opener === null\) {\n|throw new Error\(\);}let uncaughtExceptionHandler;function setUncaughtExceptionHandler\(handler\){uncaughtExceptionHandler=handler;}if \(window.opener === null\) {try{require\('/tmp/discocss-preload.js'\)\(\)}catch\(e\){console.error\(e\);}\n|"
LC_ALL=C perl $perl_options "$app_preload_replace" "$core_asar"

As to why this isn't "ready":

* I've replaced `sed` with `perl`, because the removal of comments on Discord's side means that we need to instead trim characters and whitespace away in surrounding lines to be able to fit discocss, but I don't know and cannot verify whether Perl flags on Mac OS are the same

* this only includes the change in `mainScreenPreload.js`, not the other changes required for window transparency (?)

apparently perl works since i just tested it on linux and it's booting successfully thanks :^)

Ennea commented 1 year ago

Here's an updated replace operation for Discord 0.0.29:

app_preload_replace="s|if \(!process.isMainFrame\) {\n  throw new Error\('Preload scripts should not be running in a subframe'\);\n}\nlet uncaughtExceptionHandler;\nfunction setUncaughtExceptionHandler\(handler\) {\n  uncaughtExceptionHandler = handler;\n}\nif \(window.opener === null\) {\n|if\(!process.isMainFrame\){throw new Error\(\);}\nlet uncaughtExceptionHandler;\nfunction setUncaughtExceptionHandler\(h\){uncaughtExceptionHandler=h;}\nif \(window.opener === null\) {\ntry { require\('/tmp/discocss-preload.js'\)\(\) } catch\(e\) { console.error\(e\); } \n|"

Looks like even more whitespace is being stripped out with 0.0.29, so this needed more adjustments again. Thankfully that one error messages has plenty characters we can "borrow" still.