Compare commits

...

603 Commits

Author SHA1 Message Date
Alexei Stukov 4707671795
Use rii 2018-08-07 09:47:59 +03:00
Alexei Stukov 222c2347fd
Versioning 2018-08-07 08:34:12 +03:00
Alexei Stukov 0d81028a3c
Working again 2018-08-07 08:32:14 +03:00
Alexei Stukov 7b99b7d7f1
Merge pull request #857 from Modder4869/patch-3
Update dblClickEdit.plugin.js
2018-08-01 03:37:47 +03:00
Modder4869 fa20c57f86
Update dblClickEdit.plugin.js 2018-07-29 21:00:53 +03:00
Alexei Stukov 884ea57c14 Update issue templates 2018-07-22 00:57:54 +03:00
Alexei Stukov a6d81c2f25
Delete Dumhub 2018-07-22 00:54:46 +03:00
Alexei Stukov e85e3a49d9
Merge pull request #842 from Modder4869/patch-2
Update dblClickEdit.plugin.js
2018-07-22 00:51:08 +03:00
Alexei Stukov b62ab6259e
closes #854, closes #853, closes #852, closes #850, closes #845, closes #842, closes #839, closes #838, closes #837, closes #834, closes #833, closes #831, closes #829, closes #828, closes #827, closes #826, closes #825, closes #824, closes #823, closes #820, closes #819, closes #818, closes #817, closes #816, closes #815, closes #814, closes #812, closes #811, closes #810, closes #809, closes #808, closes #807, closes #806, closes #805, closes #804, closes #803, closes #802, closes #800, closes #798, closes #797, closes #796, closes #795, closes #794, closes #793, closes #792, closes #790, closes #789, closes #788, closes #787, closes #786, closes #785, closes #784, closes #783, closes #782, closes #781, closes #780, closes #779, closes #778, closes #776, closes #775, closes #772, closes #771, closes #770, closes #769, closes #768, closes #767, closes #766, closes #764, closes #762, closes #761, closes #760, closes #758, closes #755, closes #753, closes #752, closes #751, closes #750, closes #749, closes #748, closes #747, closes #746, closes #745, closes #744, closes #740, closes #739, closes #738, closes #737, closes #736, closes #734, closes #731, closes #725, closes #724, closes #723, closes #720, closes #718, closes #717, closes #716, closes #715, closes #714, closes #713, closes #711, closes #708, closes #707, closes #706, closes #703, closes #701, closes #700, closes #699, closes #698, closes #697, closes #696, closes #693, closes #692, closes #691, closes #690, closes #689, closes #687, closes #686, closes #685, closes #684, closes #683, closes #681, closes #680, closes #677, closes #676, closes #675, closes #674, closes #673, closes #672, closes #671, closes #669, closes #668, closes #665, closes #662, closes #661, closes #659, closes #658, closes #655, closes #654, closes #653, closes #652, closes #651, closes #649, closes #647, closes #646, closes #645, closes #644, closes #643, closes #642, closes #641, closes #640, closes #639, closes #637, closes #636, closes #635, closes #633, closes #632, closes #631, closes #629, closes #628, closes #627, closes #626, closes #625, closes #624, closes #623, closes #622, closes #621, closes #620, closes #618, closes #617, closes #615, closes #614, closes #613, closes #612, closes #611, closes #610, closes #609, closes #608, closes #607, closes #606, closes #605, closes #603, closes #602, closes #601, closes #600, closes #599, closes #597, closes #596, closes #595, closes #594, closes #593, closes #592, closes #591, closes #590, closes #588, closes #587, closes #585, closes #583, closes #581, closes #579, closes #578, closes #577, closes #574, closes #573, closes #572, closes #571, closes #570, closes #568, closes #567, closes #565, closes #564, closes #562, closes #560, closes #559, closes #558, closes #557, closes #556, closes #555, closes #554, closes #552, closes #550, closes #549, closes #547, closes #546, closes #543, closes #542, closes #541, closes #540, closes #539, closes #535, closes #533, closes #532, closes #530, closes #529, closes #528, closes #527, closes #526, closes #525, closes #524, closes #523, closes #522, closes #521, closes #520, closes #519, closes #517, closes #515, closes #514, closes #512, closes #511, closes #510, closes #508, closes #507, closes #506, closes #505, closes #503, closes #502, closes #500, closes #498, closes #497, closes #493, closes #492, closes #490, closes #489, closes #488, closes #485, closes #483, closes #482, closes #481, closes #480, closes #478, closes #476, closes #474, closes #473, closes #471, closes #470, closes #429
Refer to: https://github.com/Jiiks/BetterDiscordApp/blob/master/ISSUE_TEMPLATE.md for any new issues
2018-07-22 00:47:53 +03:00
Alexei Stukov 82232fa9c6
Merge pull request #700 from samuelthomas2774/patch-1
closes #854, closes #853, closes #852, closes #850, closes #845, closes #842, closes #839, closes #838, closes #837, closes #834, closes #833, closes #831, closes #829, closes #828, closes #827, closes #826, closes #825, closes #824, closes #823, closes #820, closes #819, closes #818, closes #817, closes #816, closes #815, closes #814, closes #812, closes #811, closes #810, closes #809, closes #808, closes #807, closes #806, closes #805, closes #804, closes #803, closes #802, closes #800, closes #798, closes #797, closes #796, closes #795, closes #794, closes #793, closes #792, closes #790, closes #789, closes #788, closes #787, closes #786, closes #785, closes #784, closes #783, closes #782, closes #781, closes #780, closes #779, closes #778, closes #776, closes #775, closes #772, closes #771, closes #770, closes #769, closes #768, closes #767, closes #766, closes #764, closes #762, closes #761, closes #760, closes #758, closes #755, closes #753, closes #752, closes #751, closes #750, closes #749, closes #748, closes #747, closes #746, closes #745, closes #744, closes #740, closes #739, closes #738, closes #737, closes #736, closes #734, closes #731, closes #725, closes #724, closes #723, closes #720, closes #718, closes #717, closes #716, closes #715, closes #714, closes #713, closes #711, closes #708, closes #707, closes #706, closes #703, closes #701, closes #700, closes #699, closes #698, closes #697, closes #696, closes #693, closes #692, closes #691, closes #690, closes #689, closes #687, closes #686, closes #685, closes #684, closes #683, closes #681, closes #680, closes #677, closes #676, closes #675, closes #674, closes #673, closes #672, closes #671, closes #669, closes #668, closes #665, closes #662, closes #661, closes #659, closes #658, closes #655, closes #654, closes #653, closes #652, closes #651, closes #649, closes #647, closes #646, closes #645, closes #644, closes #643, closes #642, closes #641, closes #640, closes #639, closes #637, closes #636, closes #635, closes #633, closes #632, closes #631, closes #629, closes #628, closes #627, closes #626, closes #625, closes #624, closes #623, closes #622, closes #621, closes #620, closes #618, closes #617, closes #615, closes #614, closes #613, closes #612, closes #611, closes #610, closes #609, closes #608, closes #607, closes #606, closes #605, closes #603, closes #602, closes #601, closes #600, closes #599, closes #597, closes #596, closes #595, closes #594, closes #593, closes #592, closes #591, closes #590, closes #588, closes #587, closes #585, closes #583, closes #581, closes #579, closes #578, closes #577, closes #574, closes #573, closes #572, closes #571, closes #570, closes #568, closes #567, closes #565, closes #564, closes #562, closes #560, closes #559, closes #558, closes #557, closes #556, closes #555, closes #554, closes #552, closes #550, closes #549, closes #547, closes #546, closes #543, closes #542, closes #541, closes #540, closes #539, closes #535, closes #533, closes #532, closes #530, closes #529, closes #528, closes #527, closes #526, closes #525, closes #524, closes #523, closes #522, closes #521, closes #520, closes #519, closes #517, closes #515, closes #514, closes #512, closes #511, closes #510, closes #508, closes #507, closes #506, closes #505, closes #503, closes #502, closes #500, closes #498, closes #497, closes #493, closes #492, closes #490, closes #489, closes #488, closes #485, closes #483, closes #482, closes #481, closes #480, closes #478, closes #476, closes #474, closes #473, closes #471, closes #470, closes #429
2018-07-22 00:41:49 +03:00
Modder4869 57e16e3b43
Update dblClickEdit.plugin.js 2018-07-02 12:59:08 +03:00
Modder4869 7f6cd474fd
Update dblClickEdit.plugin.js 2018-06-27 18:16:40 +03:00
Alexei Stukov 718ab4fb7d
Merge pull request #777 from Modder4869/patch-1
fix popout classname.
2018-04-25 14:36:00 +03:00
Modder4869 c187ed3127
fix popout classname. 2018-04-23 22:42:20 +03:00
Alexei Stukov 4966be2020
Link to correct active development fork 2018-03-10 19:40:03 +02:00
Samuel Elliott 1d7627bce7
Create ISSUE_TEMPLATE.md 2018-02-05 20:44:30 +00:00
Jiiks e9e3627339 Delete obj 2018-01-10 17:54:00 +02:00
Jiiks 8688a9ea7d Don't crash if stable doesn't exist 2018-01-10 17:50:26 +02:00
Jiiks 2a29984950 Ignore .suo 2018-01-10 17:32:48 +02:00
Jiiks cf1a9ecb91 Restructure 2018-01-10 17:29:29 +02:00
Jiiks 4114a6ee26 New installer 2018-01-10 17:17:15 +02:00
Alexei Stukov 55a6fb8697
remin 2018-01-10 16:50:32 +02:00
Alexei Stukov 5344fd2b1e
Merge pull request #664 from rauenzi/patch1
patch react, react-dom and layer changes
2018-01-10 16:49:18 +02:00
Zack Rauen 7322ea8ba9 patch react, react-dom and layer changes 2018-01-09 21:13:44 -05:00
pohky 4a377d9648
Update emotefilter.json 2017-11-01 09:33:14 +01:00
Jiiks 1a6648ebf0 Emote parser bug fix 2017-10-16 21:38:44 +03:00
Jiiks 9ab77a8217 Support for twitchemotes v3 api 2017-09-30 05:07:53 +03:00
pohky 1d07436569 Merge pull request #536 from SomeGuyNamedDavid/patch-1
Update emotefilter.json
2017-07-26 03:23:42 +02:00
pohky f91dff5c1b Update emotefilter.json 2017-07-26 03:22:06 +02:00
David a160359413 Update emotefilter.json 2017-07-25 02:04:53 -04:00
pohky ebe69a5369 Merge pull request #537 from DeathStrikeV/master
Updated FFZ emotes =)
2017-07-24 05:28:08 +02:00
DeathStrikeV 0831320b61 Updated FFZ emotes =3 2017-07-24 03:56:39 +01:00
David 4df677c28d Update emotefilter.json 2017-07-22 22:17:33 -04:00
David aee8aa7483 Update emotefilter.json 2017-07-22 21:09:25 -04:00
Alexei Stukov 1cc631b29d 626d414 2017-07-22 13:31:47 +03:00
Alexei Stukov 626d41480c Hide changelog for now, fix things that use ta 2017-07-22 13:28:23 +03:00
pohky caaa0aba8b Merge pull request #484 from SomeGuyNamedDavid/master
Alphabetize EmoteFilter (and add a whole lot of items)
2017-07-21 10:13:34 +02:00
pohky daec28f2b0 Update emotefilter.json
added missing commas
2017-07-21 10:12:40 +02:00
pohky 6d1baa0639 Merge pull request #531 from DeathStrikeV/master
Updated FFZ emotes =)
2017-07-21 09:55:09 +02:00
DeathStrikeV 31e94d72f7 Updated FFZ emotes =3 2017-07-21 03:59:40 +01:00
David 055b3b9a25 Update emotefilter.json 2017-07-19 01:35:49 -04:00
DeathStrikeV c0fd7e41cc Updated FFZ emotes =3 2017-07-17 03:55:29 +01:00
David 187b39dac1 Update emotefilter.json 2017-07-16 12:09:58 -04:00
DeathStrikeV 10f686a71f Updated FFZ emotes =3 2017-07-15 08:55:27 +01:00
DeathStrikeV eabad3bced Updated FFZ emotes =3 2017-07-14 03:55:54 +01:00
David 6daeeaf866 Update emotefilter.json 2017-07-13 15:23:05 -04:00
David 255caea48e Update emotefilter.json 2017-07-13 14:50:13 -04:00
pohky a46fb246ed Merge pull request #518 from DeathStrikeV/master
Updated FFZ emotes =)
2017-07-13 16:44:41 +02:00
David 054efe9e75 Update emotefilter.json 2017-07-12 19:39:43 -04:00
DeathStrikeV 07f5c3b6d5 Updated FFZ emotes =3 2017-07-10 03:54:32 +01:00
David 895f987ca9 Update emotefilter.json 2017-07-08 23:06:53 -04:00
David cefa91aa13 Update emotefilter.json 2017-07-07 01:15:19 -04:00
DeathStrikeV 0271df21c9 Updated FFZ emotes =3 2017-07-07 03:55:56 +01:00
David a6b89cf205 Update emotefilter.json 2017-07-06 22:24:47 -04:00
David a74e425a8e Update emotefilter.json 2017-07-05 17:56:26 -04:00
David 191bfaca02 Update emotefilter.json 2017-07-05 17:55:34 -04:00
David de1a63f7bd Update emotefilter.json 2017-07-04 12:22:57 -04:00
David 39e7982c64 Update emotefilter.json 2017-07-03 19:05:18 -04:00
David ccbebd6855 Update emotefilter.json 2017-07-03 17:02:39 -04:00
David 192184e4d1 Update emotefilter.json 2017-07-03 14:49:48 -04:00
DeathStrikeV 94622aa854 Updated FFZ emotes =3 2017-07-03 03:53:23 +01:00
David 051edcf619 Update emotefilter.json 2017-07-02 13:40:39 -04:00
David 3c1c8f27a4 Update emotefilter.json 2017-07-01 23:54:11 -04:00
David 11ca29c2fb Update emotefilter.json 2017-07-01 22:16:43 -04:00
David 4eb5c183a5 Update emotefilter.json 2017-07-01 19:25:43 -04:00
David bf041b54ef Update emotefilter.json 2017-06-30 14:38:04 -04:00
DeathStrikeV 3c53865150 Updated FFZ emotes =3 2017-06-30 03:55:54 +01:00
David db66110556 Update emotefilter.json 2017-06-29 20:51:31 -04:00
DeathStrikeV d1371a5383 Updated FFZ emotes =3 2017-06-28 00:17:57 +01:00
David c5e0886690 Update emotefilter.json 2017-06-26 02:04:28 -04:00
DeathStrikeV 6d77162321 Updated FFZ emotes =3 2017-06-26 03:53:18 +01:00
David 5ebeb06520 Update emotefilter.json 2017-06-25 13:04:29 -04:00
David 35dadec203 Update emotefilter.json 2017-06-24 21:36:22 -04:00
Alexei Stukov 9f1314e75c Merge pull request #509 from DeathStrikeV/master
Updated FFZ emotes =)
2017-06-24 01:55:14 +03:00
David a21cb93d3b Update emotefilter.json 2017-06-23 16:21:41 -04:00
DeathStrikeV 6cf7f8583d Updated FFZ emotes =3 2017-06-23 03:53:03 +01:00
DeathStrikeV 3787744a71 Updated FFZ emotes =3 2017-06-22 03:56:17 +01:00
David 358c8e288d Update emotefilter.json 2017-06-21 18:40:33 -04:00
DeathStrikeV e5a8224c49 Updated FFZ emotes =3 2017-06-21 03:54:25 +01:00
DeathStrikeV d34db2cbc2 Updated FFZ emotes =3 2017-06-20 04:20:36 +01:00
David c5abd4703a Update emotefilter.json 2017-06-19 01:05:51 -04:00
David b63b4a31f3 Update emotefilter.json 2017-06-19 01:01:34 -04:00
DeathStrikeV 8f0c9b5158 Updated FFZ emotes =3 2017-06-19 03:54:52 +01:00
DeathStrikeV 715480c429 Updated FFZ emotes =3 2017-06-18 21:02:09 +01:00
BlazingSky 12444400a0 Merge pull request #16 from Jiiks/master
Update to latest
2017-06-18 18:42:31 +01:00
BlazingSky 9d7e1bae32 Update to latest (#15)
* Settings panel injection fix

* css fixes

* 1.792

* 1.792

* Fix scrolling and tools

* Fix scrolling and tools
2017-06-18 18:39:57 +01:00
DeathStrikeV 3fb10a820a Updated FFZ emotes =3 2017-06-18 13:31:59 +01:00
Alexei Stukov 565ff12946 Fix scrolling and tools 2017-06-18 08:04:03 +03:00
Alexei Stukov da082999cb Fix scrolling and tools 2017-06-18 08:03:34 +03:00
Alexei Stukov 4fc5abe092 1.792 2017-06-18 03:38:14 +03:00
Alexei Stukov ecc8b3baa1 1.792 2017-06-18 03:38:12 +03:00
Alexei Stukov 319fd6b12b css fixes 2017-06-18 03:36:24 +03:00
David cf6a9ca3b7 Update emotefilter.json 2017-06-17 20:02:50 -04:00
Alexei Stukov df8b319275 Settings panel injection fix 2017-06-17 20:08:43 +03:00
David 19b37a9feb Update emotefilter.json 2017-06-16 20:57:54 -04:00
David 633e2fb986 Update emotefilter.json 2017-06-15 20:53:03 -04:00
David b24b1b7cda Create emotefilter.json 2017-06-15 20:03:16 -04:00
David ab58d87acd Create emotefilter.json 2017-06-15 16:52:37 -04:00
Alexei Stukov db7f9911c9 Merge pull request #487 from DeathStrikeV/master
Updated FFZ emotes =)
2017-06-14 15:51:56 +03:00
DeathStrikeV 21cc2c8beb Updated FFZ emotes =3 2017-06-14 01:17:37 +01:00
DeathStrikeV b805ec8b2c Updated FFZ emotes =3 2017-06-10 00:34:34 +01:00
DeathStrikeV c8f21ae02e Updated FFZ emotes =3 2017-06-07 02:37:30 +01:00
David 154d916a9e Update emotefilter.json 2017-06-06 01:54:30 -04:00
DeathStrikeV e4681e2a23 Updated FFZ emotes =3 2017-06-05 07:49:35 +01:00
David e5aeea60e9 Update emotefilter.json 2017-06-04 01:37:21 -04:00
David 37c3f12178 Update emotefilter.json 2017-06-02 01:17:57 -04:00
David 72e9d2f455 Update emotefilter.json 2017-06-01 13:41:08 -04:00
David e3c8befb25 Update emotefilter.json 2017-05-29 23:08:46 -04:00
DeathStrikeV 8e9b59521a Updated FFZ emotes =3 2017-05-29 10:57:40 +01:00
DeathStrikeV 1c882bc52d Updated FFZ emotes =3 2017-05-29 10:43:11 +01:00
David a33a2b205d Update emotefilter.json 2017-05-29 03:07:20 -04:00
David 0c014877ea Update emotefilter.json 2017-05-24 23:03:32 -04:00
pohky d5522e547c Merge pull request #486 from DeathStrikeV/master
Updated FFZ emotes =3
2017-05-23 09:46:19 +02:00
DeathStrikeV 1e997efa28 Updated FFZ emotes =3 2017-05-23 08:30:45 +01:00
David 01eb06ab23 Update emotefilter.json 2017-05-22 18:29:21 -04:00
David 42ee775176 Update emotefilter.json 2017-05-21 15:00:56 -04:00
David 187966d4b0 Update emotefilter.json 2017-05-20 17:34:24 -04:00
DeathStrikeV 50edc74c55 Updated FFZ emotes =3 2017-05-20 10:51:09 +01:00
BlazingSky 29d8bba9a9 Merge pull request #14 from Jiiks/master
Pull latest changes in
2017-05-20 08:11:33 +01:00
David 2382b1e130 Update emotefilter.json 2017-05-18 20:15:50 -04:00
David e67e4ee7b9 Update emotefilter.json 2017-05-16 21:06:52 -04:00
David 1bf65e5706 Update emotefilter.json 2017-05-16 21:01:26 -04:00
Alexei Stukov 4dfc413227 Fix open folder button position 2017-05-13 13:26:23 +03:00
Alexei Stukov 7a9ac5b035 Fix open folder button position 2017-05-13 13:26:20 +03:00
pohky 678a756dd6 Merge pull request #479 from Zerthox/patch-2
Add "You!" to emotefilter
2017-05-13 06:37:24 +02:00
Alexei Stukov 1e8f45e825 Restore open folder buttons 2017-05-12 22:45:29 +03:00
Alexei Stukov 85f79d5259 Restore open folder buttons 2017-05-12 22:45:25 +03:00
Alexei Stukov 5f83b20f6b Restore open folder buttons 2017-05-12 22:45:22 +03:00
Alexei Stukov c9b6a11941 Restore open folder buttons 2017-05-12 22:45:19 +03:00
Zerthox 4a33c39e8b Add "You!" 2017-05-12 21:16:36 +02:00
Alexei Stukov 05d379ba79 Merge pull request #477 from DeathStrikeV/master
Updated FFZ emotes + Added some new words to emotefilter.json
2017-05-12 18:33:30 +03:00
DeathStrikeV 8aa4a7c700 Updated FFZ emotes =3 2017-05-11 01:18:15 +01:00
BlazingSky 04c0df30e7 Merge pull request #13 from Jiiks/master
Merging changes from master
2017-05-11 00:08:30 +01:00
Alexei Stukov 0ea7990226 added Hai! 2017-05-08 16:02:04 +03:00
Alexei Stukov a96a0384b2 https://github.com/Jiiks/BetterDiscordApp/pull/441/files 2017-05-08 07:37:44 +03:00
Alexei Stukov bf6f826c9d https://github.com/Jiiks/BetterDiscordApp/pull/441 2017-05-08 07:36:59 +03:00
Alexei Stukov 81bd8938fe Merge pull request #439 from noodlebox/osx-electron-fix
Fix Electron installer for OSX
2017-05-08 07:34:24 +03:00
Alexei Stukov 0255164f42 Merge pull request #430 from AlcaDesign/patch-1
Reduce cases in Node installer
2017-05-08 07:34:07 +03:00
Alexei Stukov 4a7422039e Merge pull request #385 from noodlebox/rewrite-autogif
Fix AutoPlayGifs plugin
2017-05-08 07:32:03 +03:00
Alexei Stukov 8dfd0f2a73 Merge pull request #361 from yozora-mikazuki/master
Version-agnostic uninstaller for Windows
2017-05-08 07:30:40 +03:00
Alexei Stukov 5abe7c4a9e Merge pull request #464 from SomeGuyNamedDavid/patch-1
Update emotefilter.json
2017-05-08 07:26:25 +03:00
Alexei Stukov 1c75af3513 Merge branch 'master' into patch-1 2017-05-08 07:26:00 +03:00
Alexei Stukov 214c77be13 Merge pull request #456 from Violetnred2/patch-2
Update emotefilter.json
2017-05-08 07:23:59 +03:00
Alexei Stukov 7c62116554 License 2017-05-07 19:44:59 +03:00
Alexei Stukov 4cb39d90c0 close issues
Closes #111 Closes #153 Closes #215 Closes #238 Closes #275 Closes #280 Closes #281 Closes #286 Closes #289 Closes #291 Closes #294 Closes #302 Closes #304  Closes #308  Closes #315  Closes #317  Closes #320  Closes #321 Closes #322 Closes #323 Closes #324  Closes #325  Closes #327  Closes #331  Closes #332  Closes #333  Closes #334  Closes #337  Closes #337 Closes #340 Closes #341 Closes #345 Closes #346 Closes #347 Closes #348 Closes #351 Closes #354 Closes #359 Closes #360 Closes #364 Closes #367 Closes #368 Closes #370 Closes #371 Closes #372 Closes #373 Closes #374 Closes #375 Closes #376 Closes #377 Closes #378 Closes #379 Closes #380 Closes #382 Closes #383 Closes #386 Closes #387 Closes #388 Closes #390 Closes #393 Closes #394 Closes #395 Closes #396 Closes #397 Closes #398 Closes #402
2017-05-05 09:02:04 +03:00
Alexei Stukov db34f5c6b0 Test
Closes #469 Closes #468
2017-05-05 08:56:35 +03:00
Alexei Stukov 8bfd9cdaa5 Fixed name overflow and plugin settings close button. 2017-05-05 04:24:22 +03:00
Alexei Stukov e7aeb7d1af Fixed name overflow and plugin settings close button. 2017-05-05 04:24:20 +03:00
Alexei Stukov 327c08fd93 Localization fix and layer identifiers 2017-05-04 18:47:16 +03:00
Alexei Stukov b933703f4f Localization fix and layer identifiers 2017-05-04 18:47:15 +03:00
pohky a5089721db Merge pull request #467 from DeathStrikeV/master
Updated FFZ emotes =3
2017-05-03 13:30:06 +02:00
DeathStrikeV 5a51afd01e Updated FFZ emotes =3 2017-05-02 20:15:17 +01:00
Alexei Stukov fc7a85a79c minify 2017-05-02 18:15:35 +03:00
Alexei Stukov 707afde649 Fix setting saving 2017-05-02 18:15:02 +03:00
Alexei Stukov a85d8e19d9 Fix setting saving 2017-05-02 18:14:59 +03:00
David 1a367d83ba Update emotefilter.json 2017-05-01 23:57:45 -04:00
Alexei Stukov 05d55ea6fa Fixed settings sidebar injection 2017-05-01 12:36:49 +03:00
Alexei Stukov 9859064dc6 Fixed settings sidebar injection 2017-05-01 12:36:48 +03:00
Alexei Stukov 2d4416466c Fixed theme and plugin state not saving 2017-04-30 14:21:23 +03:00
Alexei Stukov 6372743f9f Fixed theme and plugin state not saving 2017-04-30 14:21:19 +03:00
Alexei Stukov 060c2ab0ec Fix for pluginpanel crashing 2017-04-30 14:16:29 +03:00
Alexei Stukov 91dd2e6ee7 Fix for pluginpanel crashing 2017-04-30 14:16:27 +03:00
Alexei Stukov eff75f27dc Allow dom nodes for plugin settings. 2017-04-30 14:02:42 +03:00
Alexei Stukov 8650b376ef Allow dom nodes for plugin settings. 2017-04-30 14:02:23 +03:00
Alexei Stukov f58ccdad4a Fix license link 2017-04-30 06:27:03 +03:00
Alexei Stukov 6e020a0298 Update credits and license 2017-04-30 06:26:35 +03:00
Alexei Stukov bdb22e9fb6 v1.78 2017-04-30 06:24:11 +03:00
Alexei Stukov f6cae7c238 v1.78 2017-04-30 06:11:58 +03:00
Alexei Stukov ad86bbb8c8 v1.78 2017-04-30 06:11:32 +03:00
Alexei Stukov 5bf01fa3c8 Fix missing keys 2017-04-30 06:07:07 +03:00
Alexei Stukov 2fbf1e9985 Show BD server regardless 2017-04-30 05:44:50 +03:00
Alexei Stukov 2fbe862933 Invite code joining 2017-04-30 05:34:52 +03:00
Alexei Stukov 2d554d0086 BD Blue add friend button bg 2017-04-30 05:25:59 +03:00
Alexei Stukov 3262eb58a9 Editor detached bdblue
Fixed editor attach button bdblue styling
2017-04-30 05:22:26 +03:00
Alexei Stukov b15f56212d Editor attach
Fixed css editor updating when attaching if open.
2017-04-30 05:21:08 +03:00
Alexei Stukov 6d23660361 Pinned server css 2017-04-30 04:49:40 +03:00
Alexei Stukov fbb0283148 xhr creds 2017-04-30 04:36:23 +03:00
Alexei Stukov 93ecab675d Changelog 2017-04-30 04:20:55 +03:00
Alexei Stukov 8820d0e674 v1.78 public test 2017-04-30 04:11:51 +03:00
Alexei Stukov df7f12d5bd v1.78 public test 2017-04-30 04:11:22 +03:00
DeathStrikeV f01ea2473c Updated FFZ emotes =3 2017-04-27 00:56:32 +01:00
pohky 32b6e6dc48 Merge pull request #466 from DeathStrikeV/master
Updated FFZ emotes =3
2017-04-26 10:24:52 +02:00
DeathStrikeV d71acb07fd Updated emotes 2017-04-24 18:36:19 +01:00
pohky b92989ac14 Merge pull request #465 from DeathStrikeV/master
More FFZ emotes =)
2017-04-21 14:56:07 +02:00
DeathStrikeV d517bae2d3 Updated emotes 2017-04-17 03:28:15 +01:00
pohky 889a415314 Merge pull request #463 from DeathStrikeV/master
More FFZ emotes =)
2017-04-16 02:09:00 +02:00
David 77d72d6284 Update emotefilter.json 2017-04-14 18:32:14 -04:00
DeathStrikeV 206685c29d Updated emotes 2017-04-09 13:34:39 +01:00
DeathStrikeV 3b1c5ee3a8 Updated emotes 2017-04-03 00:38:45 +01:00
pohky a17497d9a4 Merge pull request #460 from DeathStrikeV/master
More FFZ Emotes =)
2017-04-02 12:19:52 +02:00
DeathStrikeV cc64dfa958 Updated emotes 2017-04-02 10:02:31 +01:00
DeathStrikeV f7ab2a5b59 Updated emotes 2017-03-30 01:04:54 +01:00
pohky 8230b05046 Merge pull request #459 from DeathStrikeV/master
More FFZ emotes =)
2017-03-26 23:34:03 +02:00
DeathStrikeV 29c91bdfdf Updated emotes 2017-03-26 20:16:52 +01:00
pohky bd34bd6157 Merge pull request #455 from DeathStrikeV/master
More FFZ Emotes =D
2017-03-24 22:33:22 +01:00
Violetnred2 70ef5cd327 Update emotefilter.json
filtering out few extra single word emotes that does not represent their word well
2017-03-23 13:28:24 +02:00
DeathStrikeV c3450d50c4 Updated emotes 2017-03-21 21:12:00 +00:00
DeathStrikeV e4796621b7 Updated emotes 2017-03-17 00:11:29 +00:00
pohky aefd07995d Merge pull request #454 from DeathStrikeV/master
More ffz emotes
2017-03-12 16:07:18 +01:00
DeathStrikeV b7f46fd7f4 Updated emotes 2017-03-12 03:00:25 +00:00
DeathStrikeV 36d68836d4 Updated emotes 2017-03-10 18:35:03 +00:00
Alexei Stukov 897be73f09 Merge pull request #453 from DeathStrikeV/master
More FFZ emotes
2017-03-06 23:11:40 +02:00
DeathStrikeV 3e89697b4f Updated emotes 2017-03-06 20:42:16 +00:00
DeathStrikeV b78666140a Updated emotes 2017-03-04 00:45:09 +00:00
DeathStrikeV 52e8bc512d Merge pull request #12 from Jiiks/master
Merge updates
2017-03-03 18:56:09 +00:00
DeathStrikeV bb50c6f48e Updated emotes 2017-03-03 18:54:54 +00:00
Alexei Stukov b02340a130 Merge pull request #452 from Violetnred2/patch-1
Update emotefilter.json
2017-03-03 15:44:13 +02:00
Alexei Stukov 319e6db4fc Remove excess comma 2017-03-03 15:43:44 +02:00
Violetnred2 5c52b3b987 Update emotefilter.json
blacklist some LoL champion names plus assorted words
2017-03-03 13:58:09 +02:00
Alexei Stukov 72c2585e6a Merge pull request #450 from SomeGuyNamedDavid/patch-2
Blacklist emotes
2017-02-28 10:42:05 +02:00
Alexei Stukov a64dfa8bf0 missing comma 2017-02-28 10:41:33 +02:00
Alexei Stukov f35e867358 Merge branch 'master' into patch-2 2017-02-28 10:40:59 +02:00
David b200229b26 Update emotefilter.json 2017-02-27 16:55:51 -05:00
Alexei Stukov 770eae466e Merge pull request #449 from Zerthox/patch-1
Add "Technical" to emotefilter
2017-02-27 13:01:31 +02:00
David 6a86149b63 Blacklist emotes 2017-02-26 22:09:22 -05:00
DeathStrikeV b6833d2962 Merge branch 'master' of github.com:DeathStrikeV/BetterDiscordApp 2017-02-26 22:37:30 +00:00
DeathStrikeV a976753b93 Updated emotes 2017-02-26 22:36:45 +00:00
Zerthox e0885c6d6a Add Technical 2017-02-24 13:47:14 +01:00
DeathStrikeV 717586cee1 Merge pull request #11 from Jiiks/master
Update
2017-02-23 22:38:48 +00:00
Jiiks 23724784e2 Merge pull request #447 from DeathStrikeV/master
More updated emotes =D
2017-02-23 19:41:53 +02:00
DeathStrikeV e26b1db0c4 Updated emotes 2017-02-22 00:41:28 +00:00
DeathStrikeV c687da23fe Updated emotes 2017-02-18 00:15:26 +00:00
DeathStrikeV e509f16648 Updated emotes 2017-02-17 00:32:43 +00:00
DeathStrikeV 1919061656 Updated emotes 2017-02-15 18:47:13 +00:00
Jiiks 90fd6199a1 Merge pull request #446 from jjtcm/master
Add "Profi" to emotefilter
2017-02-14 00:55:39 +02:00
jjtcm d6aabd89ae Add "Profi" to emotefilter 2017-02-13 18:45:55 +01:00
DeathStrikeV 406ced863f Updated emotes 2017-02-12 22:51:38 +00:00
DeathStrikeV 1d9e4753be Merge branch 'master' of github.com:DeathStrikeV/BetterDiscordApp 2017-02-12 21:20:19 +00:00
DeathStrikeV aad61c5281 Updated emotes 2017-02-12 21:05:22 +00:00
DeathStrikeV 3543b57f53 Updated emotes 2017-02-12 15:29:04 +00:00
Jiiks fb927b093a Merge pull request #445 from DeathStrikeV/master
Added "Seriously" to emotesfilter
2017-02-12 16:10:38 +02:00
Jiiks 01cfee0ebd Fixed indent 2017-02-12 16:10:12 +02:00
DeathStrikeV c811e2a064 Added "Seriously" to emotesfilter 2017-02-12 09:25:43 +00:00
DeathStrikeV 92e992abd2 Merge pull request #10 from Jiiks/master
Pull latest changes
2017-02-12 09:04:55 +00:00
Jiiks d8feba59ea deprecate branch 2017-02-12 00:37:49 +02:00
Jiiks 11190a8a4c Merge pull request #288 from sarnex/master
Update Linux support to 0.0.13
2017-02-10 16:00:38 +02:00
Jiiks 143602a729 More case sentivity fixes 2017-02-10 15:58:37 +02:00
Jiiks 713e9e93d3 Fixed case sensitivity for storage file 2017-02-10 15:55:13 +02:00
Jiiks beb013122f Merge pull request #436 from mkody/fix-version-config
Update version of BD in config.json
2017-02-10 15:54:00 +02:00
Jiiks f7fa19dcf8 Conflict merge
https://github.com/Jiiks/BetterDiscordApp/pull/424
2017-02-10 15:52:14 +02:00
Jiiks 44073ed15d Conflict merge
https://github.com/Jiiks/BetterDiscordApp/pull/433
2017-02-10 15:50:16 +02:00
Jiiks 031c64271a Conflict merge
https://github.com/Jiiks/BetterDiscordApp/pull/420
2017-02-10 15:48:56 +02:00
Jiiks 79d9c6f00c Conflict merge
https://github.com/Jiiks/BetterDiscordApp/pull/432
2017-02-10 15:46:12 +02:00
Jiiks 391b6a2085 Merge pull request #426 from Zerthox/patch-5
Add Spooky, Spaghetti, Rucksack, Rein, Moin to emotefilter
2017-02-10 15:42:18 +02:00
Jiiks 0c22d475c3 Merge pull request #438 from SapiensAnatis/patch-1
add 'the'
2017-02-10 15:37:51 +02:00
Jiiks e8e52cf7c6 Merge pull request #442 from brodycas3/master
Add Minecraft to emote filter
2017-02-10 14:52:12 +02:00
Jiiks b6e2ca2670 Merge pull request #443 from NooB-AssassinZ3/patch-1
Fixing error in Linux
2017-02-05 16:38:18 +02:00
NooB-AssassinZ3 e06509ca0a Fixed with install path 2017-02-05 07:12:16 -06:00
NooB-AssassinZ3 cc4df4ada4 FIXING YOUR BLUNDER
SERIOUSLY GUYS. CONSISTENCY
2017-02-05 07:01:54 -06:00
Jiiks de617fed27 Merge pull request #434 from DeathStrikeV/master
Updated emotes
2017-01-31 21:38:50 +02:00
DeathStrikeV 59c931191b Updated emotes 2017-01-31 19:16:17 +00:00
Zerthox ca3859d343 Add Moin 2017-01-31 12:04:23 +01:00
brodycas3 30df5f6158 Update emotefilter.json 2017-01-29 21:23:46 -05:00
DeathStrikeV f15b0dee3d Updated emotes 2017-01-29 22:52:57 +00:00
Nick Sarnie ddda646afc Merge pull request #1 from mkody/fix-mainjs-linux
Change linux path to use the $HOME/.config folder
2017-01-29 12:28:42 -05:00
Nick Sarnie be22c14356
Update Linux support to 0.0.14
Signed-off-by: Nick Sarnie <commendsarnex@gmail.com>
2017-01-29 12:27:32 -05:00
MKody f08539d5f9
Fix path to the bdStorage.json for case-sensitive partitions 2017-01-29 12:27:32 -05:00
MKody ef10e075f6
Update version of BD in config.json 2017-01-29 12:27:32 -05:00
MKody c6f85e545f Change linux path to use the $HOME/.config folder 2017-01-29 15:37:51 +01:00
MKody 0f2812bc10 Update version of BD in config.json 2017-01-29 15:37:17 +01:00
Jiiks 513fb57621 Removed garbage 2017-01-28 03:48:36 +02:00
Jiiks 0878f4ab00 Merge pull request #440 from EhsanKia/bttv-update-jan18
Fully update BTTV db, removing ~6k deleted emotes and adding ~14k new ones
2017-01-28 02:42:06 +02:00
DeathStrikeV dc18638567 Updated emotes 2017-01-28 00:05:11 +00:00
noodlebox e793920ed9 Use path for stable release as Linux default 2017-01-26 18:03:52 -06:00
noodlebox b6bdaedb6d Add sane default paths for Linux 2017-01-26 00:24:52 -06:00
noodlebox 3431d30ac2 Add default install path for OSX 2017-01-25 23:04:28 -06:00
DeathStrikeV c74e9c1030 Updated emotes 2017-01-23 00:58:07 +00:00
Jiiks 5daf0bbdc5 Added z-index to minimal mode restore button 2017-01-23 01:43:18 +02:00
Jiiks 604ec38101 Fix localStorage path
Removed extra `/`
2017-01-22 20:01:17 +02:00
Jiiks fcfd75346b Change localStorage path 2017-01-22 20:00:24 +02:00
DeathStrikeV 6768b064f7 Updated emotes 2017-01-19 19:23:26 +00:00
Ehsan Kia 71124e0129 Fully update BTTV emotes, removing 6000 404'd emotes and adding around 14k new ones. 2017-01-18 21:18:31 -08:00
noodlebox 43aae6ac72 Fix default Discord path for OSX 2017-01-18 04:12:35 -06:00
noodlebox 5a4e121e2b Fix missing value for OSX 2017-01-18 03:40:01 -06:00
SapiensAnatis 810b0fcee2 add 'the'
yeah
2017-01-16 19:13:18 +00:00
DeathStrikeV 5120488766 Updated emotes 2017-01-13 21:37:19 +00:00
DeathStrikeV 8e9ebaa853 Updated emotes 2017-01-13 02:04:51 +00:00
Jiiks d862285c63 make proxystorage return null instead of undefined 2017-01-11 20:59:24 +02:00
Jiiks 52c4114148 1.77
Fixed empty data loading and added localstorage proxy
2017-01-11 12:55:08 +02:00
Jiiks 19feb05e9b Really fixed customcss and favourite emotes loading 2017-01-11 12:51:37 +02:00
Jiiks 47a36a2e56 Fixed customcss and fav emotes load handling 2017-01-11 12:46:18 +02:00
Jiiks e1fd1f0df7 Custom localStorage for old plugin compatibility 2017-01-11 12:43:46 +02:00
Jiiks 46fe0f7c37 Actually write on setItem 2017-01-11 11:40:17 +02:00
Jiiks 00dfb68677 Actually supply a filename and run the function 2017-01-11 11:25:20 +02:00
Jiiks 0a55c0edae Logging 2017-01-11 11:23:15 +02:00
Jiiks 33162a1798 Localstorage fix so old plugins can work 2017-01-11 11:21:17 +02:00
DeathStrikeV a6f53183c1 Updated emotes 2017-01-09 21:49:20 +00:00
Jiiks b0b24974e6 alt storage release 2017-01-09 10:38:52 +02:00
Jiiks 7ff3971168 Use individual storages per plugin 2017-01-09 08:32:58 +02:00
Jiiks ba56f3bf6e Updated to comply with the new storage spec 2017-01-09 08:29:18 +02:00
Jiiks b7851955b2 Updated to use individual storage files for plugins 2017-01-09 08:15:00 +02:00
Jiiks 5784e45e87 Updated emote blacklist to use the new storage 2017-01-09 07:46:58 +02:00
Jiiks 186d6c9bc5 Alternate storage lib fix 2017-01-09 07:42:14 +02:00
Jiiks 6e1816d973 Alternate storage fix 2017-01-09 07:41:36 +02:00
DeathStrikeV 5e23ad66af Updated emotes 2017-01-06 17:28:44 +00:00
DeathStrikeV 788d20e452 Updated emotes 2017-01-06 12:42:32 +00:00
DeathStrikeV 032b69d564 Updated emotes 2017-01-05 13:20:22 +00:00
DeathStrikeV 01a55116b0 Updated emotes 2017-01-05 13:17:20 +00:00
DeathStrikeV 31603634ce Updated emotes 2017-01-05 03:37:23 +00:00
Jiiks 9c99e8a27d Merge pull request #428 from DeathStrikeV/master
Updated emotes
2017-01-05 04:23:21 +02:00
DeathStrikeV f2d4680698 Updated emotes 2017-01-02 22:12:25 +00:00
Jacob Foster 028b96589e Reduce cases in Node installer 2017-01-02 03:46:50 -06:00
Zerthox b4bc6ff109 Add Dirk 2016-12-31 20:24:44 +01:00
DeathStrikeV e21c1dc28a Updated emotes 2016-12-31 10:54:51 +00:00
DeathStrikeV bebf352bd0 Updated emotes 2016-12-29 23:29:16 +00:00
Jiiks 8369decbfc Merge pull request #425 from DeathStrikeV/master
More emote updates
2016-12-24 14:17:18 +02:00
DeathStrikeV 1111b98767 Updated emotes 2016-12-24 11:09:20 +00:00
DeathStrikeV ffb456c466 Updated emotes 2016-12-22 23:21:20 +00:00
DeathStrikeV 68247caf66 Updated emotes 2016-12-20 07:38:43 +00:00
Zerthox c65b760ca1 Add Spooky, Spaghetti, Rucksack, Rein 2016-12-19 19:18:31 +01:00
DeathStrikeV 8e4b5f6ee0 Updated emotes 2016-12-17 22:10:30 +00:00
DeathStrikeV 6e08a4b1ed Updated emotes 2016-12-17 12:26:26 +00:00
DeathStrikeV 0b26620901 Updated emotes 2016-12-17 08:23:40 +00:00
DeathStrikeV d4c8f04331 Merge pull request #9 from Jiiks/master
Update to latest
2016-12-17 07:23:23 +00:00
DeathStrikeV 67f0257cb4 Updated emotes 2016-12-17 07:20:25 +00:00
pohky a2de68ec1f Update emotefilter.json
Added Bella
2016-12-16 23:22:19 +01:00
DeathStrikeV 93115073e9 Updated emotes 2016-12-13 23:11:30 +00:00
DeathStrikeV 19f5f9f7a5 Updated emotes 2016-12-13 08:27:48 +00:00
Jiiks 131eab393d Merge pull request #418 from Zerthox/patch-3
Added Meow, Hartz, Brille, Affe, Baby, YOUTUBE to emote filter
2016-12-12 22:44:18 +02:00
Jiiks 8f7cc5e06f Merge pull request #419 from elnormous/installer_fix
Fix Node installer
2016-12-12 22:43:37 +02:00
Jiiks b46e797728 Merge pull request #417 from DeathStrikeV/master
More FFZ emotes, duplicates/filtered emotes can be accessed with ~# modifier (e.g. FeelsBadMan~1)
2016-12-12 22:43:22 +02:00
DeathStrikeV 42898de340 Updated emotes 2016-12-12 20:33:40 +00:00
Zerthox 65fda6f4e7 Added YOUTUBE 2016-12-12 20:01:55 +01:00
Zerthox e15af62927 Added Baby 2016-12-12 19:58:18 +01:00
DeathStrikeV d2a7c6734a Updated emotes 2016-12-10 07:39:51 +00:00
Zerthox 1b9eb941d2 Added Affe 2016-12-09 20:59:12 +01:00
Zerthox 59263be1b5 Added Brille 2016-12-09 20:35:32 +01:00
DeathStrikeV df2b647750 Updated emotes 2016-12-08 05:01:16 +00:00
DeathStrikeV 4e0a23ec03 Updated emotes 2016-12-07 01:39:00 +00:00
DeathStrikeV beae2087a8 Updated emotes 2016-12-06 19:49:43 +00:00
Jiiks 2039252e69 Fixed bd server join button 2016-12-05 22:05:48 +02:00
Elviss Strazdins 1219eb76bc Fix Node installer 2016-12-05 15:05:25 +02:00
DeathStrikeV 31a1fcfc46 Updated emotes 2016-12-05 11:13:33 +00:00
DeathStrikeV 37731b9fa7 Merge branch 'master' of github.com:DeathStrikeV/BetterDiscordApp 2016-12-02 21:38:41 +00:00
DeathStrikeV 2d8120fc1e Updated emotes 2016-12-02 21:38:09 +00:00
DeathStrikeV bd0e1b135e Merge pull request #8 from Jiiks/master
Update to latest
2016-12-02 10:23:05 +00:00
Jiiks 9a2b4fb8b2 Hide serverlist on join 2016-12-02 12:03:09 +02:00
Jiiks e7b9be97b0 Unliteral 2016-12-02 11:59:40 +02:00
Jiiks 5cea881ed9 Open invite codes in browser 2016-12-02 11:58:11 +02:00
DeathStrikeV e40b9fe82c Updated emotes 2016-12-02 09:54:24 +00:00
Jiiks c14c4255eb Fix icode regex 2016-12-02 11:42:54 +02:00
Jiiks fec2679fc8 icxss 2016-12-02 11:28:41 +02:00
Jiiks 520ca3faea icxss 2016-12-02 11:27:48 +02:00
Jiiks c8e906b00d Fix tags and minify 2016-12-02 09:24:44 +02:00
Jiiks 9bddcaa181 Undefined check for unsafes 2016-12-02 09:20:53 +02:00
Jiiks aa4877d851 live debug 2016-12-02 09:19:37 +02:00
Jiiks a9a2d09ae0 return not continue 2016-12-02 09:18:51 +02:00
Jiiks 422c18917c Ignore servers with undefined invite codes 2016-12-02 09:16:58 +02:00
Jiiks ccdc5f1a9f Fixed publicservers categories 2016-12-02 09:14:00 +02:00
Jiiks 080141e7d0 Fixed publicservers identifier filter 2016-12-02 09:10:51 +02:00
Jiiks b55bd54b29 Fixed publicserver search 2016-12-02 09:03:40 +02:00
Jiiks 8c0951a0ea Updated public servers endpoint 2016-12-02 07:36:41 +02:00
DeathStrikeV bb5744dfe9 Updated emotes 2016-11-29 21:36:09 +00:00
DeathStrikeV 5bf2597030 Updated emotes 2016-11-28 23:38:15 +00:00
DeathStrikeV ade5cbc446 Updated emotes 2016-11-28 13:45:55 +00:00
DeathStrikeV 35ca5f6339 Updated emotes 2016-11-28 07:03:14 +00:00
DeathStrikeV 97c259f1c4 Updated emotes 2016-11-27 20:48:51 +00:00
DeathStrikeV 8eedc29d71 Updated emotes 2016-11-27 12:33:46 +00:00
DeathStrikeV 3975eabca0 Updated emotes 2016-11-27 11:10:46 +00:00
DeathStrikeV 1b99b6289a Updated emotes 2016-11-25 07:36:15 +00:00
DeathStrikeV 0b9fb52800 Updated emotes 2016-11-25 06:34:40 +00:00
DeathStrikeV f1a0f11257 Updated emotes 2016-11-24 09:55:07 +00:00
DeathStrikeV dea323a0b8 Updated emotes 2016-11-23 07:30:50 +00:00
Zerthox c0bd71fe7d Added Meow & Hartz 2016-11-21 19:57:26 +01:00
DeathStrikeV 85093234fa Updated emotes 2016-11-20 09:44:32 +00:00
DeathStrikeV 13e21fb052 Updated emotes 2016-11-19 19:56:18 +00:00
DeathStrikeV e592126078 Updated emotes 2016-11-19 14:40:30 +00:00
DeathStrikeV 35de874ced Updated emotes 2016-11-18 02:00:28 +00:00
DeathStrikeV cdc95aef68 Updated emotes 2016-11-16 23:17:58 +00:00
DeathStrikeV 08cc4c5bc3 Updated emotes 2016-11-16 01:35:32 +00:00
DeathStrikeV 5c514efa96 Updated emotes 2016-11-16 01:31:48 +00:00
DeathStrikeV a9bc977764 Updated emotes 2016-11-16 00:12:44 +00:00
DeathStrikeV 2fa3e7a4b5 Updated emotes 2016-11-15 21:06:06 +00:00
DeathStrikeV 9b4f5f4366 Updated emotes 2016-11-15 07:57:48 +00:00
DeathStrikeV 2b55554af1 Updated emotes 2016-11-14 22:33:50 +00:00
DeathStrikeV 5aff38bf39 Updated emotes 2016-11-13 22:36:49 +00:00
Jiiks 53d4989a79 Merge pull request #415 from DeathStrikeV/master
More FFZ Emotes
2016-11-13 06:35:58 +02:00
Jiiks d23d331463 Merge pull request #414 from Zerthox/patch-2
Added "Snorlax" (Broken)
2016-11-13 06:35:47 +02:00
DeathStrikeV 020b1b8d4e Updated emotes 2016-11-12 18:07:45 +00:00
DeathStrikeV e251a03914 Merge pull request #7 from Jiiks/master
Pull latest updates
2016-11-11 19:14:50 +00:00
DeathStrikeV 1faac18e8d Updated emotes 2016-11-11 19:14:13 +00:00
DeathStrikeV a23878fd0b Updated emotes 2016-11-11 07:29:05 +00:00
Zerthox 56773ae55f Added "Snorlax" (Broken) 2016-11-10 19:22:07 +01:00
Jiiks dd28c89236 Merge pull request #413 from TakosThings/patch-1
Add "Bomb" to filter
2016-11-10 15:48:17 +02:00
DeathStrikeV 14331ddee5 Merge branch 'master' of github.com:DeathStrikeV/BetterDiscordApp 2016-11-10 07:29:45 +00:00
DeathStrikeV b1a06a519f Updated emotes 2016-11-10 07:28:27 +00:00
TakosThings cc1938b14b Add "Bomb" to filter 2016-11-10 04:35:26 +10:30
Jiiks c4e0cc15c9 Merge pull request #406 from Leeo97one/patch-1
Electron installer fix
2016-11-09 10:41:31 +02:00
Jiiks 6651b5ac3f Merge pull request #410 from DeathStrikeV/master
More FFZ Emotes
2016-11-09 05:30:45 +02:00
DeathStrikeV faa7b30df5 Merge pull request #6 from Jiiks/master
Update to latest changes
2016-11-08 19:53:25 +00:00
DeathStrikeV 9a638e7eb3 Updated emotes 2016-11-08 19:38:07 +00:00
DeathStrikeV 06770ca1af Merge branch 'master' of github.com:DeathStrikeV/BetterDiscordApp 2016-11-08 07:31:08 +00:00
DeathStrikeV 337a79efbb Updated emotes 2016-11-08 07:29:51 +00:00
Jiiks fd3dab39de Merge pull request #409 from Zerthox/patch-1
Added "Nein" and "Pokeball" to emote filter
2016-11-07 22:32:01 +02:00
Zerthox 84092e1c6f Add "Nein" and "Pokeball" 2016-11-07 21:17:28 +01:00
Jiiks 77addb5b03 Merge pull request #408 from DeathStrikeV/master
More emotes - Pull at your own leisure
2016-11-07 22:09:54 +02:00
DeathStrikeV 68e56d9ea8 Merge pull request #5 from Jiiks/master
Pull latest changes
2016-11-07 19:24:08 +00:00
Jiiks 71b0077fc0 Formatting 2016-11-07 20:46:14 +02:00
DeathStrikeV 2e64e4c47b Updated emotes 2016-11-06 23:46:21 +00:00
Léo c4f4ac41e8 Electron installer fix
Fix the index.js file path in the Electron installer.
2016-11-06 12:03:29 +01:00
Jiiks 07f38008d8 Merge pull request #405 from EhsanKia/bttv-update-nov5
Bttv update nov5
2016-11-06 09:54:24 +02:00
Ehsan Kia 5c70075ca0 Merge branch 'master' of github.com:Jiiks/BetterDiscordApp into bttv-update-nov5
# Conflicts:
#	data/emotedata_ffz.json
2016-11-06 00:48:42 -07:00
Jiiks e09fb169ae Merge pull request #404 from DeathStrikeV/master
More emote updates GG
2016-11-06 08:32:50 +02:00
Ehsan Kia dc48d88d59 Update BTTV emote db 2016-11-05 16:27:00 -07:00
Ehsan Kia 227547d7e7 Remove ImTriggered from FFZ 2016-11-05 16:24:35 -07:00
DeathStrikeV 00da2ef58c Updated emotes 2016-11-05 22:35:26 +00:00
DeathStrikeV 195e8a9b77 Updated emotes 2016-11-05 12:11:29 +00:00
DeathStrikeV 7cb778f884 Updated emotes 2016-11-05 01:56:58 +00:00
DeathStrikeV 289abee257 Updated emotes 2016-11-05 00:07:28 +00:00
DeathStrikeV 2c49e52f90 Merge branch 'master' of github.com:DeathStrikeV/BetterDiscordApp 2016-11-04 22:43:53 +00:00
DeathStrikeV 07968430e3 Updated emotes 2016-11-04 22:43:27 +00:00
Alex e10b78dc9b Merge pull request #4 from Jiiks/master
Updates
2016-11-04 22:42:10 +00:00
Jiiks a1f9f29198 Changed info arrow colour 2016-11-04 07:11:52 +02:00
Jiiks 0b614022ad Final logger format maybe 2016-11-04 07:11:22 +02:00
Jiiks 821a9f8749 Reformatted logger again 2016-11-04 07:03:39 +02:00
Jiiks 1bb83de279 Reformatted logs 2016-11-04 06:51:56 +02:00
Jiiks 48e55c9417 Timestamps and init log 2016-11-04 06:49:51 +02:00
Jiiks 5dc6327fda Loggers 2016-11-04 06:46:02 +02:00
DeathStrikeV e1470dab3e Updated emotes 2016-11-04 00:06:53 +00:00
DeathStrikeV ab0e948fe4 Updated emotes 2016-11-03 20:43:07 +00:00
Jiiks d5f16c0b2d Merge pull request #403 from DeathStrikeV/master
Updated FFZ emotes
2016-11-03 01:06:20 +02:00
Alex 66c24f246a Merge pull request #3 from Jiiks/master
Updating to latest
2016-11-02 21:28:33 +00:00
DeathStrikeV 27b1978515 Updated emotes 2016-11-02 21:22:04 +00:00
Jiiks 8df7431743 Skeletons 2016-11-02 07:38:32 +02:00
Jiiks c3443b5725 added Okie 2016-11-02 07:38:03 +02:00
DeathStrikeV 5e466e79fd Updated emotes 2016-11-01 08:07:46 +00:00
Jiiks 4f549676bc Merge pull request #392 from DeathStrikeV/master
FFZ Emote Update
2016-11-01 05:50:31 +02:00
Jiiks cfd651eaab Updated plugin base 2016-11-01 05:44:51 +02:00
Jiiks 6d58d8f2f8 event and plugin bases 2016-11-01 05:42:15 +02:00
Jiiks 1a7d84a14c Added resource injection, fixed timestamps, ignores 2016-10-31 20:33:04 +02:00
Jiiks 376471cb2d added noclean grunt tasks 2016-10-31 19:24:51 +02:00
Jiiks 3eea2eacc3 Client side skeleton and grunt config for js 2016-10-31 19:20:34 +02:00
Jiiks 9416be4105 Added resources downloader and hash getter 2016-10-31 18:47:59 +02:00
Jiiks e7b56fe792 Reformatted logger, added eventhook and tests
Standalone test file skeleton
2016-10-31 18:40:55 +02:00
Jiiks 7f5986aa01 {} convention, logs, exit and hook skeleton 2016-10-31 18:05:51 +02:00
Jiiks fc53df5e4b Default configs 2016-10-31 17:57:12 +02:00
Jiiks c5454a8f57 v2 initial slow track 2016-10-31 17:36:03 +02:00
DeathStrikeV 3d381b7ca1 Updated emotes 2016-10-30 21:56:27 +00:00
DeathStrikeV 469cb2a2da Updated emotes 2016-10-29 21:09:50 +01:00
DeathStrikeV 8b57885002 Updated emotes 2016-10-29 00:36:56 +01:00
DeathStrikeV 3429d6c8ca Updated emotes 2016-10-28 07:58:50 +01:00
Jiiks 28ad0c0acc Merge pull request #401 from EhsanKia/fix-lul
Change BTTV emote length to 3 (allowing LUL)
2016-10-25 20:17:29 +03:00
Jiiks 70c6eaca03 Merge pull request #400 from EhsanKia/bttv-update-oct16
Updated BTTV emote database
2016-10-25 20:17:23 +03:00
DeathStrikeV a80d16fbd8 Updated emotes 2016-10-20 08:07:38 +01:00
Ehsan Kia 4fa0825bc7 Change BTTV emote length to 3 (allowing LUL) 2016-10-17 00:19:29 -07:00
Ehsan Kia 2db776f93a Updated BTTV emote database 2016-10-16 19:01:11 -07:00
DeathStrikeV e330ff197d Updated emotes 2016-10-16 19:52:23 +01:00
DeathStrikeV b002ae6130 Updated emotes 2016-10-11 09:41:09 +01:00
DeathStrikeV 5c27d91fde Updated emotes 2016-10-09 22:02:09 +01:00
DeathStrikeV 5f94a8b155 Updated emotes 2016-10-08 17:13:27 +01:00
DeathStrikeV f18f353501 Updated emotes 2016-10-08 16:33:12 +01:00
DeathStrikeV 0e2bf5b1c4 Updated emotes 2016-10-07 20:05:05 +01:00
DeathStrikeV ea34f260df Updated emotes 2016-10-07 20:02:43 +01:00
DeathStrikeV 56f590dbf4 Updated emotes 2016-10-07 19:37:07 +01:00
DeathStrikeV 54709b608a Updated emotes 2016-10-07 10:58:51 +01:00
DeathStrikeV aaea907eac Updated emotes 2016-10-06 23:01:55 +01:00
DeathStrikeV ebb99040e4 Updated emotes 2016-10-06 22:43:01 +01:00
DeathStrikeV d874f6becc Updated emotes 2016-10-06 20:09:35 +01:00
DeathStrikeV f3d8865df5 Updated emotes 2016-10-06 00:36:17 +01:00
DeathStrikeV 9098bca396 Updated emotes 2016-10-05 19:42:21 +01:00
DeathStrikeV e7bda2e6c1 Updated ffz emotes 2016-10-02 21:16:52 +01:00
Alex a8534308b7 Merge pull request #2 from Jiiks/master
Update
2016-10-02 21:15:18 +01:00
Jiiks 24eb3f3d9d Merge pull request #389 from EhsanKia/bttv-update-sep21
Add new bttv emotes
2016-09-21 13:19:32 +03:00
Ehsan Kia ad2f98107a Add new bttv emotes 2016-09-21 00:47:21 -07:00
noodlebox b9b28c0bd9 Fix AutoPlayGifs plugin 2016-09-10 05:06:17 -05:00
pohky 2b361cbcc3 Merge pull request #381 from EhsanKia/bttv-update-sep5
Added new bttv emotes
2016-09-07 19:05:14 +02:00
Ehsan Kia 39505125fd Added new bttv emotes 2016-09-05 15:44:04 -07:00
Jiiks 48d4a58102 ayy and indent 2016-08-16 12:24:55 +03:00
pohky c51bb8cc43 Merge pull request #366 from EhsanKia/bttv-update-aug15
Adding new BTTV emotes
2016-08-16 05:21:16 +02:00
Ehsan Kia 51ae2698c4 Adding new BTTV emotes 2016-08-15 21:55:01 -04:00
pohky 501f38357f FFZ Emote Update 2016-08-16 02:32:19 +02:00
Jiiks 2fc35436a4 Fixed replace 2016-08-15 02:03:18 +03:00
Jiiks b87e0781f6 User input escapes 2016-08-15 02:00:09 +03:00
Jiiks fe1a30027a Merge pull request #362 from Cyken-Zeraux/patch-2
Canary 0.0.138 Support
2016-08-12 21:14:01 +03:00
pohky eb58553ade Update emotefilter.json 2016-08-12 04:54:22 +02:00
Jiiks b28ef7abc5 Publicservers user data escape 2016-08-11 17:53:25 +03:00
Jiiks 8625b1bdbf Added uri encoding 2016-08-11 17:30:37 +03:00
Yozora 9ae3b5ba69 Remove unnecessary line of code
I forgot to delete this line before committing the file
2016-08-06 23:48:46 +02:00
pohky 42971a5714 Update emotefilter.json 2016-08-06 23:47:03 +02:00
pohky 7bd1a219cd Update emotefilter.json 2016-08-06 23:46:34 +02:00
CZauX 336152802a Canary 0.0.138 Support
app.asar extracts to resources/app, not resources/app/app. Fixed pathing for index.js to check both locations and display error if not found rather than crashing.

Also added splice file detection, errors out instead of crashes.
2016-08-06 10:06:35 -05:00
Yozora d067bc2cfc Added version-agnostic uninstaller for Windows
This uninstaller.bat removes BetterDiscord from all app-* folders in %localappdata%\Discord\ and restarts Discord afterwards.
2016-08-06 12:50:27 +02:00
pohky f751f540ec Update emotefilter.json 2016-08-04 22:13:27 +02:00
pohky bd576ef69c Update emotefilter.json 2016-08-04 16:14:20 +02:00
pohky d186bc9218 Update emotefilter.json 2016-08-03 22:22:48 +02:00
pohky ef8ca8fd15 Update emotefilter.json 2016-08-03 06:26:02 +02:00
Jiiks 9e4f6ccf25 Added some emotes 2016-08-02 19:50:14 +03:00
pohky d377cef33c FFZ Emotes Update 2016-08-02 14:44:31 +02:00
pohky 99afa4ccc7 Merge pull request #358 from EhsanKia/bttv-update-aug1
Fix stupid javascript issue
2016-08-01 21:37:46 +02:00
Ehsan Kia 320a68f8cb Fix stupid javascript issue 2016-08-01 15:34:01 -04:00
pohky b09590e8e7 Merge pull request #357 from EhsanKia/bttv-update-aug1
BTTV database update
2016-08-01 21:20:45 +02:00
Ehsan Kia 4b63daaf48 BTTV database update 2016-08-01 15:16:30 -04:00
Jiiks d26247bbd6 v1.74 minor fixes
Fixed bd invite link and dev mode breaking
2016-07-31 01:47:35 +03:00
pohky 0ab1fe3f19 Update emotefilter.json 2016-07-25 10:31:12 +02:00
pohky 00ff05bfe0 Update emotefilter.json 2016-07-25 07:05:18 +02:00
pohky 2bd94b9ae4 Merge pull request #355 from EhsanKia/bttv-update-july24
BTTV database update july 24
2016-07-24 22:15:14 +02:00
Ehsan Kia 6d1b7667b8 BTTV database update july 24 2016-07-24 16:13:23 -04:00
Jiiks 51cf6e531c Pre-release, windows and linux support
Missing error handling, uninstall and advanced options
2016-07-22 11:56:15 +03:00
Jiiks e5d91a8564 Rebase 2016-07-22 11:52:05 +03:00
pohky 91fcf59656 Update emotefilter.json 2016-07-22 10:22:36 +02:00
pohky 20337f3f36 Update emotefilter.json 2016-07-22 06:37:19 +02:00
pohky 7eac80b59f Update emotefilter.json 2016-07-21 00:38:22 +02:00
pohky 8c2e38662c Update emotefilter.json 2016-07-20 21:14:37 +02:00
pohky 31617f79b3 FFZ Emotes Update 2016-07-20 15:22:20 +02:00
pohky 08ec6a4ddb Merge pull request #352 from EhsanKia/bttv-update-july18
updated bttv db emote
2016-07-20 00:15:27 +02:00
Ehsan Kia 1a394c75c9 updated bttv db emote 2016-07-18 20:09:22 -04:00
pohky b604daf201 Update emotefilter.json 2016-07-16 10:54:10 +02:00
pohky 2eb0f8d9c7 Update emotefilter.json 2016-07-13 07:37:37 +02:00
pohky 839c06d968 Update emotefilter.json 2016-07-12 12:26:09 +02:00
Jiiks 2b32ffac01 Create node_modules folder if it doesn't exist 2016-07-12 06:13:11 +03:00
pohky 456852070e Merge pull request #344 from EhsanKia/fix-bttv-db
Fix missing BTTV emotes
2016-07-11 18:18:24 +02:00
Ehsan Kia f2d76b2e99 Fix missing emotes 2016-07-11 10:43:42 -04:00
pohky 4d63434d51 Update emotefilter.json 2016-07-10 03:02:48 +02:00
pohky d2a6b384d3 Merge pull request #342 from EhsanKia/bttv-update-july9
New BTTV emote db update
2016-07-09 16:44:29 +02:00
Ehsan Kia ba4402a4d4 New BTTV emote db update 2016-07-09 09:50:50 -04:00
pohky d36caf0599 Update emotefilter.json 2016-07-08 11:03:03 +02:00
pohky 40dbd67e80 Update emotefilter.json 2016-07-07 23:12:33 +02:00
pohky 19393f4480 Update emotefilter.json 2016-07-06 18:48:15 +02:00
pohky 9bf4b9dcb6 Update emotefilter.json 2016-07-05 23:05:49 +02:00
pohky c07f7ac73f Update FFZ emotes 2016-07-05 23:03:16 +02:00
pohky 3ba91bfbf3 Update emotefilter.json 2016-07-02 18:11:12 +02:00
pohky 1a48e6045f Update emotefilter.json 2016-06-30 04:04:35 +02:00
Jiiks 3c62a57b96 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-06-29 12:30:31 +03:00
Jiiks 1a560a1656 added "Freddie" 2016-06-29 12:30:27 +03:00
Jiiks d2c5a95f13 Merge pull request #339 from EhsanKia/bttv-update-june26
Update BTTV db
2016-06-27 23:50:46 +03:00
Jiiks d81b806d6b Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-06-27 20:09:52 +03:00
Jiiks 9a97a5cc2e added 12h option 2016-06-27 20:09:48 +03:00
pohky 6998c5c131 Update emotefilter.json 2016-06-27 11:41:37 +02:00
pohky 01070c916c Update emotefilter.json 2016-06-27 01:46:01 +02:00
Ehsan Kia 136266be85 Update BTTV db 2016-06-26 16:45:59 -04:00
Jiiks 284838bb5c Versioning 2016-06-24 02:13:18 +03:00
Jiiks 4fa8d75653 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-06-24 02:12:47 +03:00
Jiiks ef3d2ad9b1 Updated for latest Discord version 2016-06-24 02:12:41 +03:00
pohky 995868b5b9 FFZ Emotes update 2016-06-21 04:01:47 +02:00
pohky d8457795e4 Update emotefilter.json 2016-06-20 11:44:24 +02:00
pohky 8de42e7931 Merge pull request #335 from EhsanKia/bttv-update-june19
Updated BTTV emote database
2016-06-20 03:05:05 +02:00
Ehsan Kia d8db32f389 Updated BTTV emote database 2016-06-19 17:33:25 -04:00
pohky 22513f3d27 Update FFZ emotes 2016-06-13 04:02:36 +02:00
pohky 3470dc2594 Merge pull request #330 from EhsanKia/bttv-update-june12
Updated BTTV emote database
2016-06-12 19:12:41 +02:00
Ehsan Kia f978d4b2d9 Updated BTTV emote database 2016-06-12 00:26:27 -04:00
pohky 1a40b63d04 Merge pull request #326 from EhsanKia/bttv-update-june6
Update BTTV emote database
2016-06-06 22:22:19 +02:00
Ehsan Kia 4e20898cae Update BTTV emote database 2016-06-06 09:13:44 -04:00
Jiiks 849c139124 Remove unused 2016-06-05 12:24:32 +03:00
Jiiks c1af5fd726 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-06-05 12:23:44 +03:00
Jiiks 1e79726b73 Electron installer update 2016-06-05 12:23:40 +03:00
pohky 1dfd428995 FFZ Emotes Update 2016-06-05 10:27:27 +02:00
Jiiks cfe00cd50d Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-06-04 07:41:29 +03:00
Jiiks 36d832d3e2 Installer version info 2016-06-04 07:41:25 +03:00
pohky 46f983f132 Update emotefilter.json 2016-06-03 04:35:16 +02:00
pohky f535aa5761 Update emotefilter.json 2016-06-02 19:46:09 +02:00
pohky ab07e14d7f Update emotefilter.json 2016-06-01 03:13:11 +02:00
pohky bdbc2c0110 Update emotefilter.json 2016-05-31 04:55:45 +02:00
pohky 00e64da94a Update emotefilter.json 2016-05-31 01:00:21 +02:00
pohky 0370e80071 Update FFZ Emotes 2016-05-30 21:35:51 +02:00
pohky b25201b576 Merge pull request #318 from EhsanKia/bttv-update-may26
Update BTTV emote DB
2016-05-26 07:14:00 +02:00
Ehsan Kia e6955f919d Update BTTV emote DB 2016-05-26 01:12:24 -04:00
Jiiks 8205109f29 Updater vi 2016-05-25 22:50:26 +03:00
Jiiks b277ab2c7f Versioning for updater 2016-05-25 22:21:45 +03:00
Jiiks b68a850750 Added loading/update splash base and quit modal 2016-05-25 22:14:08 +03:00
pohky b55607f1b2 Update emotefilter.json 2016-05-25 08:25:14 +02:00
pohky 3451215be9 Update emotefilter.json 2016-05-25 00:17:27 +02:00
Jiiks f649c729b2 1.73 disabled native sub emotes and added initial dev mode 2016-05-24 23:33:24 +03:00
pohky 8a786de8cc Update emotefilter.json 2016-05-24 17:07:28 +02:00
pohky e8e82cb02b Bugfix blacklisted emotes
fixed a bug where blacklisted emotes cut the text off
2016-05-24 14:29:30 +02:00
Jiiks 329d8bc55e Updated separated files 2016-05-22 19:40:14 +03:00
pohky 1137428be4 Update emotefilter.json 2016-05-22 16:55:03 +02:00
pohky d09d870d9e FFZ Emotes update 2016-05-22 07:17:14 +02:00
Jiiks ab7ccf061d Fixed server invite code 2016-05-21 22:00:32 +03:00
pohky b343b5d7c9 quick fix
open themes/plugins folder
2016-05-21 19:09:22 +02:00
Jiiks 13c1ab4be0 v1.72
Fixed emotes
Fixed public server button not showing
Changed public server api endpoint
Added public server description, tags and category search
Added mutation listener for settings panel instead of relying on defers
Fixed many small bugs
2016-05-21 12:19:29 +03:00
Jiiks 512ccd1904 Fixed typo 2016-05-20 08:14:02 +03:00
Jiiks c4a1b2bc20 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-05-20 08:12:53 +03:00
Jiiks 457f314ac3 But notice 2016-05-20 08:12:49 +03:00
pohky dde563e0eb Minimal Mode fix
hotfix
2016-05-20 06:42:49 +02:00
Jiiks b742f86ee0 v1.71
Fixed emotes, emote edits, new changelog and versioning
2016-05-20 05:30:54 +03:00
Jiiks 596b0e8490 Fixed emotes 2016-05-20 05:12:32 +03:00
pohky e9461a9830 Update emotefilter.json 2016-05-19 15:44:48 +02:00
Jiiks 178f2b464c Added Choco 2016-05-18 03:43:21 +03:00
pohky 220e75e29b Merge pull request #310 from EhsanKia/bttv-update-may15
Updated BTTV emote database
2016-05-15 14:16:33 +02:00
Ehsan Kia c7fa09505d Updated BTTV emote database 2016-05-15 00:45:28 -04:00
pohky d6c55d7e1b Update emotefilter.json 2016-05-15 01:58:02 +02:00
pohky 276b39e169 Update emotedata_ffz.json, emotefilter.json
weekly update
2016-05-15 01:19:22 +02:00
pohky 9c6b3629d3 Update emotefilter.json 2016-05-13 09:14:22 +02:00
pohky 5a636f6e9a Update emotefilter.json 2016-05-12 23:39:55 +02:00
Jiiks db31c2662a Installer base 2016-05-12 17:17:05 +03:00
pohky 66d7636228 Update emotefilter.json 2016-05-12 14:56:03 +02:00
Jiiks ae9dcd6220 Moved installers 2016-05-12 05:14:52 +03:00
Jiiks f4461ed97f Added WindowInstaller/bin/ to ignore 2016-05-12 05:09:47 +03:00
pohky 201d1fb22b Update emotefilter.json 2016-05-11 22:59:18 +02:00
pohky cb7176be5d Update emotefilter.json 2016-05-11 02:20:00 +02:00
pohky c3dff1ca6e Update emotefilter.json 2016-05-11 00:54:06 +02:00
pohky 6be4da2197 Update emotedata_ffz.json, emotefilter.json 2016-05-09 11:30:45 +02:00
pohky 5add6c9a21 Update emotefilter.json 2016-05-08 02:55:15 +02:00
pohky 2f4716714d Merge pull request #296 from EhsanKia/bttv-update-may7
Updated BTTV emote database
2016-05-07 20:21:51 +02:00
Ehsan Kia 5c3f653718 Updated BTTV emote database 2016-05-07 13:45:20 -04:00
pohky 6b8f324199 Update emotefilter.json 2016-05-07 19:21:16 +02:00
Jiiks 199aa4fa45 Updated styling 2016-05-07 18:53:52 +03:00
Jiiks 2845884954 Updated css 2016-05-07 18:51:40 +03:00
Jiiks 25e2d278a8 Updated preview image 2016-05-07 01:26:59 +03:00
pohky c86be946ee Update emotefilter.json 2016-05-07 00:17:08 +02:00
Jiiks bdf889e14f Fixed a eol bug 2016-05-07 00:44:48 +03:00
Jiiks c61af06452 Removed some unintended css 2016-05-07 00:07:46 +03:00
Jiiks 6d16dea9ac For 0.2.8 and fixed settings import 2016-05-06 23:57:38 +03:00
163 changed files with 11835 additions and 54234 deletions

View File

@ -0,0 +1,92 @@
---
name: Issue template
about: Template for all future issues
---
*Before* you create an issue, make sure you have:
1. Checked that that issue hasn't already been submitted. You can search open issues [here](https://github.com/Jiiks/BetterDiscordApp/issues).
2. Checked that there isn't an answer in either of the Discord servers (if you can access them - don't complain if you can't).
3. Checked that it isn't in the following list of frequently asked questions.
If none of that helps you, delete the prefilled contents of this issue and ask whatever question you may have *in English so we can understand it*.
### FAQ
> *BetterDiscord doesn't work.*
> *BetterDiscord won't install.*
> *BetterDiscord doesn't support macOS.*
This branch isn't being updated anymore. Until BetterDiscord v2 is released you can use [Zach Rauen's fork](https://github.com/rauenzi/BetterDiscordApp).
> *BetterDiscord doesn't support Linux.*
There's an installer script for BetterDiscord on Linux available [here](https://github.com/bb010g/betterdiscordctl).
> *BetterDiscord doesn't work in my browser.*
The browser version doesn't exist anymore. Use the desktop client.
> *BetterDiscord doesn't work on my phone.*
... and never will. BetterDiscord is a client modification for Discord's desktop Electron client. (Electron is a framework for making cross platform apps using web technologies. Basically the desktop client is just the web client in a specialised web browser.)
> *Is there any security risks involved with installing BetterDiscord?*
> *My friend was hacked after he/she installed BetterDiscord.*
*Not by itself.* However, BetterDiscord allows loading plugins. Discord, BetterDiscord, and any plugins you install (even without enabling) have full access to your system as your local user account. (Including full access to your Discord account.) So, make sure you only download plugins from sources you trust.
Also, please note that [BetterDocs](https://betterdocs.net) and other third-party sources by definition *are not* affiliated with BetterDiscord or it's developers.
> *How do I install plugin [x]?*
> *Is there a plugin to [x]?*
> *Does [x] theme exist?*
https://imgur.com/lczPQxW
> *Minimal mode broke everything.*
You can get back into Discord's settings to disable it by pressing `Control + ,` on Windows and Linux or `Command + ,` on macOS.
> *How do I completely hide messages from people I've blocked?*
Add this to your custom CSS:
```css
.message-group-blocked {
display: none !important;
}
```
> *How do I remove BetterDiscord?*
BetterDiscord is installed to the following locations:
Platform | Discord path
-------------|---------------
Windows | `%APPDATA%`\discord\0.0.`*`\modules\discord_desktop_core
macOS | ~/Library/Application Support/discord/0.0.`*`/modules/discord_desktop_core
Linux | ~/.config/discord/0.0.`*`/modules/discord_desktop_core
To remove BetterDiscord, open the file `index.js` in that directory and make sure only this line exists:
```js
module.exports = require('./core');
```
Then, delete the `core` directory.
BetterDiscord's data is stored in the following locations:
Platform | BetterDiscord data path
-------------|---------------
Windows | `%APPDATA%`\BetterDiscord
macOS | ~/Library/Preferences/BetterDiscord
Linux | ~/.config/BetterDiscord
To remove all of BetterDiscord's data, just delete that directory.
> *BetterDiscord v2?*
[BetterDiscord v2 is the new version of BetterDiscord currently in development.](https://github.com/JsSucks/BetterDiscordApp) If you'd like to help out with BetterDiscord v2, join the JsSucks Discord server. (Invite code `KYKwv4R`.) The only requirement is JavaScript/ES6 knowledge.

11
.gitignore vendored
View File

@ -9,4 +9,13 @@ Firefox/data/js/jquery-2.1.4.min.js
/nbproject/private/
node_modules
.sass-cache
/*.jiiks
/*.jiiks
Installers/dotNet/bin/
Installers/dotNet/packages/
Installers/dotNet/dlls/
v2/dist/vendor/
v2/lib/static.js
**/*.suo
Installers/**/*/bin
Installers/**/*/obj
Installers/**/*/packages

86
ISSUE_TEMPLATE.md Normal file
View File

@ -0,0 +1,86 @@
*Before* you create an issue, make sure you have:
1. Checked that that issue hasn't already been submitted. You can search open issues [here](https://github.com/Jiiks/BetterDiscordApp/issues).
2. Checked that there isn't an answer in either of the Discord servers (if you can access them - don't complain if you can't).
3. Checked that it isn't in the following list of frequently asked questions.
If none of that helps you, delete the prefilled contents of this issue and ask whatever question you may have *in English so we can understand it*.
### FAQ
> *BetterDiscord doesn't work.*
> *BetterDiscord won't install.*
> *BetterDiscord doesn't support macOS.*
This branch isn't being updated anymore. Until BetterDiscord v2 is released you can use [Zach Rauen's fork](https://github.com/rauenzi/BetterDiscordApp).
> *BetterDiscord doesn't support Linux.*
There's an installer script for BetterDiscord on Linux available [here](https://github.com/bb010g/betterdiscordctl).
> *BetterDiscord doesn't work in my browser.*
The browser version doesn't exist anymore. Use the desktop client.
> *BetterDiscord doesn't work on my phone.*
... and never will. BetterDiscord is a client modification for Discord's desktop Electron client. (Electron is a framework for making cross platform apps using web technologies. Basically the desktop client is just the web client in a specialised web browser.)
> *Is there any security risks involved with installing BetterDiscord?*
> *My friend was hacked after he/she installed BetterDiscord.*
*Not by itself.* However, BetterDiscord allows loading plugins. Discord, BetterDiscord, and any plugins you install (even without enabling) have full access to your system as your local user account. (Including full access to your Discord account.) So, make sure you only download plugins from sources you trust.
Also, please note that [BetterDocs](https://betterdocs.net) and other third-party sources by definition *are not* affiliated with BetterDiscord or it's developers.
> *How do I install plugin [x]?*
> *Is there a plugin to [x]?*
> *Does [x] theme exist?*
https://imgur.com/lczPQxW
> *Minimal mode broke everything.*
You can get back into Discord's settings to disable it by pressing `Control + ,` on Windows and Linux or `Command + ,` on macOS.
> *How do I completely hide messages from people I've blocked?*
Add this to your custom CSS:
```css
.message-group-blocked {
display: none !important;
}
```
> *How do I remove BetterDiscord?*
BetterDiscord is installed to the following locations:
Platform | Discord path
-------------|---------------
Windows | `%APPDATA%`\discord\0.0.`*`\modules\discord_desktop_core
macOS | ~/Library/Application Support/discord/0.0.`*`/modules/discord_desktop_core
Linux | ~/.config/discord/0.0.`*`/modules/discord_desktop_core
To remove BetterDiscord, open the file `index.js` in that directory and make sure only this line exists:
```js
module.exports = require('./core');
```
Then, delete the `core` directory.
BetterDiscord's data is stored in the following locations:
Platform | BetterDiscord data path
-------------|---------------
Windows | `%APPDATA%`\BetterDiscord
macOS | ~/Library/Preferences/BetterDiscord
Linux | ~/.config/BetterDiscord
To remove all of BetterDiscord's data, just delete that directory.
> *BetterDiscord v2?*
[BetterDiscord v2 is the new version of BetterDiscord currently in development.](https://github.com/JsSucks/BetterDiscordApp) If you'd like to help out with BetterDiscord v2, join the JsSucks Discord server. (Invite code `KYKwv4R`.) The only requirement is JavaScript/ES6 knowledge.

3
Installers/Electron/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
dist/
pack.bat
run.bat

View File

@ -0,0 +1,20 @@
{
"name": "betterdiscordinstaller",
"description": "Better Discord installer.",
"version": "0.1.1",
"homepage": "https://github.com/Jiiks/BetterDiscordApp",
"license": "MIT",
"main": "index.js",
"dependencies": {
"fs-extra": "^0.30.0",
"readline": "^1.3.0",
"open": "^0.0.5",
"request": "^2.72.0",
"path": "^0.12.7",
"walk": "^2.3.9",
"unzip": "^0.1.11"
},
"devDependencies": {
"electron-prebuilt": "~1.2.8"
}
}

View File

@ -0,0 +1,71 @@
'use strict';
const
fs = require('fs'),
path = require('path'),
walk = require('walk'),
p = require('path');
fs.mkdirPSync = function(dirPath) {
try {
fs.mkdirSync(dirPath);
} catch(err) {
if(err.errno === -4058 || err.errno === -2) {
fs.mkdirPSync(path.dirname(dirPath));
fs.mkdirPSync(dirPath);
} else if(err.errno === -4075) {
return "EXIST";
} else {
return "NOT OK";
}
}
return "OK";
}
class Asar {
constructor(filePath) {
this.path = filePath;
this.files = [];
}
extract(statusCb, progressCb, cb) {
this.walker = walk.walk(this.path, { followLinks: false });
statusCb("Creating Directories");
this.walker.on('file', (root, stat, next) => {
this.files.push(`${root}/${stat.name}`);
try {
fs.statSync(root.replace("app.asar", "app"));
} catch(err) {
fs.mkdirPSync(root.replace("app.asar", "app"));
}
next();
});
this.walker.on('end', () => {
var self = this;
statusCb("Copying files");
var p = 1;
var filecount = this.files.length;
function copy(files, index) {
if(index >= filecount) {
statusCb("Finished extracting app package");
cb(null);
return;
}
setTimeout(() => { self.copyfile(files, index, copy) }, 1);
progressCb(index, filecount);
}
copy(this.files, 0);
});
}
copyfile(files, index, cb) {
fs.writeFileSync(files[index].replace("app.asar", "app"), fs.readFileSync(files[index]));
cb(files, index+1);
}
}
module.exports = Asar;

View File

@ -0,0 +1,650 @@
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src:local('Open Sans'), local('OpenSans'), url('../font/OpenSans-Regular.ttf') format('TrueType');
}
/* latin-ext */
@font-face {
font-family: 'Inconsolata';
font-style: normal;
font-weight: 400;
src: local('Inconsolata'), url('../font/Inconsolata.woff2') format('woff2');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Inconsolata';
font-style: normal;
font-weight: 400;
src: local('Inconsolata'), url('../font/Inconsolata.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
html, body {
margin:0;
padding:0;
background: rgba(34, 35, 42, 1);
overflow: hidden;
}
html, body {
width:800px;
height:400px;
}
* {
font-family: "Open Sans";
color:#E8E8E8;
outline:none;
user-select: none;
-webkit-user-select: none;
cursor: default;
}
a {
cursor: pointer;
color: dodgerblue;
}
#titleBar {
display:flex;
-webkit-app-region: drag;
pointer-events: none;
width:100%;
height:40px;
background:rgba(34, 35, 42, 0.6);
border-bottom:1px solid #000;
box-shadow:0 1px 0 0 #303030;
background: rgba(23, 23, 23, 0.6);
border:none;
box-shadow: none;
}
#titleBar h3 {
color:#FFF;
}
.icon {
display:inline-block;
width:40px;
height:40px;
padding:5px;
}
.icon-image {
background:blue;
height:30px;
width:30px;
}
.title {
display:inline-block;
height:40px;
line-height:40px;
color:#FFF;
}
.main-container {
display:flex;
width:100%;
height:calc(100% - 40px);
}
.sidebar {
width:200px;
height:358px;
border-right:1px solid #000;
box-shadow:1px 0 0 0 #303030;
background:rgba(44, 45, 56, 0.6);
z-index:90001;
margin-top: 1px;
border:none;
margin:0;
box-shadow: none;
margin-left:1px;
}
.sidebar-inner {
width:100%;
height:100%;
padding:5px;
}
.main {
flex-grow:1;
padding:5px;
transform:translateX(0);
}
.panel-container {
position:absolute;
left:10px;
transition: all 0.5s ease-in-out;
}
.panel {
display:inline-block;
width:580px;
position:absolute;
transition: all 0.5s ease-in-out;
opacity: 0;
}
.main-container.panel-0 #uninstall {
display: inline-block;
}
.main-container.panel-0 #back {
display: none;
}
.main-container.panel-0 #next {
display: inline-block;
}
.main-container.panel-0 #cancel {
display: inline-block;
}
.main-container.panel-1 #uninstall {
display: none;
}
.main-container.panel-1 #back {
display: inline-block;
}
.main-container.panel-1 #next {
display: inline-block;
}
.main-container.panel-1 #cancel {
display: inline-block;
}
.main-container.panel-2 #uninstall {
display: none;
}
.main-container.panel-2 #back {
display: inline-block;
}
.main-container.panel-2 #next {
display: inline-block;
}
.main-container.panel-2 #cancel {
display: inline-block;
}
.main-container.panel-3 #uninstall {
display: none;
}
.main-container.panel-3 #back {
display: none;
}
.main-container.panel-3 #next {
display: none;
}
.main-container.panel-3 #cancel {
display: inline-block;
}
.main-container.panel-0 #li-0:before {
background:dodgerblue;
}
.main-container.panel-0 #li-1:before {
background:gray;
}
.main-container.panel-0 #li-2:before {
background:gray;
}
.main-container.panel-0 #li-3:before {
background:gray;
}
.main-container.panel-1 #li-0:before {
background:#00D443;
}
.main-container.panel-1 #li-1:before {
background:dodgerblue;
}
.main-container.panel-1 #li-2:before {
background:gray;
}
.main-container.panel-1 #li-3:before {
background:gray;
}
.main-container.panel-2 #li-0:before,
.main-container.panel-advanced #li-0:before {
background:#00D443;
}
.main-container.panel-2 #li-1:before,
.main-container.panel-advanced #li-1:before {
background:#00D443;
}
.main-container.panel-2 #li-2:before,
.main-container.panel-advanced #li-2:before {
background:dodgerblue;
}
.main-container.panel-2 #li-3:before,
.main-container.panel-advanced #li-3:before {
background:gray;
}
.main-container.panel-2 #panel-advanced {
pointer-events: none;
}
.main-container.panel-3 #li-0:before {
background:#00D443;
}
.main-container.panel-3 #li-1:before {
background:#00D443;
}
.main-container.panel-3 #li-2:before {
background:#00D443;
}
.main-container.panel-3 #li-3:before {
background:dodgerblue;
}
.main-container.panel-0 .panel-container {
left: 10px;
}
.main-container.panel-1 .panel-container {
left: -590px;
}
.main-container.panel-2 .panel-container,
.main-container.panel-advanced .panel-container {
left: -1180px;
}
.main-container.panel-3 .panel-container {
left: -1770px;
}
.main-container.panel-0 .panel-container #panel-0 {
opacity: 1;
}
.main-container.panel-0 .panel-container #panel-1 {
opacity: 0;
}
.main-container.panel-0 .panel-container #panel-2 {
opacity: 0;
}
.main-container.panel-0 .panel-container #panel-3 {
opacity: 0;
}
.main-container.panel-1 .panel-container #panel-0 {
opacity: 0;
}
.main-container.panel-1 .panel-container #panel-1 {
opacity: 1;
}
.main-container.panel-1 .panel-container #panel-2 {
opacity: 0;
}
.main-container.panel-1 .panel-container #panel-3 {
opacity: 0;
}
.main-container.panel-2 .panel-container #panel-0 {
opacity: 0;
}
.main-container.panel-2 .panel-container #panel-1 {
opacity: 0;
}
.main-container.panel-2 .panel-container #panel-2 {
opacity: 1;
}
.main-container.panel-2 .panel-container #panel-3 {
opacity: 0;
}
.main-container.panel-3 .panel-container #panel-0 {
opacity: 0;
}
.main-container.panel-3 .panel-container #panel-1 {
opacity: 0;
}
.main-container.panel-3 .panel-container #panel-2 {
opacity: 0;
}
.main-container.panel-3 .panel-container #panel-3 {
opacity: 1;
}
.main-container.panel-advanced .controls button {
display: none;
}
.main-container.panel-advanced #panel-advanced {
pointer-events: initial;
}
.main-container.panel-advanced .panel-container #panel-0 {
opacity: 0;
}
.main-container.panel-advanced .panel-container #panel-1 {
opacity: 0;
}
.main-container.panel-advanced .panel-container #panel-2 {
opacity: 0;
}
.main-container.panel-advanced .panel-container #panel-3 {
opacity: 0;
}
.main-container.panel-advanced .panel-container #panel-advanced {
opacity: 1;
}
.main-container .panel-container #panel-advanced textarea {
background: rgba(33, 34, 41, 0.98);
width: 570px;
height: 140px;
resize: none;
border: 1px solid #000;
outline: 1px solid #303030;
}
.main-container .panel-container #panel-advanced button {
float: right;
margin-right: 10px;
margin-top: 5px;
}
.visible {
opacity: 1;
}
#panel-1 {
left:600px;
}
#panel-2 {
left:1200px;
}
#panel-advanced {
left:1200px;
}
#panel-3 {
left:1775px;
}
#licensetext {
width: 100%;
overflow-y: scroll;
white-space: pre-line;
height:280px;
}
#licenseform {
float:right;
margin-top:5px;
margin-right:10px;
}
input[type='radio'] {
cursor:pointer;
}
label {
cursor:pointer;
}
label, input[type='radio']{
font-size: 16px;
display: inline-block;
margin: 0;
margin-left: 3px;
line-height: 25px;
height: 28px;
vertical-align: top;
}
ul {
margin:0;
padding:0;
list-style:none;
}
li {
list-style:none;
color:gray;
}
li.active {
color:#FFF;
}
li.visited {
color:#EBEBEB;
}
.sidebar-inner li:before {
content: "";
display:inline-block;
background:gray;
border-radius: 50%;
width: 10px;
height: 10px;
margin-right:3px;
}
.sidebar-inner li.active:before {
background:dodgerblue;
}
.sidebar-inner li.visited:before {
background:#00D443;
}
.controls {
position:absolute;
bottom:5px;
right:5px;
}
button {
color:gray;
width:60px;
background:#1b1c23;
border-style:solid;
border-color:#000;
border-width:0 1px 1px 0;
padding:5px;
box-shadow:1px 1px 0 0 #303030 inset;
cursor:pointer;
border: none;
box-shadow: none;
}
button:hover {
color:#FFF;
background:#24262f;
}
button:disabled {
background:#292929;
border-color:#191919;
color:gray;
cursor: not-allowed;
}
button:active {
background: #232b2e;
}
button#advanced-settings {
width: 100px;
display: block;
}
::-webkit-scrollbar-thumb {
background:#282828 !important;
}
::-webkit-scrollbar, ::-webkit-scrollbar-track-piece {
background:#383838 !important;
}
input.path {
width: 450px;
height: 23px;
background: rgb(27, 28, 35) none repeat scroll 0% 0%;
border: 1px solid rgb(17, 17, 17);
box-shadow: -1px -1px 0px 0px rgb(50, 49, 49) inset;
border-width: 1px 0px 0px 1px;
border-style: solid;
border-color: #111;
}
.modal {
position: absolute;
background: rgba(29, 29, 29, 0.71);
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 900000;
}
.modal-container {
background: #212229;
width: 600px;
height: 200px;
position: relative;
margin: auto;
top: 100px;
box-shadow: 0px 0px 5px 5px rgba(0, 0, 0, 0.39);
}
.modal-header {
height: 30px;
line-height: 30px;
background: #212229;
padding-left: 10px;
border-bottom: 1px solid #000;
box-shadow: 0 1px 0 0 #303030;
}
.modal-body {
padding:30px;
}
.modal-footer {
position: absolute;
bottom: 0;
left:0;
right: 0;
height: 35px;
padding-top:10px;
background:#212229;
box-shadow: 0 1px 0 0 #303030 inset;
border-top: 1px solid #000;
}
.modal-footer button {
margin-right:5px;
float: right;
}
.splash {
width:300px !important;
height:100px !important;
}
.splash .wrapper {
top:20px;
width:40px;
margin:auto;
position:relative;
}
.splash .wrapper .spinner {
width:30px;
height:30px;
border-radius:30px;
border-width:5px;
border-color:#121212 #404040 #404040 #404040;
border-style:solid;
animation: spin 0.7s linear infinite;
}
.splash .spinnertext {
position: absolute;
bottom: 0;
width: 100%;
display: block;
text-align: center;
bottom: 10px;
color: rgb(171, 171, 171);
-webkit-animation: spinnertext-opacity 2s linear 0s infinite;
}
@-webkit-keyframes spin {
100% {
transform: rotate(360deg);
}
}
@-webkit-keyframes spinnertext-opacity {
0% {opacity: 0}
20% {opacity: 0}
50% {opacity: 1}
100%{opacity: 0}
}
#log {
padding: 10px;
height:294px;
resize: none;
width: 570px;
background: rgba(42, 44, 55, 0.6);
border: none;
-webkit-user-select: text;
word-wrap: break-word;
white-space: pre-line;
overflow: auto;
}
progress {
position: absolute;
bottom: -36px;
left:0;
width:525px;
height: 27px;
-webkit-appearance:none;
}
progress::-webkit-progress-bar {
background:rgba(42, 44, 55, 0.6);
}
progress[value]::-webkit-progress-value {
background-image: -webkit-linear-gradient(left, rgba(73,155,234,1) 0%, rgba(32,124,229,1) 100%);
}
.border {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
border:1px solid #55BBF7;
pointer-events: none;
}
.warning {
color: red;
font-weight: 700;
}

View File

@ -0,0 +1,36 @@
<html>
<head>
<head>
<link rel="stylesheet" href="css/main.css">
<script type="text/javascript" src="js/jquery-2.0.0.min.js"></script>
</head>
</head>
<body>
<div class="border"></div>
<div id="titleBar">
<div class="icon">
<div class="icon-image"></div>
</div>
<div class="title">
Error!
</div>
</div>
<div>
<div id="log" style="width:680px"></div>
</div>
<div>
<button style="position: absolute;right: 10px;bottom: 6px;">OK</button>
</div>
</body>
<script>
const ipcRenderer = require('electron').ipcRenderer;
$(function() {
ipcRenderer.send('async', '{ "arg": "geterror" }');
});
ipcRenderer.on('async-reply', (event, arg) => {
console.log(event);
console.log(arg);
$("#log").text(arg);
});
</script>
</html>

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,153 @@
<html>
<head>
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<div class="border"></div>
<div id="titleBar">
<div class="icon">
<div class="icon-image"></div>
</div>
<div class="title">
BetterDiscord Installer - v0.1.1
</div>
</div>
<div class="main-container panel-0">
<div class="sidebar">
<div class="sidebar-inner">
<ul>
<li id="li-0" class="navli">Introduction</li>
<li id="li-1" class="navli">License</li>
<li id="li-2" class="navli">Destination</li>
<li id="li-3" class="navli">Installation</li>
</ul>
</div>
</div>
<div class="main">
<div class="panel-container">
<div class="panel" id="panel-0">
<h2>Welcome to the BetterDiscord setup</h2>
<p style="white-space:pre-line">
The setup will install BetterDiscord on your computer.
Click "Next" to continue or "Cancel" to exit the setup.
BetterDiscord is not in any way affiliated with Discord
For support join the <a href="https://betterdiscord.net/discord" target="_blank">official BetterDiscord support channel</a> in Discord
</p>
<p>
<strong class="warning" style="font-size:12px">
Do not contact Discord support about BetterDiscord issues!
<br>
If Discord breaks, ask in the BetterDiscord support channel!
</strong>
</p>
<input name="cd" id="cd" type="checkbox">
<label style="margin:0; line-height: 18px;" for="cd">I will not contact Discord support about BetterDiscord issues</label>
</div>
<div class="panel" id="panel-1">
<div id="licensetext">
The MIT License (MIT)
Copyright (c) 2015-2016 Jiiks | Jiiks.net
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</div>
<form action="" id="licenseform">
<input type="radio" name="licensegroup" value="Accept" id="accept" disabled="true"><label for="accept">Accept</label>
<input type="radio" name="licensegroup" value="Decline" id="decline" checked="true"><label for="decline">Decline</label>
</form>
</div>
<div class="panel" id="panel-2">
<p style="font-size: 12px;">Setup will install BetterDiscord to the following location:</p>
<input class="path" id="libpath" type="text" style="height:26px;" disabled="true" />
<button id="libpathbtn" style="height:26px;">Browse</button>
<p style="font-size:12px">
*If you wish to install somewhere else then click "Browse" and select your path
</p>
<label for="discordPath" style="display:block; margin-top: 10px; font-size: 12px;">Discord Path:</label>
<input class="path" id="discordPath" type="text" style="height:26px;" disabled="true" />
<button id="path" style="height:26px;">Browse</button>
<p style="font-size:12px">
*If the path is not pointing to the latest version of Discord then click "Browse" and select it
<br>
*If you want to install to ptb/canary then click "Browse" and select it
<br>
*Installer will kill Discord process
</p>
<div class="checkboxGroup">
<input type="checkbox" name="demotes" id="demotes">
<label for="demotes" style="margin:0; line-height: 18px;">Disable emotes completely</label>
</div>
<div class="checkboxGroup">
<input type="checkbox" name="restart" id="restart" checked="true">
<label for="restart" style="margin:0; line-height: 18px;">Restart Discord after installation</label>
</div>
<button id="advanced-settings">Advanced</button>
</div>
<div class="panel" id="panel-advanced">
<span>Advanced settings</span> - <span class="warning">For advanced users only!</span>
<ul>
<li><input type="checkbox" name="aaot" id="aaot"><label for="aaot">Discord window always on top</label></li>
<li><input type="checkbox" name="aframeless" id="aframeless" checked><label for="aframeless">Frameless Discord window</label></li>
<li><input type="checkbox" name="atransparent" id="atransparent"><label for="atransparent">Transparent Discord window</label></li>
<li><input type="checkbox" name="athickframe" id="athickframe"><label for="athickframe">Thick Frame</label></li>
<li><input type="checkbox" name="aprefs" id="aprefs"><label for="aprefs">Use custom Web Preferences:</label></li>
</ul>
<textarea name="" id="" cols="30" rows="10"></textarea>
<button id="advanced-close">Save</button>
</div>
<div class="panel" id="panel-3">
<div name="log" id="log"></div>
<progress id="logpbar" value="0" max="100"></progress>
</div>
</div>
<div class="controls">
<button id="uninstall">Uninstall</button>
<button id="back">Back</button>
<button id="next" >Next</button>
<button id="cancel">Cancel</button>
</div>
</div>
</div>
<div class="modal" id="quit" style="display: none;">
<div class="modal-container">
<div class="modal-header">
<span>Exit Setup?</span>
</div>
<div class="modal-body">
Setup is not complete. If you exit now, BetterDiscord will not be installed.
<br>
Exit Setup?
</div>
<div class="modal-footer">
<button id="modal-exit">
Yes
</button>
<button id="modal-cancel">
No
</button>
</div>
</div>
</div>
</body>
<script type="text/javascript" src="js/jquery-2.0.0.min.js"></script>
<script type="text/javascript" src="js/main.js"></script>
<script type="text/javascript">
$(window).blur(function(){
$(".border").css("border-color", "#F76455");
});
$(window).focus(function(){
$(".border").css("border-color", "#55BBF7");
});
</script>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,202 @@
'use strict';
const ipcRenderer = require('electron').ipcRenderer;
var config = {
urls: {
package: "https://github.com/Jiiks/BetterDiscordApp/archive/stable16.zip",
finish: "https://betterdiscord.net/installed"
},
discord: {
lastKnownVersion: "0.0.291"
},
import: "BetterDiscordApp-stable16",
cache: [
"emotes_bttv.json",
"emotes_bttv_2.json",
"emotes_ffz.json",
"emotes_twitch_global.json",
"emotes_twitch_subscriber.json",
"user.json"
]
};
(function() {
//Pass latest config to core application
ipcSendAsync("config", config);
//Get Discord installation path
ipcSendAsync("get", "discordpath" );
//Get BetterDiscord installation path
ipcSendAsync("get", "libpath");
})();
//Listeners
(function() {
$("#cd").on("change", () => {
$("#next").prop("disabled", !$("#cd").prop("checked"));
});
var currentPanel = 0;
function switchPanel() {
var container = $(".panel-container");
var main = $(".main-container");
main.removeClass();
main.addClass(`main-container panel-${currentPanel}`)
switch(currentPanel) {
case 0:
$("#next").text("Next");
//$("#next").prop("disabled", !$("#cd").prop("checked"));
break;
case 1:
$("#next").text("Next");
//$("#next").prop("disabled", !$("#accept").prop("checked"));
break;
case 2:
$("#next").text("Install");
$("#cancel").text("Cancel");
break;
case 3:
$("#cancel").text("Abort");
ipcSendAsync("install");
break;
}
}
$("#next").on("click", function() {
currentPanel++;
switchPanel();
});
$("#back").on("click", function() {
currentPanel--;
switchPanel();
});
$("#cancel").on("click", function() {
$("#quit").show();
});
$("#uninstall").on("click", function() {
});
$("#accept").on("change", function() {
// $("#next").prop("disabled", !$(this).prop("checked"));
});
$("#decline").on("change", function() {
// $("#next").prop("disabled", $(this).prop("checked"));
});
$("#licensetext").on("scroll", function() {
var e = $(this);
if(e.height() + e.scrollTop() >= e[0].scrollHeight) {
$("#accept").prop("disabled", false);
} else {
$("#accept").prop("disabled", true);
$("#decline").prop("checked", true)
// $("#next").prop("disabled", true);
}
});
$(".modal").on("click", function(e) {
if(e.target.className !== "modal") return;
$(this).hide();
});
$("#modal-cancel").on("click", function() {
$(".modal").hide();
});
$("#modal-exit").on("click", function() {
ipcRenderer.send("async", {arg: "quit", data: []});
});
$("#path").on("click", () => {
ipcRenderer.send("async", { arg: "browsedialog", data: "discordpath" });
});
$("#libpathbtn").on("click", () => {
ipcRenderer.send("async", { arg: "browsedialog", data: "libpath" });
});
$("#advanced-settings").on("click", function() {
currentPanel = "advanced";
switchPanel();
});
$("#advanced-close").on("click", function() {
var main = $(".main-container");
currentPanel = 2;
switchPanel();
});
})();
ipcRenderer.on("async-reply", (event, arg) => {
var data = arg.data;
arg = arg.arg;
switch(arg) {
case "discordpath":
$("#discordPath").val(data);
break;
case "libpath":
$("#libpath").val(data);
break;
}
});
/*ipcRenderer.on('async-reply', (event, arg) => {
switch(arg.arg) {
case "exists":
switch(arg.file) {
case "install":
if(arg.exists) {
appendLog("Located app package");
appendLog("Downloading latest BetterDiscord package");
ipcRenderer.send('async', '{"arg": "download", "package": "https://github.com/Jiiks/BetterDiscordApp/archive/stable16.zip" }');
} else {
appendLog("Unable to locate app.asar. Check your install path.");
}
}
break;
case "discordpath":
$("#discordPath").val(arg.path);
break;
case "locate-app.asar":
appendLog(arg.data);
break;
}
});*/
function ipcSendAsync(arg, data) {
ipcRenderer.send("async", { arg: arg, data: data });
}
function install() {
appendLog("Initiating installation");
appendLog("Locating Discord package");
ipcRenderer.send('async', { "arg": "install" });
}
function appendLog(text) {
var log = $("#log");
log.append(text+"\n");
var sh = log[0].scrollHeight - 40;
if(log.height() + log.scrollTop() >= sh) {
log.scrollTop(sh);
}
}
function updatePbar(cur, max) {
var pbar = $("#logpbar");
pbar.val(cur);
pbar.prop("max", max);
}

View File

@ -0,0 +1,15 @@
'use strict';
const ipcRenderer = require('electron').ipcRenderer;
ipcRenderer.on('async-reply', (event, arg) => {
switch(arg) {
case "update":
$(".spinnertext").text("Downloading Update");
break;
}
});
$(function() {
ipcRenderer.send('async', '{ "arg": "update" }');
});

View File

@ -0,0 +1,16 @@
<html>
<head>
<head>
<link rel="stylesheet" href="css/main.css">
<script type="text/javascript" src="js/jquery-2.0.0.min.js"></script>
<script type="text/javascript" src="js/splash.js"></script>
</head>
</head>
<body class="splash">
<div class="border"></div>
<div class="wrapper">
<div class="spinner"></div>
</div>
<span class="spinnertext">Checking for updates...</span>
</body>
</html>

View File

@ -0,0 +1,8 @@
{
"windows": {
"version": "0.1.0"
},
"osx": {
"version": "0.1.1"
}
}

View File

@ -0,0 +1,45 @@
'use strict';
var devMode = false;
const
electron = require('electron'),
app = electron.app,
BrowserWindow = electron.BrowserWindow,
ipcMain = electron.ipcMain,
utils = require('./utils'),
_utils = new utils();
var
mainWindow,
windowOptions = {
width: 300,
height: 100,
fullscreenable: false,
maximizable: false,
frame: false,
resizable: devMode ? true : false,
alwaysOnTop: devMode ? true : false,
transparent: false
};
class Index {
constructor() {
app.on("ready", () => this.appReady());
}
appReady() {
mainWindow = new BrowserWindow(windowOptions);
this.loadInstaller();
}
loadInstaller() {
this.installer = require('./installer_index');
this.installerInstance = new this.installer(app, mainWindow, ipcMain, _utils);
}
}
module.exports = new Index();

View File

@ -0,0 +1,269 @@
'use strict';
//Imports
const
path = require('path'),
dialog = require('electron').dialog,
fs = require("fs"),
fse = require("fs-extra"),
request = require('request'),
unzip = require('unzip'),
readline = require('readline'),
asar = require('./asar');
const platform = (process.platform !== "win32" && process.platform !== "darwin") ? "linux" : process.platform;
var
config = {
urls: {
package: "https://github.com/Jiiks/BetterDiscordApp/archive/stable16.zip",
finish: "https://betterdiscord.net/installed"
},
discord: {
lastKnownVersion: "0.0.292"
},
import: "BetterDiscordApp-stable16",
cache: [
"emotes_bttv.json",
"emotes_bttv_2.json",
"emotes_ffz.json",
"emotes_twitch_global.json",
"emotes_twitch_subscriber.json",
"user.json"
],
paths: {
installPath: "",
libPath: ""
}
};
class Installer {
constructor(app, mainWindow, ipc, utils) {
this.app = app;
this.utils = utils;
this.initConfig();
mainWindow.setSize(800, 400);
mainWindow.center();
mainWindow.loadURL(`file://${__dirname}/data/index.html`);
this.webContents = mainWindow.webContents;
ipc.on('async', (event, arg) => this.receiveAsync(event, arg));
}
initConfig() {
config.paths.installPath = path.normalize(this.utils.installPath(config.discord.lastKnownVersion));
config.paths.libPath = path.normalize(this.utils.libPath());
}
install() {
this.utils.log("Config: " + JSON.stringify(config));
this.appendLog("Initializing");
this.locateAppPackage();
}
locateAppPackage() {
var p = path.normalize(`${config.paths.installPath}/resources`);
var pkg = fs.readdirSync(p).filter(file => {
if(file === "app.asar") {
return true;
}
});
if(pkg.length <= 0) {
//App package not found
this.appendLog("Unable to locate app package, check the logs for errors");
return;
}
this.appendLog("Located app package");
this.downloadBd();
//this.extractAppPackage();
}
downloadBd() {
var self = this;
this.appendLog("Downloading BetterDiscord");
var error = false;
var size = 0;
var downloaded = 0;
var req = request({
method: 'GET',
uri: config.urls.package
});
req.pipe(unzip.Extract({ path: path.normalize(config.paths.libPath) }));
req.on('data', chunk => {
downloaded += chunk.length;
this.updatePb(downloaded, size);
});
req.on('response', data => {
size = data.headers['content-length'];
});
req.on('error', err => {
error = true;
self.utils.log(err);
self.appendLog("Failed to download BetterDiscord package, check the logs for errors");
});
req.on('end', () => {
console.log("got here?");
if(error) {
self.appendLog("Failed to download BetterDiscord package, check the logs for errors");
} else {
self.extractAppPackage();
}
});
}
extractAppPackage() {
var self = this;
try {
if(fs.existsSync(`${config.paths.installPath}/resources/app`)) {
self.appendLog("Deleting old app directory");
setTimeout(() => {
fse.removeSync(`${config.paths.installPath}/resources/app`);
extract();
}, 500);
} else {
extract();
}
} catch(err) {
self.appendLog("Could not delete old app directory, check the logs for errors");
return;
}
function extract() {
try {
self.appendLog("Extracting app package");
var a = new asar(`${config.paths.installPath}/resources/app.asar`);
a.extract(msg => {
self.appendLog(msg);
}, (curIndex, total) => {
self.updatePb(curIndex, total);
}, err => {
if(err === null) {
self.inject();
} else {
self.log(err);
self.appendLog("Failed to extract app package, check the logs for errors");
self.clean();
}
});
}catch(err) {
console.log(err);
}
}
}
inject() {
var self = this;
this.updatePb(0, 5);
this.appendLog("Injecting loader");
var lines = [];
var lr = readline.createInterface({
input: fs.createReadStream(`${config.paths.installPath}/resources/app/index.js`)
});
lr.on('line', line => {
lines.push(line);
if(line.indexOf("'use strict';") > -1) {
lines.push(path.normalize(`var _betterDiscord = require('${config.paths.libPath}/${config.import}');`).replace(/\\/g,"/"));
lines.push("var _betterDiscord2;");
}
if(line.indexOf("mainWindow = new BrowserWindow(mainWindowOptions);") > -1) {
lines.push(` _betterDiscord2 = new _betterDiscord.BetterDiscord(mainWindow, false);`);
}
});
lr.on('close', () => {
fs.writeFileSync(`${config.paths.installPath}/resources/app/index.js`, lines.join('\n'));
self.appendLog("Finished installing BetterDiscord");
self.updatePb(5, 5);
});
}
clean() {
this.appendLog("Cleaning installation");
try {
if(fs.existsSync(`${config.paths.installPath}/resources/app`)) {
self.appendLog("Deleting app directory");
setTimeout(() => {
fse.removeSync(`${config.paths.installPath}/resources/app`);
}, 500);
}
} catch(err) {
self.appendLog("Could not delete old app directory, check the logs for errors");
}
}
appendLog(msg) {
this.utils.log(msg);
this.webContents.executeJavaScript(`appendLog("${msg}");`);
}
updatePb(cur, max) {
this.webContents.executeJavaScript(`updatePbar(${cur}, ${max});`);
}
getData(e) {
switch(e) {
case "discordpath":
return config.paths.installPath;
case "libpath":
return config.paths.libPath;
}
}
receiveAsync(event, arg) {
var data = arg.data || '';
arg = arg.arg;
switch(arg) {
case "get":
this.replyAsync(event, data, this.getData(data));
break;
case "browsedialog":
var path = dialog.showOpenDialog({ properties: ['openDirectory'] });
switch(data) {
case "discordpath":
path = path === undefined ? config.paths.installPath : path[0];
config.paths.installPath = path;
break;
case "libpath":
path = path === undefined ? config.paths.libPath : path[0];
config.paths.libPath = path;
break;
}
this.replyAsync(event, data, path);
break;
case "install":
this.install();
break;
case "quit":
this.app.quit();
break;
}
}
replyAsync(event, arg, data) {
event.sender.send('async-reply', { "arg": arg, "data": data });
}
}
module.exports = Installer;

View File

@ -0,0 +1,10 @@
{
"name": "Install",
"description": "Better Discord enhances Discord.",
"version": "0.1.1",
"homepage": "https://github.com/Jiiks/BetterDiscordApp",
"license": "MIT",
"devDependencies": {
"electron-prebuilt": "^1.0.0"
}
}

View File

@ -0,0 +1,75 @@
'use strict';
class Updater {
constructor(utils) {
this.utils = utils;
}
update() {
var self = this;
var promises = [
new Promise((resolve, reject) => {
downloadResource("/Jiiks/BetterDiscordApp/master/Installers/Electron/src/data/index.html", (error, data)
if(error) {
error(data, true);
reject();
return;
}
self.utils.log("Succesfully loaded index.html");
resolve();
});
}),
new Promise((resolve, reject) => {
downloadResource("/Jiiks/BetterDiscordApp/master/Installers/Electron/src/data/js/main.js", (error, data)
if(error) {
error(data, true);
reject();
return;
}
self.utils.log("Succesfully loaded main.js");
resolve();
});
}),
new Promise((resolve, reject) => {
downloadResource("/Jiiks/BetterDiscordApp/master/Installers/Electron/src/data/css/main.css", (error, dat
if(error) {
error(data, true);
reject();
return;
}
self.utils.log("Succesfully loaded main.css");
resolve();
});
})
];
return Promise.all(promises);
}
checkForUpdates(okCb, errorCb) {
_utils.downloadResource("/Jiiks/BetterDiscordApp/master/Installers/Electron/src/data/vi.json", (error, data) => {
if(error) {
errorCb(data);
return;
}
try {
data = JSON.parse(data);
}catch(err) {
errorCb(err);
return;
}
switch(platform) {
case "win32":
okCb(data.windows.version > vi.windows.version);
break;
case "darwin":
okCb(data.osx.version > vi.osx.version);
break;
}
});
}
}
module.exports = Updater;

View File

@ -0,0 +1,98 @@
'use strict';
const
https = require('https'),
fs = require('fs'),
eol = require('os').EOL,
platform = (process.platform !== "win32" && process.platform !== "darwin") ? "linux" : process.platform;
class Utils {
constructor() {
this.logs = "";
}
log(message) {
var d = new Date();
var ds = ("00" + (d.getDate() + 1)).slice(-2) + "/" +
("00" + d.getMonth()).slice(-2) + "/" +
d.getFullYear() + " " +
("00" + d.getHours()).slice(-2) + ":" +
("00" + d.getMinutes()).slice(-2) + ":" +
("00" + d.getSeconds()).slice(-2);
console.log(`[${ds}] ${message}`);
this.logs += `[${ds}] ${message}${eol}`;
this.saveLogs();
}
printLogs() {
console.log(this.logs);
}
saveLogs() {
fs.writeFileSync("logs.log", this.logs);
}
downloadResource(resource, callback, host) {
https.get({
host: host || "raw.githubusercontent.com",
path: resource,
headers: { 'user-agent': 'Mozilla/5.0' }
},
(response) => {
var data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
callback(false, data);
});
response.on("error", (e) => {
callback(true, e);
});
}).on('error', (e) => {
callback(true, e);
});
}
installPath(lastKnownVersion) {
return {
"win32": () => {
var hver = lastKnownVersion;
var path = `${process.env.LOCALAPPDATA}/Discord/app-${lastKnownVersion}\\`;
fs.readdirSync(`${process.env.LOCALAPPDATA}/Discord/`).filter(function(file) {
var tpath = `${process.env.LOCALAPPDATA}/Discord/${file}`;
if(!fs.statSync(tpath).isDirectory()) return;
if(!file.startsWith("app-")) return;
var ver = file.replace("app-", "");
if(ver < hver) return;
hver = ver;
path = tpath;
});
return path;
},
"darwin": () => "/Applications/Discord.app/Contents",
"linux": () => "/usr/share/discord"
}[platform]();
}
libPath() {
return {
"win32": () => {
return `${process.env.APPDATA}/BetterDiscord/lib`;
},
"darwin": () => {
return `${process.env.HOME}/.local/share/BetterDiscord`;
},
"linux": () => {
// FIXME: for a non-root user, a path like OSX's makes more sense
return "/usr/local/share/BetterDiscord";
}
}[platform]();
}
}
module.exports = Utils;

509
NodeInstaller/index.js → Installers/Node/index.js Executable file → Normal file
View File

@ -1,248 +1,261 @@
/*
* BetterDiscordApp Installer v0.3.2
*/
var dver = "0.0.284";
var asar = require('asar');
var wrench = require('wrench');
var fs = require('fs');
var readline = require('readline');
var util = require('util');
var _importSplice;
var _functionSplice;
var _functionCallSplice;
var _discordPath;
var _appFolder = "/app";
var _appArchive = "/app.asar";
var _packageJson = _appFolder + "/package.json";
var _index = _appFolder + "/app/index.js";
var _force = false;
// Get Arguments
process.argv.forEach(function (val, index, array) {
if (val == "--force") {
_force = true;
}
if (val == "-d" || val == "--directory") {
_discordPath = array[(index+1)]
}
});
function install() {
if (typeof _discordPath == 'undefined') {
var _os = process.platform;
if (_os == "win32") {
_importSplice = 89;
_functionCallSplice = 497;
_functionSplice = 601;
_discordPath = process.env.LOCALAPPDATA + "/Discord/app-"+dver+"/resources";
} else if (_os == "darwin") {
_importSplice = 67;
_functionCallSplice = 446;
_functionSplice = 547;
_discordPath = "/Applications/Discord.app/Contents/Resources" // Defaults to Applications directory
}
}
console.log("Looking for discord resources at: " + _discordPath);
fs.exists(_discordPath, function(exists) {
if(exists) {
console.log("Discord resources found at: " + _discordPath + "\nLooking for app folder");
if(fs.existsSync(_discordPath + _appFolder)) {
console.log("Deleting " + _discordPath + _appFolder + " folder.");
wrench.rmdirSyncRecursive(_discordPath + _appFolder);
console.log("Deleted " + _discordPath + _appFolder + " folder.");
}
if(fs.existsSync(_discordPath + "/node_modules/BetterDiscord")) {
console.log("Deleting " + _discordPath + "/node_modules/BetterDiscord" + " folder.");
wrench.rmdirSyncRecursive(_discordPath + "/node_modules/BetterDiscord");
console.log("Deleted " + _discordPath + "/node_modules/BetterDiscord" + " folder.");
}
console.log("Looking for app archive");
if(fs.existsSync(_discordPath + _appArchive)) {
console.log("App archive found at: " + _discordPath + _appArchive);
} else {
console.log("Failed to locate app archive at: " + _discordPath + _appArchive);
process.exit();
}
console.log("Extracting app archive");
asar.extractAll(_discordPath + _appArchive, _discordPath + _appFolder);
console.log("Copying BetterDiscord");
fs.mkdirSync(_discordPath + "/node_modules/BetterDiscord");
wrench.copyDirSyncRecursive(__dirname + "/BetterDiscord/", _discordPath + _appFolder + "/node_modules/BetterDiscord/", {forceDelete: true});
if(!fs.existsSync("splice")) {
console.log("Missing splice file");
process.exit();
}
var splice = fs.readFileSync("splice");
fs.exists(_discordPath + _appFolder, function(exists) {
if(exists) {
console.log("Extracted to: " + _discordPath + _appFolder);
console.log("Injecting index.js");
var data = fs.readFileSync(_discordPath + _index).toString().split("\n");
data.splice(_importSplice, 0, 'var _betterDiscord = require(\'betterdiscord\');\n');
data.splice(_functionCallSplice, 0, splice);
fs.writeFile(_discordPath + _index, data.join("\n"), function(err) {
if(err) return console.log(err);
console.log("Injected index.js");
console.log("Deleting old cache files");
var counter = 0;
var _prefsPath = '/Library/Preferences/BetterDiscord/';
var emotes_twitch_global = 'emotes_twitch_global.json';
fs.exists(process.env.HOME + _prefsPath + emotes_twitch_global, (exists) => {
if (exists) {
console.log("Deleting " + emotes_twitch_global);
fs.unlinkSync(process.env.HOME + _prefsPath + emotes_twitch_global, (err) => {
if(err) throw err;
});
console.log("Deleted " + emotes_twitch_global);
}
counter++;
finished();
});
var emotes_twitch_subscriber = 'emotes_twitch_subscriber.json';
fs.exists(process.env.HOME + _prefsPath + emotes_twitch_subscriber, (exists) => {
if (exists) {
console.log("Deleting " + emotes_twitch_subscriber);
fs.unlinkSync(process.env.HOME + _prefsPath + emotes_twitch_subscriber, (err) => {
if(err) throw err;
});
console.log("Deleted " + emotes_twitch_subscriber);
}
counter++;
finished();
});
var emotes_bttv = 'emotes_bttv.json';
fs.exists(process.env.HOME + _prefsPath + emotes_bttv, (exists) => {
if (exists) {
console.log("Deleting " + emotes_bttv);
fs.unlinkSync(process.env.HOME + _prefsPath + emotes_bttv, (err) => {
if(err) throw err;
});
console.log("Deleted " + emotes_bttv);
}
counter++;
finished();
});
var emotes_bttv_2 = "emotes_bttv_2.json";
fs.exists(process.env.HOME + _prefsPath + emotes_bttv_2, (exists) => {
if (exists) {
console.log("Deleting " + emotes_bttv_2);
fs.unlinkSync(process.env.HOME + _prefsPath + emotes_bttv_2, (err) => {
if(err) throw err;
});
console.log("Deleted " + emotes_bttv_2);
}
counter++;
finished();
});
var emotes_ffz = "emotes_ffz.json";
fs.exists(process.env.HOME + _prefsPath + emotes_ffz, (exists) => {
if (exists) {
console.log("Deleting " + emotes_ffz);
fs.unlinkSync(process.env.HOME + _prefsPath + emotes_ffz, (err) => {
if(err) throw err;
});
console.log("Deleted " + emotes_ffz);
}
counter++;
finished();
});
var user_pref = "user.json";
fs.exists(process.env.HOME + _prefsPath + user_pref, (exists) => {
if (exists) {
console.log("Deleting " + user_pref);
fs.unlinkSync(process.env.HOME + _prefsPath + user_pref, (err) => {
if(err) throw err;
});
console.log("Deleted " + user_pref);
}
counter++;
finished();
});
function finished() {
if(counter => 6) {
console.log("Looks like we're done here");
process.exit();
}
}
});
} else {
console.log("Something went wrong. Please try again.");
process.exit();
}
});
} else {
console.log("Discord resources not found at: " + _discordPath);
process.exit();
}
});
}
function init() {
console.log("BetterDiscord Simple Installer v0.3 for Discord "+dver+" by Jiiks.");
console.log("If Discord has updated then download the latest installer.");
var rl = readline.createInterface({ input: process.stdin, output: process.stdout });
if (_force == false) {
rl.question("The following directories will be deleted if they exists: discorpath/app, discordpath/node_modules/BetterDiscord, is this ok? Y/N", function(answer) {
var alc = answer.toLowerCase();
switch(alc) {
case "y":
install();
break;
case "yes":
install();
break;
case "n":
process.exit();
break;
case "no":
process.exit();
break;
}
});
} else {
install();
}
}
init();
/*
* BetterDiscordApp Installer v0.3.2
*/
var dver = "0.0.284";
var asar = require('asar');
var wrench = require('wrench');
var fs = require('fs');
var readline = require('readline');
var util = require('util');
var _importSplice;
var _functionSplice;
var _functionCallSplice;
var _discordPath;
var _appFolder = "/app";
var _appArchive = "/app.asar";
var _packageJson = _appFolder + "/package.json";
var _index = _appFolder + "/index.js";
var _force = false;
// Get Arguments
process.argv.forEach(function (val, index, array) {
if (val == "--force") {
_force = true;
}
if (val == "-d" || val == "--directory") {
_discordPath = array[(index+1)]
}
});
function install() {
if (typeof _discordPath == 'undefined') {
var _os = process.platform;
if (_os == "win32") {
_importSplice = 89;
_functionCallSplice = 497;
_functionSplice = 601;
_discordPath = process.env.LOCALAPPDATA + "/Discord/app-"+dver+"/resources";
} else if (_os == "darwin") {
_importSplice = 67;
_functionCallSplice = 446;
_functionSplice = 547;
_discordPath = "/Applications/Discord.app/Contents/Resources" // Defaults to Applications directory
} else if (_os == "linux") {
_discordPath = "/opt/DiscordCanary/resources";
_index = "/app/index.js";
}
}
console.log("Looking for discord resources at: " + _discordPath);
fs.exists(_discordPath, function(exists) {
if(exists) {
console.log("Discord resources found at: " + _discordPath + "\nLooking for app folder");
if(fs.existsSync(_discordPath + _appFolder)) {
console.log("Deleting " + _discordPath + _appFolder + " folder.");
wrench.rmdirSyncRecursive(_discordPath + _appFolder);
console.log("Deleted " + _discordPath + _appFolder + " folder.");
}
if(fs.existsSync(_discordPath + "/node_modules/BetterDiscord")) {
console.log("Deleting " + _discordPath + "/node_modules/BetterDiscord" + " folder.");
wrench.rmdirSyncRecursive(_discordPath + "/node_modules/BetterDiscord");
console.log("Deleted " + _discordPath + "/node_modules/BetterDiscord" + " folder.");
}
console.log("Looking for app archive");
if(fs.existsSync(_discordPath + _appArchive)) {
console.log("App archive found at: " + _discordPath + _appArchive);
} else {
console.log("Failed to locate app archive at: " + _discordPath + _appArchive);
process.exit();
}
console.log("Extracting app archive");
asar.extractAll(_discordPath + _appArchive, _discordPath + _appFolder);
console.log("Copying BetterDiscord");
if(_os == "linux") {
fs.mkdirSync(_discordPath + _appFolder + "/node_modules/BetterDiscord");
}
else {
fs.mkdirSync(_discordPath + "/node_modules/BetterDiscord");
}
wrench.copyDirSyncRecursive(__dirname + "/BetterDiscord/", _discordPath + _appFolder + "/node_modules/BetterDiscord/", {forceDelete: true});
if(!fs.existsSync("splice")) {
console.log("Missing splice file");
process.exit();
}
var splice = fs.readFileSync("splice");
fs.exists(_discordPath + _appFolder, function(exists) {
if(exists) {
console.log("Extracted to: " + _discordPath + _appFolder);
console.log("Injecting index.js");
var data = fs.readFileSync(_discordPath + _index).toString().split("\n");
if(_os == "linux") {
data = data.join("\n");
data = data.replace('var _GPUSettings2 = _interopRequireDefault(_GPUSettings);','var _GPUSettings2 = _interopRequireDefault(_GPUSettings);\n\nvar _betterDiscord = require(\'BetterDiscord\');\n');
data = data.replace('mainWindow.setMenuBarVisibility(false);','mainWindow.setMenuBarVisibility(false);\n' + splice + '\n');
data = data.split("\n");
} else {
data.splice(_importSplice, 0, 'var _betterDiscord = require(\'betterdiscord\');\n');
data.splice(_functionCallSplice, 0, splice);
}
fs.writeFile(_discordPath + _index, data.join("\n"), function(err) {
if(err) return console.log(err);
console.log("Injected index.js");
console.log("Deleting old cache files");
var counter = 0;
var _prefsPath = '/Library/Preferences/BetterDiscord/';
var emotes_twitch_global = 'emotes_twitch_global.json';
fs.exists(process.env.HOME + _prefsPath + emotes_twitch_global, (exists) => {
if (exists) {
console.log("Deleting " + emotes_twitch_global);
fs.unlinkSync(process.env.HOME + _prefsPath + emotes_twitch_global, (err) => {
if(err) throw err;
});
console.log("Deleted " + emotes_twitch_global);
}
counter++;
finished();
});
var emotes_twitch_subscriber = 'emotes_twitch_subscriber.json';
fs.exists(process.env.HOME + _prefsPath + emotes_twitch_subscriber, (exists) => {
if (exists) {
console.log("Deleting " + emotes_twitch_subscriber);
fs.unlinkSync(process.env.HOME + _prefsPath + emotes_twitch_subscriber, (err) => {
if(err) throw err;
});
console.log("Deleted " + emotes_twitch_subscriber);
}
counter++;
finished();
});
var emotes_bttv = 'emotes_bttv.json';
fs.exists(process.env.HOME + _prefsPath + emotes_bttv, (exists) => {
if (exists) {
console.log("Deleting " + emotes_bttv);
fs.unlinkSync(process.env.HOME + _prefsPath + emotes_bttv, (err) => {
if(err) throw err;
});
console.log("Deleted " + emotes_bttv);
}
counter++;
finished();
});
var emotes_bttv_2 = "emotes_bttv_2.json";
fs.exists(process.env.HOME + _prefsPath + emotes_bttv_2, (exists) => {
if (exists) {
console.log("Deleting " + emotes_bttv_2);
fs.unlinkSync(process.env.HOME + _prefsPath + emotes_bttv_2, (err) => {
if(err) throw err;
});
console.log("Deleted " + emotes_bttv_2);
}
counter++;
finished();
});
var emotes_ffz = "emotes_ffz.json";
fs.exists(process.env.HOME + _prefsPath + emotes_ffz, (exists) => {
if (exists) {
console.log("Deleting " + emotes_ffz);
fs.unlinkSync(process.env.HOME + _prefsPath + emotes_ffz, (err) => {
if(err) throw err;
});
console.log("Deleted " + emotes_ffz);
}
counter++;
finished();
});
var user_pref = "user.json";
fs.exists(process.env.HOME + _prefsPath + user_pref, (exists) => {
if (exists) {
console.log("Deleting " + user_pref);
fs.unlinkSync(process.env.HOME + _prefsPath + user_pref, (err) => {
if(err) throw err;
});
console.log("Deleted " + user_pref);
}
counter++;
finished();
});
function finished() {
if(counter => 6) {
console.log("Looks like we're done here");
process.exit();
}
}
});
} else {
console.log("Something went wrong. Please try again.");
process.exit();
}
});
} else {
console.log("Discord resources not found at: " + _discordPath);
process.exit();
}
});
}
function init() {
console.log("BetterDiscord Simple Installer v0.3 for Discord "+dver+" by Jiiks.");
console.log("If Discord has updated then download the latest installer.");
var rl = readline.createInterface({ input: process.stdin, output: process.stdout });
if (_force == false) {
rl.question("The following directories will be deleted if they exists: discorpath/app, discordpath/node_modules/BetterDiscord, is this ok? Y/N", function(answer) {
var alc = answer.toLowerCase();
switch(alc) {
case "y":
case "yes":
install();
break;
case "n":
case "no":
process.exit();
break;
}
});
} else {
install();
}
}
init();

View File

View File

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 170 KiB

View File

@ -41,7 +41,7 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="asardotnet">
<HintPath>..\dlls\asardotnet.dll</HintPath>
<HintPath>..\..\..\..\WindowsInstaller\asardotnet.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
@ -144,6 +144,7 @@
<None Include="Resources\bd_logo_large_nobg.png" />
</ItemGroup>
<ItemGroup>
<Content Include="BetterDiscord-icon.ico" />
<Content Include="Resources\BetterDiscord-icon.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View File

@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.2.6.0")]
[assembly: AssemblyFileVersion("0.2.6.0")]
[assembly: AssemblyVersion("0.2.8.0")]
[assembly: AssemblyFileVersion("0.2.8.0")]

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

View File

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 4.4 MiB

After

Width:  |  Height:  |  Size: 4.4 MiB

View File

@ -121,6 +121,12 @@ namespace BetterDiscordWI.panels {
Thread.Sleep(100);
}
if (!Directory.Exists($"{GetParent().DiscordPath}\\resources\\node_modules\\")) {
Debug.Print("node_modules doesn't exist, creating");
AppendLog("node_modules doesn't exist, creating");
Directory.CreateDirectory($"{GetParent().DiscordPath}\\resources\\node_modules\\");
}
dir = $"{GetParent().DiscordPath}\\resources\\node_modules\\BetterDiscord";
@ -174,7 +180,31 @@ namespace BetterDiscordWI.panels {
}
private void Splice() {
string indexloc = $"{GetParent().DiscordPath}\\resources\\app\\app\\index.js";
string indexloc = null;
if(File.Exists($"{GetParent().DiscordPath}\\resources\\app\\app\\index.js"))
{
//Normal path
indexloc = $"{GetParent().DiscordPath}\\resources\\app\\app\\index.js";
} else if (File.Exists($"{GetParent().DiscordPath}\\resources\\app\\index.js"))
{
//Canary 0.0.138 changed path to app\\index.js
indexloc = $"{GetParent().DiscordPath}\\resources\\app\\index.js";
}
if(indexloc == null)
{
AppendLog($"Error: index.js not found");
Finalize(1);
return;
}
if(!File.Exists(@"splice"))
{
AppendLog($"Error: splice install file not found, this should be included with the installer.");
Finalize(1);
return;
}
Thread t = new Thread(() => {
List<string> lines = new List<string>();
@ -210,9 +240,10 @@ namespace BetterDiscordWI.panels {
int errors = 0;
string curPath = $"{GetParent().DiscordPath}\\resources\\app\\app\\index.js";
if(!File.Exists(curPath)) {
AppendLog($"ERROR: FILE: {curPath} DOES NOT EXIST!");
string curPath2 = $"{GetParent().DiscordPath}\\resources\\app\\index.js";
if (!File.Exists(curPath) && !File.Exists(curPath2))
{
AppendLog($"ERROR: index.js not found in {curPath} or {curPath2}");
errors++;
}

View File

@ -1,9 +1,9 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
# Visual Studio 15
VisualStudioVersion = 15.0.26430.16
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinRepair", "WinRepair\WinRepair.csproj", "{B1DDA709-0EC8-43F5-AE94-7EBFD1CAAE5D}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BetterDiscordWI", "BetterDiscordWI\BetterDiscordWI.csproj", "{390615F1-CE33-4173-9E8C-4E4F3EB1758D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -11,10 +11,10 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B1DDA709-0EC8-43F5-AE94-7EBFD1CAAE5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B1DDA709-0EC8-43F5-AE94-7EBFD1CAAE5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B1DDA709-0EC8-43F5-AE94-7EBFD1CAAE5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B1DDA709-0EC8-43F5-AE94-7EBFD1CAAE5D}.Release|Any CPU.Build.0 = Release|Any CPU
{390615F1-CE33-4173-9E8C-4E4F3EB1758D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{390615F1-CE33-4173-9E8C-4E4F3EB1758D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{390615F1-CE33-4173-9E8C-4E4F3EB1758D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{390615F1-CE33-4173-9E8C-4E4F3EB1758D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
</startup>
</configuration>
</configuration>

View File

@ -0,0 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{390615F1-CE33-4173-9E8C-4E4F3EB1758D}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>BetterDiscordWI</RootNamespace>
<AssemblyName>BetterDiscordWI</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>betterdiscord_small_white_blue_icO_icon.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="asardotnetasync">
<HintPath>..\..\..\..\..\Projects\C#\asardotnetasync\asardotnetasync\bin\Release\asardotnetasync.dll</HintPath>
</Reference>
<Reference Include="Costura, Version=1.6.2.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
<HintPath>..\packages\Costura.Fody.1.6.2\lib\dotnet\Costura.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\..\..\..\libs\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="controls\Button.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="controls\Button.Designer.cs">
<DependentUpon>Button.cs</DependentUpon>
</Compile>
<Compile Include="FormMain.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FormMain.Designer.cs">
<DependentUpon>FormMain.cs</DependentUpon>
</Compile>
<Compile Include="panels\ConfigPanel.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="panels\ConfigPanel.Designer.cs">
<DependentUpon>ConfigPanel.cs</DependentUpon>
</Compile>
<Compile Include="panels\InstallPanel.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="panels\InstallPanel.Designer.cs">
<DependentUpon>InstallPanel.cs</DependentUpon>
</Compile>
<Compile Include="panels\IPanel.cs" />
<Compile Include="panels\LicensePanel.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="panels\LicensePanel.Designer.cs">
<DependentUpon>LicensePanel.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utils.cs" />
<EmbeddedResource Include="FormMain.resx">
<DependentUpon>FormMain.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="panels\ConfigPanel.resx">
<DependentUpon>ConfigPanel.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="panels\InstallPanel.resx">
<DependentUpon>InstallPanel.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="panels\LicensePanel.resx">
<DependentUpon>LicensePanel.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="app.manifest" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Betterdiscord small black+blue.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Betterdiscord small white+blue.png" />
</ItemGroup>
<ItemGroup>
<None Include="FodyWeavers.xml" />
</ItemGroup>
<ItemGroup>
<Content Include="betterdiscord_small_white_blue_icO_icon.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Fody.2.0.0\build\netstandard1.4\Fody.targets" Condition="Exists('..\packages\Fody.2.0.0\build\netstandard1.4\Fody.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Fody.2.0.0\build\netstandard1.4\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.2.0.0\build\netstandard1.4\Fody.targets'))" />
<Error Condition="!Exists('..\packages\Costura.Fody.1.6.2\build\dotnet\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.1.6.2\build\dotnet\Costura.Fody.targets'))" />
</Target>
<Import Project="..\packages\Costura.Fody.1.6.2\build\dotnet\Costura.Fody.targets" Condition="Exists('..\packages\Costura.Fody.1.6.2\build\dotnet\Costura.Fody.targets')" />
</Project>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Weavers>
<Costura />
</Weavers>

View File

@ -0,0 +1,128 @@
namespace BetterDiscordWI {
partial class FormMain {
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormMain));
this.panelDock = new System.Windows.Forms.Panel();
this.lblTitle = new System.Windows.Forms.Label();
this.panel2 = new System.Windows.Forms.Panel();
this.btnBack = new BetterDiscordWI.controls.Button();
this.btnNext = new BetterDiscordWI.controls.Button();
this.btnCancel = new BetterDiscordWI.controls.Button();
this.SuspendLayout();
//
// panelDock
//
this.panelDock.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panelDock.Location = new System.Drawing.Point(12, 96);
this.panelDock.Name = "panelDock";
this.panelDock.Size = new System.Drawing.Size(752, 339);
this.panelDock.TabIndex = 0;
//
// lblTitle
//
this.lblTitle.AutoSize = true;
this.lblTitle.BackColor = System.Drawing.SystemColors.Window;
this.lblTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold);
this.lblTitle.ForeColor = System.Drawing.Color.Black;
this.lblTitle.Location = new System.Drawing.Point(82, 37);
this.lblTitle.Name = "lblTitle";
this.lblTitle.Size = new System.Drawing.Size(147, 16);
this.lblTitle.TabIndex = 5;
this.lblTitle.Text = "BetterDiscord Setup";
//
// panel2
//
this.panel2.BackColor = System.Drawing.SystemColors.Window;
this.panel2.BackgroundImage = global::BetterDiscordWI.Properties.Resources.Betterdiscord_small_black_blue;
this.panel2.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.panel2.Location = new System.Drawing.Point(12, 12);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(64, 64);
this.panel2.TabIndex = 4;
//
// btnBack
//
this.btnBack.Location = new System.Drawing.Point(527, 466);
this.btnBack.Name = "btnBack";
this.btnBack.Size = new System.Drawing.Size(75, 23);
this.btnBack.TabIndex = 6;
this.btnBack.Text = "< Back";
this.btnBack.UseVisualStyleBackColor = true;
this.btnBack.Click += new System.EventHandler(this.btnBack_Click);
//
// btnNext
//
this.btnNext.Location = new System.Drawing.Point(608, 466);
this.btnNext.Name = "btnNext";
this.btnNext.Size = new System.Drawing.Size(75, 23);
this.btnNext.TabIndex = 7;
this.btnNext.Text = "Next >";
this.btnNext.UseVisualStyleBackColor = true;
this.btnNext.Click += new System.EventHandler(this.btnNext_Click);
//
// btnCancel
//
this.btnCancel.Location = new System.Drawing.Point(689, 466);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 8;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// FormMain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.Control;
this.ClientSize = new System.Drawing.Size(776, 501);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnNext);
this.Controls.Add(this.btnBack);
this.Controls.Add(this.lblTitle);
this.Controls.Add(this.panel2);
this.Controls.Add(this.panelDock);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.Name = "FormMain";
this.Text = "Setup - BetterDiscord";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Panel panelDock;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.Label lblTitle;
public controls.Button btnNext;
public controls.Button btnCancel;
public controls.Button btnBack;
}
}

View File

@ -0,0 +1,71 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using BetterDiscordWI.panels;
namespace BetterDiscordWI {
public partial class FormMain : Form {
private readonly IPanel[] _panels = { new LicensePanel(), new ConfigPanel(), new InstallPanel() };
private int _currentPanel;
public string DiscordPath = null;
public bool RestartDiscord = true;
public bool Stable = true, Canary, Ptb;
public FormMain() {
InitializeComponent();
foreach (var panel in _panels) {
panel.SetForm(this);
panel.Control.Dock = DockStyle.Fill;
panelDock.Controls.Add(panel.Control);
}
SwitchPanel(0);
}
public void SetTitle(string title) => lblTitle.Text = title;
public void SwitchPanel(int index) {
_currentPanel = index;
foreach (var panel in _panels) { panel.HidePanel(); }
SetTitle($"BetterDiscord {_panels[index].Title}");
_panels[index].ShowPanel();
}
private readonly Pen _borderPen = new Pen(Color.FromArgb(160, 160, 160));
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
var g = e.Graphics;
g.FillRectangle(SystemBrushes.Window, new Rectangle(0, 0, Width, 85));
g.DrawLine(_borderPen, 0, 85, Width, 85);
g.DrawLine(SystemPens.Window, 0, 86, Width, 86);
g.DrawLine(_borderPen, 0, 445, Width, 445);
g.DrawLine(SystemPens.Window, 0, 446, Width, 446);
}
private void btnNext_Click(object sender, EventArgs e) {
_currentPanel++;
SwitchPanel(_currentPanel);
}
private void btnCancel_Click(object sender, EventArgs e) {
Application.Exit();
}
private void btnBack_Click(object sender, EventArgs e) {
_currentPanel--;
SwitchPanel(_currentPanel);
}
public void Fail() {
btnCancel.ShowEnable();
btnNext.ShowDisable();
btnBack.ShowEnable();
}
}
}

View File

@ -0,0 +1,541 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAUAEBAAAAEAIABoBAAAVgAAABgYAAABACAAiAkAAL4EAAAgIAAAAQAgAKgQAABGDgAAMDAAAAEA
IACoJQAA7h4AAAAAAAABACAA4BwAAJZEAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAATCwAAEwsAAAAA
AAAAAAAA5YI+geWCPoHlgj6B5YI+geWCPoHlgj6B5YI+fOWCPmHlgDsv99jDE////2D///9r////OP//
/wr///8A////AOWCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj765YI+5eWDQJj32sZi////2///
/+3///+p////MP///wDlgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5H85pvzy
6nX////7/////////9H///8z5YI+meWCPprlgj6a5YI+muWCPprlgj6Z5YI+rOWCPu3lgj7/5YI+/+WB
PPPtqXtl////2v//////////////qwAAAAAAAAAAAAAAAAAAAADlgj4A5YI+AOWCPgLlgj5y5YI+/uWC
Pv/lgj3/6I5Ref///8D//////////////+4AAAAA5YI+AOWCPgDlgj4J5YI+AuWCPgDlgj4A5YI+X+WC
Pv3lgj7/5YI+/+eMTXT///+7///////////////+5YI+AOWCPgDlgj4t5YI+feWCPj3lgj5u5YI+geWC
Ptvlgj7/5YI+/+WCPvTokVVN////u////////////////+WCPgDlgj425YI+0OWCPrzlgj5/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj218LaOFv///77////////////////lgj5O5YI+1+WCPv/lgj675YI+f+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI9tvC1jhb///++////////////////5YI+7OWCPv/lgj7/5YI+veWC
Pjvlgj5s5YI+gOWCPtvlgj7/5YI+/+WCPvTokVVN////u////////////////+WCPv/lgj7/5YI+/+WC
Pr/lgj4J5YI+AOWCPgDlgj5f5YI+/eWCPv/lgj7/54xNdf///7v///////////////7lgj7/5YI+/+WC
Pv/lgj6/5YI+CeWCPgDlgj4C5YI+c+WCPv7lgj7/5YI9/+iOUXn////A///////////////r5YI+/+WC
Pv/lgj7/5YI+5uWCPp7lgj6a5YI+reWCPu3lgj7/5YI+/+WBPPPtqntl////2///////////////puWC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/kfzml/PLrdf////v/////////zv//
/y7lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI++uWCPuTlhECX+NvHYv///9v////s////pv//
/y3///8A5YI+gOWCPoDlgj6A5YI+gOWCPoDlgj6A5YI+e+WCPmDlgDou+NvHFP///2H///9q////N///
/wn///8A////AAADAAAAAQAAAAAAAAAAAAD8AAAA5gAAAMAAAACAAAAAAAAAAAAAAAAGAAAABAAAAAAA
AAAAAAAAAAEAAAADAAAoAAAAGAAAADAAAAABACAAAAAAAAAJAAATCwAAEwsAAAAAAAAAAAAA5YI+P+WC
Pj/lgj4/5YI+P+WCPj/lgj4/5YI+P+WCPj/lgj4/5YI+PeWCPjDlgj4Z5YI+Bfrm2AD///8S////PP//
/zb///8f////CP///wD///8AAAAAAAAAAAAAAAAA5YI+8OWCPvDlgj7w5YI+8OWCPvDlgj7w5YI+8OWC
PvDlgj7w5YI+7+WCPuflgj7T5YI+p+WBPFnxupQe////dP///+D////b////tP///23///8e////AP//
/wAAAAAA5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
PvrlgT235ohIMv///3P////4//////////3////T////Vv///wP///8A5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YE9yOqcZyv///+n////////
////////////7////2D///8A5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+R/OYf///5H////9P///////////////////97///805YI+buWC
Pm/lgj5v5YI+b+WCPm/lgj5v5YI+b+WCPm/lgj5u5YI+euWCPrzlgj775YI+/+WCPv/lgj7/5YI+/+WB
PdLyv50t////0v////////////////////////+ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AADlgj4A5YI+AOWCPhLlgj6u5YI+/+WCPv/lgj7/5YI+/+WCPu3okFQ3////s///////////////////
///////dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5YI+AOWCPgDlgj5m5YI+/+WC
Pv/lgj7/5YI+/+WCPvPmiEc9////qP/////////////////////////5AAAAAAAAAAAAAAAA5YI+AOWC
PgHlgj4N5YI+AeWCPgAAAAAA5YI+AOWCPgLlgj6P5YI+/+WCPv/lgj7/5YI+/+WCPuvmiUkw////qP//
////////////////////////AAAAAAAAAADlgj4A5YI+AOWCPkTlgj5/5YI+EOWCPjHlgj4z5YI+POWC
PoPlgj7v5YI+/+WCPv/lgj7/5YI+/+WCPtDokVQX////qf//////////////////////////AAAAAOWC
PgDlgj4B5YI+TuWCPuPlgj6p5YI+POWCPuXlgj7w5YI+9OWCPv7lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pov//f0D////q///////////////////////////5YI+AOWCPgPlgj5f5YI+6OWCPv/lgj6n5YI+P+WC
PvTlgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+2eWBPSf///8B////q///////////////////
////////5YI+B+WCPm/lgj7w5YI+/+WCPv/lgj6n5YI+P+WCPvTlgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+2eWBPSf///8B////q///////////////////////////5YI+keWCPvTlgj7/5YI+/+WC
Pv/lgj6n5YI+O+WCPuTlgj7v5YI+8+WCPv7lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPoz++vcD////q///
////////////////////////5YI+/OWCPv/lgj7/5YI+/+WCPv/lgj6q5YI+DuWCPi/lgj4x5YI+OuWC
PoHlgj7v5YI+/+WCPv/lgj7/5YI+/+WCPtDokFQY////qf//////////////////////////5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj6r5YI+A+WCPgAAAAAA5YI+AOWCPgLlgj6O5YI+/+WCPv/lgj7/5YI+/+WC
PuvmiUkx////qP//////////////////////////5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj6r5YI+A+WC
PgAAAAAA5YI+AOWCPgDlgj5n5YI+/+WCPv/lgj7/5YI+/+WCPvPmiEc9////qP//////////////////
///////45YI+/+WCPv/lgj7/5YI+/+WCPv/lgj6q5YI+A+WCPgDlgj4A5YI+AOWCPhLlgj6v5YI+/+WC
Pv/lgj7/5YI+/+WCPu3okFQ3////s//////////////////////////Y5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7Q5YI+cuWCPnDlgj5w5YI+fOWCPr3lgj775YI+/+WCPv/lgj7/5YI+/+WBPdHywJ4t////0v//
//////////////////////+R5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+R/OYb///9I////9P///////////////////9n///8u5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YE9x+ud
aCv///+o////////////////////7P///1j///8A5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPvrlgTy15olJMf///3T////5//////////3////P////UP//
/wL///8A5YI+7+WCPvDlgj7w5YI+8OWCPvDlgj7w5YI+8OWCPvDlgj7w5YI+7uWCPublgj7S5YI+peWB
PFfxvZof////d////+H////b////sv///2r///8b////AP///wAAAAAA5YI+PuWCPj7lgj4+5YI+PuWC
Pj7lgj4+5YI+PuWCPj7lgj4+5YI+O+WCPi7lgj4Y5YI+BPrn2gD///8T////Pf///zf///8f////CP//
/wD///8AAAAAAAAAAAAAAAAAAAQfAAAABwAAAAEAAAABAAAAAAAAAAAA/8AAAP/gAADxwAAA8AAAAMAA
AACAAAAAAAAAAAAAAAAAAAAAAcAAAAHgAAABwAAAAAAAAAAAAAAAAAEAAAABAAAABwAABB8AKAAAACAA
AABAAAAAAQAgAAAAAAAAEAAAEwsAABMLAAAAAAAAAAAAAOWCPhLlgj4S5YI+EuWCPhLlgj4S5YI+EuWC
PhLlgj4S5YI+EuWCPhLlgj4S5YI+EuWCPhHlgj4N5YI+BOWCPgDlgj4A////AP///wD///8L////FP//
/w////8H////Af///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5YI+y+WCPszlgj7M5YI+zOWC
Pszlgj7M5YI+zOWCPszlgj7M5YI+zOWCPszlgj7M5YI+yuWCPsHlgj6r5YI+h+WCPlTlgj4ewgAAAf//
/yT///+V////x////7X///+V////Zf///y3///8G////AP///wAAAAAAAAAAAAAAAADlgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI++uWC
Ptrlgj6I5H02If///x7///+p/////v/////////+////6P///6f///9A////BP///wAAAAAAAAAAAOWC
Pv7lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7R5H44RP///xT///+u/////////////////////////+3///+C////D///
/wAAAAAA5YI+/uWCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7g5H02O////yr////d////////////////////////
//z///+W////DP///wDlgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj685HszEf///3//////////////
//////////////////r///9y////AOWCPvflgj745YI++OWCPvjlgj745YI++OWCPvjlgj745YI++OWC
Pvjlgj745YI++OWCPvrlgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPvnkfjdS////L///
/+v//////////////////////////////9z///8t5YI+RuWCPkblgj5G5YI+RuWCPkblgj5G5YI+RuWC
Pkblgj5G5YI+RuWCPkblgj5G5YI+TeWCPn7lgj7b5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WB
PZj//fwP////x////////////////////////////////v///4MAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADlgj4A5YI+AOWCPjnlgj7e5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+wOqaYw3///+n////////////////////////////////////yQAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADlgj4A5YI+AOWCPpDlgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7Q5Hs0Ef///5b////////////////////////////////////vAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOWCPgDlgj4A5YI+gOWC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPs3jdy4P////lP//////////////////////////////////
//0AAAAAAAAAAAAAAAAAAAAAAAAAAOWCPgDlgj4D5YI+EeWCPgHlgj4AAAAAAAAAAAAAAAAA5YI+AOWC
PhPlgj6+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+uuBrGwf///+U////////////////////////
/////////////wAAAAAAAAAAAAAAAAAAAADlgj4A5YI+AuWCPl3lgj575YI+AeWCPgvlgj4N5YI+DeWC
PhDlgj4w5YI+n+WCPvzlgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj6T9dG4AP///5X/////////////
///////////////////////+AAAAAAAAAAAAAAAA5YI+AOWCPgXlgj5q5YI+8eWCPpXlgj4O5YI+pOWC
Psnlgj7G5YI+zeWCPunlgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI++eWCPlLsom8A////lf//
//////////////////////////////////4AAAAAAAAAAOWCPgDlgj4J5YI+e+WCPvPlgj7/5YI+lOWC
PhPlgj7T5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7B5YI+E/LC
oQD///+V/////////////////////////////////////gAAAADlgj4A5YI+D+WCPo3lgj745YI+/+WC
Pv/lgj6U5YI+E+WCPtPlgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+7+WC
PknlhEEA//79AP///5X////////////////////////////////////+5YI+AOWCPhblgj6e5YI+/OWC
Pv/lgj7/5YI+/+WCPpTlgj4T5YI+0+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7v5YI+S+WEQQD//f0A////lf////////////////////////////////////7lgj4k5YI+reWC
Pv7lgj7/5YI+/+WCPv/lgj7/5YI+lOWCPhPlgj7T5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7C5YI+E/LBoAD///+V/////////////////////////////////////uWC
Pszlgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj6U5YI+DuWCPqLlgj7G5YI+xOWCPsvlgj7o5YI+/uWC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPvnlgj5T7KJvAP///5X/////////////////////////////
///////+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPpXlgj4A5YI+CuWCPgzlgj4M5YI+D+WC
Pi7lgj6e5YI+++WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPpP21LwA////lf//////////////////
//////////////////7lgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+leWCPgDlgj4AAAAAAAAA
AAAAAAAA5YI+AOWCPhLlgj695YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+u+BrGwf///+U////////
/////////////////////////////+WCPv7lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj6V5YI+AOWC
PgAAAAAAAAAAAAAAAADlgj4A5YI+AOWCPoDlgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7N43cuEP//
/5T////////////////////////////////////85YI+/uWCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
PpXlgj4A5YI+AAAAAAAAAAAAAAAAAOWCPgDlgj4A5YI+keWCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
PtDkfDQR////lv///////////////////////////////////+vlgj7+5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+lOWCPgDlgj4AAAAAAAAAAADlgj4A5YI+AOWCPjrlgj7f5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+wOqaZA3///+n////////////////////////////////////wuWCPv7lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj6z5YI+R+WCPkjlgj5I5YI+SOWCPk/lgj6A5YI+3OWCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgT2X//79D////8j///////////////////////////////z///955YI+/uWC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPvzlgj745YI++OWCPvjlgj745YI+++WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI++OR9N1H///8w////7P//////////////////////////////1f//
/yblgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj675Hw0EP///4D/////////////////////////////
//j///9n////AOWCPv7lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+3+R9Njr///8r////3f//////////////////
///////6////i////wn///8A5YI+/uWCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPtDkfjhC////Ff///7D/////////////
////////////6f///3j///8L////AAAAAADlgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI++uWCPtnlgj6G5H02IP///x////+r/////v//
///////9////5v///6H///86////A////wAAAAAAAAAAAOWCPsrlgj7K5YI+yuWCPsrlgj7K5YI+yuWC
Psrlgj7K5YI+yuWCPsrlgj7K5YI+yuWCPsjlgj6/5YI+qeWCPoXlgj5S5YI+HbwAAAH///8n////mP//
/8j///+1////lP///2P///8q////Bf///wD///8AAAAAAAAAAAAAAAAA5YI+EeWCPhHlgj4R5YI+EeWC
PhHlgj4R5YI+EeWCPhHlgj4R5YI+EeWCPhHlgj4R5YI+EOWCPgzlgj4E5YI+AOWCPgD///8A////AP//
/wz///8V////EP///wj///8B////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeD/AAAAHwAA
AAcAAAADAAAAAQAAAAEAAAAAAAAAAP/8AAD//gAA//4AAPx8AAD4AAEA8AABAOAAAQDAAAMAgAADAAAA
AQAAAAEAAIABAAD8AAAA/gAAAP4AAAD8AAAAAAAAAAAAAAAAAAEAAAABAAAAAwAAAAcAAAAfAAHg/ygA
AAAwAAAAYAAAAAEAIAAAAAAAACQAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADlgj5V5YI+VeWC
PlXlgj5V5YI+VeWCPlXlgj5V5YI+VeWCPlXlgj5V5YI+VeWCPlXlgj5V5YI+VeWCPlXlgj5V5YI+VeWC
PlXlgj5U5YI+TuWCPkHlgj4t5YI+GeWCPgjlgj4A5YI+AAAAAAD///8A////BP///zX///9V////Uv//
/0r///85////JP///xD///8C////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AADlgj785YI+/eWCPv3lgj795YI+/eWCPv3lgj795YI+/eWCPv3lgj795YI+/eWCPv3lgj795YI+/eWC
Pv3lgj795YI+/eWCPv3lgj795YI+++WCPvXlgj7q5YI+1+WCPrflgj6F5YI+R+WCPhPSJwAA////Af//
/yz///+h////9v////v////y////4////8n///+e////Y////yf///8F////AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAADlgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+9uWC
Psrlgj5z5YI+HPjgywD///8L////cf///+3//////////////////////////f///+P///+e////QP//
/wb///8AAAAAAAAAAAAAAAAAAAAAAAAAAADlgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj795YI+zeWCPlXkezMF////Av///1/////t////////////////////////
////////////7v///5j///8l////AP///wAAAAAAAAAAAAAAAADlgj7+5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPvHlgj595H44Cf///wH///9y////+P//
///////////////////////////////////////R////Rv///wH///8AAAAAAAAAAADlgj7+5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj745YI+fd9n
FAT///8L////p///////////////////////////////////////////////5P///1D///8A////AAAA
AADlgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+8OWCPlPzx6gA////Nv///+f/////////////////////////////////////////////
/9////87////AP///wDlgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPsflgDsX////Av///5v/////////////////////////////
//////////////////////+9////Ff///wDlgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPvvlgj5h88SjAP///0v////2////////
///////////////////////////////////////8////bf///wDlgj7H5YI+yOWCPsjlgj7I5YI+yOWC
Psjlgj7I5YI+yOWCPsjlgj7I5YI+yOWCPsjlgj7I5YI+yOWCPsjlgj7I5YI+yOWCPsjlgj7M5YI+4OWC
Pvnlgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj6u3FUABf//
/xr////W////////////////////////////////////////////////////yf///xnlgj4O5YI+DuWC
Pg7lgj4O5YI+DuWCPg7lgj4O5YI+DuWCPg7lgj4O5YI+DuWCPg7lgj4O5YI+DuWCPg7lgj4O5YI+DuWC
Pg7lgj4R5YI+IeWCPlnlgj7D5YI+/uWCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7d5YE8H////wP///+u////////////////////////////////////////////////////9f//
/1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA5YI+AOWCPgDlgj4c5YI+s+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7z5YI+Pe6vhAD///+L////////////////////////////////////////
/////////////////5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOWCPgDlgj4A5YI+N+WCPunlgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj775YI+VPG9mQD///90////////////////////////
/////////////////////////////////84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADlgj4A5YI+CuWC
Prvlgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7+5YI+X/LAngD///9p////////
/////////////////////////////////////////////////+0AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AADlgj4A5YI+BOWCPq3lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj795YI+W/LA
ngD///9o//////////////////////////////////////////////////////////sAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAADlgj4A5YI+FOWCPs3lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj755YI+TPLCoAD///9o////////////////////////////////////////////////////////
//4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADlgj4A5YI+DeWCPhflgj4A5YI+AAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAOWCPgDlgj4A5YI+YuWCPvjlgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7v5YI+NfTJrAD///9o////////////////////////////////////////
//////////////////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5YI+AOWCPgDlgj4R5YI+keWC
PmHlgj4A5YI+AAAAAAAAAAAAAAAAAAAAAADlgj4A5YI+AOWCPgjlgj5W5YI+4eWCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7X5YI+GvjcyQD///9o////////////////////////
//////////////////////////////////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADlgj4A5YI+AOWC
Phjlgj6i5YI+/OWCPmjlgj4A5YI+HeWCPkzlgj5M5YI+TOWCPkzlgj5Q5YI+beWCPq/lgj7x5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj6n5YI+BP328AD///9o////////
//////////////////////////////////////////////////4AAAAAAAAAAAAAAAAAAAAAAAAAAOWC
PgDlgj4A5YI+IuWCPrLlgj7+5YI+/+WCPmjlgj4A5YI+YOWCPvnlgj755YI++eWCPvnlgj775YI+/uWC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPvvlgj5e5YI+AP//
/wD///9o//////////////////////////////////////////////////////////4AAAAAAAAAAAAA
AAAAAAAA5YI+AOWCPgDlgj4t5YI+weWCPv/lgj7/5YI+/+WCPmjlgj4A5YI+YuWCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pszlgj4Z5YI+AP///wD///9o////////////////////////////////////////////////////////
//4AAAAAAAAAAAAAAADlgj4A5YI+AOWCPjvlgj7P5YI+/+WCPv/lgj7/5YI+/+WCPmjlgj4A5YI+YuWC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+9uWCPl/lgj4A5YNAAP///wD///9o////////////////////////////////////////
//////////////////4AAAAAAAAAAOWCPgDlgj4B5YI+SeWCPtrlgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pmjlgj4A5YI+YuWCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+meWCPgjlgj4A////AP///wD///9o////////////////////////
//////////////////////////////////4AAAAA5YI+AOWCPgLlgj5Z5YI+5OWCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPmjlgj4A5YI+YuWCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+m+WCPgnlgj4A////AP///wD///9o////////
//////////////////////////////////////////////////7lgj4A5YI+BeWCPmrlgj7t5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPmjlgj4A5YI+YuWCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+9+WCPmHlgj4A5YNAAP//
/wD///9o//////////////////////////////////////////////////////////7lgj4L5YI+e+WC
PvPlgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPmjlgj4A5YI+YuWCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Ps3lgj4a5YI+AP///wD///9o////////////////////////////////////////////////////////
//7lgj6c5YI+9uWCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPmjlgj4A5YI+X+WC
Pvjlgj745YI++OWCPvjlgj765YI+/uWCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPvvlgj5g5YI+AP///wD///9o////////////////////////////////////////
//////////////////7lgj795YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pmjlgj4A5YI+HOWCPkjlgj5I5YI+SOWCPkjlgj5N5YI+auWCPqzlgj7w5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj6o5YI+Bf318AD///9o////////////////////////
//////////////////////////////////7lgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPmjlgj4A5YI+AAAAAAAAAAAAAAAAAAAAAADlgj4A5YI+AOWCPgflgj5U5YI+4OWC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7X5YI+GvjbyAD///9o////////
//////////////////////////////////////////////////7lgj7+5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPmjlgj4A5YI+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOWC
PgDlgj4A5YI+YOWCPvjlgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7v5YI+NfTJ
rAD///9o//////////////////////////////////////////////////////////7lgj7+5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPmjlgj4A5YI+AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAADlgj4A5YI+FOWCPszlgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj755YI+TPLCoAD///9o////////////////////////////////////////////////////////
//7lgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPmjlgj4A5YI+AAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADlgj4A5YI+BOWCPq3lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj795YI+W/LAngD///9o////////////////////////////////////////
//////////////////nlgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pmjlgj4A5YI+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADlgj4A5YI+CuWCPrzlgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7+5YI+X/LAngD///9p////////////////////////
/////////////////////////////////+jlgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPmjlgj4A5YI+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOWCPgDlgj4A5YI+OOWC
Purlgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj775YI+VPG9mQD///90////////
/////////////////////////////////////////////////8blgj7+5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPmflgj4A5YI+AAAAAAAAAAAAAAAAAAAAAAAAAAAA5YI+AOWC
PgDlgj4d5YI+teWCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7z5YI+Pe6v
gwD///+L/////////////////////////////////////////////////////////5Dlgj7+5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPnHlgj4M5YI+EOWCPhDlgj4Q5YI+EOWC
PhDlgj4S5YI+I+WCPlzlgj7F5YI+/uWCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7c5YE8Hv///wP///+v////////////////////////////////////////////////////8f//
/0vlgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPuDlgj7K5YI+yuWC
Psrlgj7K5YI+yuWCPsrlgj7P5YI+4uWCPvrlgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj6t21EABP///xr////X////////////////////////////////////////
////////////vv///xLlgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPvvlgj5f88OjAP///0z////3////////////////////////
///////////////////////5////X////wDlgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPsblgDsW////Av///53/////////////
//////////////////////////////////////+v////Dv///wDlgj7+5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+7+WCPlHzxqgA////N///
/+j//////////////////////////////////////////////9X///8v////AP///wDlgj7+5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj735YI+et5h
CwP///8M////qf//////////////////////////////////////////////2////0L///8A////AAAA
AADlgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
PvDlgj565H43CP///wL///90////+f////////////////////////////////////7////G////Ov//
/wD///8AAAAAAAAAAADlgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj785YI+y+WCPlLjeTAE////Av///2L////u////////////////////////////////////6v//
/43///8d////AP///wAAAAAAAAAAAAAAAADlgj7+5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC
Pv/lgj7/5YI+9OWCPsflgj5w5YI+GvbVvgD///8M////dP///+7//////////////////////////P//
/9////+X////OP///wT///8AAAAAAAAAAAAAAAAAAAAAAAAAAADlgj775YI+/OWCPvzlgj785YI+/OWC
Pvzlgj785YI+/OWCPvzlgj785YI+/OWCPvzlgj785YI+/OWCPvzlgj785YI+/OWCPvzlgj785YI++uWC
PvTlgj7p5YI+1eWCPrTlgj6B5YI+ROWCPhL///8A////Af///zD///+l////9/////v////y////4///
/8j///+b////X////yT///8D////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADlgj5S5YI+U+WC
PlPlgj5T5YI+U+WCPlPlgj5T5YI+U+WCPlPlgj5T5YI+U+WCPlPlgj5T5YI+U+WCPlPlgj5T5YI+U+WC
PlPlgj5S5YI+TOWCPj7lgj4r5YI+F+WCPgflgj4A5YI+AAAAAAD///8A////Bf///zn///9Y////VP//
/0v///86////JP///w////8C////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
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
</value>
</data>
</root>

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BetterDiscordWI {
static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FormMain());
}
}
}

View File

@ -2,35 +2,35 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("WinRepair")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTitle("BetterDiscordWI")]
[assembly: AssemblyDescription("BetterDiscord Windows Installer")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WinRepair")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyCompany("CSharpForLife")]
[assembly: AssemblyProduct("BetterDiscordWI")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("5b1dac68-94c6-4d74-bd41-66bbf2ab18a5")]
[assembly: Guid("390615f1-ce33-4173-9e8c-4e4f3eb1758d")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("0.3.0.0")]
[assembly: AssemblyFileVersion("0.3.0.0")]

View File

@ -0,0 +1,83 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace BetterDiscordWI.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BetterDiscordWI.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Betterdiscord_small_black_blue {
get {
object obj = ResourceManager.GetObject("Betterdiscord_small_black_blue", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Betterdiscord_small_white_blue {
get {
object obj = ResourceManager.GetObject("Betterdiscord_small_white_blue", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

View File

@ -0,0 +1,127 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="Betterdiscord_small_black_blue" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Betterdiscord small black+blue.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Betterdiscord_small_white_blue" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Betterdiscord small white+blue.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View File

@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace BetterDiscordWI.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.1.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

@ -0,0 +1,22 @@
using System;
using System.Net;
using System.Threading.Tasks;
namespace BetterDiscordWI {
public static class Utils {
public static WebHeaderCollection Headers = new WebHeaderCollection { ["User-Agent"] = "Mozilla/5.0" };
public static async Task<string> GetHash() {
using (var wc = new WebClient { Headers = Headers }) {
var result = await wc.DownloadStringTaskAsync(@"https://api.github.com/repos/Jiiks/BetterDiscordApp/commits/master");
var start = result.IndexOf("{\"sha\":") + 8;
var end = result.IndexOf("\",\"") - 8;
return result.Substring(start, end);
}
}
}
}

View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Specifying requestedExecutionLevel element will disable file and registry virtualization.
Remove this element if your application requires this virtualization for backwards
compatibility.
-->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on and is
is designed to work with. Uncomment the appropriate elements and Windows will
automatically selected the most compatible environment. -->
<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
<!-- Windows 7 -->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
<!-- Windows 8 -->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
<!-- Windows 8.1 -->
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
<!-- Windows 10 -->
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
</application>
</compatibility>
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
<!--
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
-->
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
<!--
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
-->
</assembly>

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,31 @@
namespace BetterDiscordWI.controls {
partial class Button {
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@ -0,0 +1,36 @@
namespace BetterDiscordWI.controls {
public partial class Button : System.Windows.Forms.Button {
public Button() {
InitializeComponent();
}
public Button HideDisable(string newText = null) {
if (newText != null) Text = newText;
Hide();
Enabled = false;
return this;
}
public Button HideEnable(string newText = null) {
if (newText != null) Text = newText;
Hide();
Enabled = true;
return this;
}
public Button ShowDisable(string newText = null) {
if (newText != null) Text = newText;
Show();
Enabled = false;
return this;
}
public Button ShowEnable(string newText = null) {
if (newText != null) Text = newText;
Show();
Enabled = true;
return this;
}
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Costura.Fody" version="1.6.2" targetFramework="net462" developmentDependency="true" />
<package id="Fody" version="2.0.0" targetFramework="net462" developmentDependency="true" />
</packages>

View File

@ -0,0 +1,205 @@
namespace BetterDiscordWI.panels {
partial class ConfigPanel {
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
this.label1 = new System.Windows.Forms.Label();
this.tbPath = new System.Windows.Forms.TextBox();
this.btnBrowse = new BetterDiscordWI.controls.Button();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.cbRestart = new System.Windows.Forms.CheckBox();
this.cbCanary = new System.Windows.Forms.CheckBox();
this.cbPtb = new System.Windows.Forms.CheckBox();
this.lblCanarywarning = new System.Windows.Forms.Label();
this.lblPtbwarning = new System.Windows.Forms.Label();
this.cbStable = new System.Windows.Forms.CheckBox();
this.lblStablewarning = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(3, 3);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(380, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Setup will install BetterDiscord to the following location. Click Install to cont" +
"inue.";
//
// tbPath
//
this.tbPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tbPath.Location = new System.Drawing.Point(6, 31);
this.tbPath.Name = "tbPath";
this.tbPath.ReadOnly = true;
this.tbPath.Size = new System.Drawing.Size(377, 20);
this.tbPath.TabIndex = 1;
//
// btnBrowse
//
this.btnBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnBrowse.Location = new System.Drawing.Point(389, 31);
this.btnBrowse.Name = "btnBrowse";
this.btnBrowse.Size = new System.Drawing.Size(75, 23);
this.btnBrowse.TabIndex = 2;
this.btnBrowse.Text = "Browse";
this.btnBrowse.UseVisualStyleBackColor = true;
this.btnBrowse.Click += new System.EventHandler(this.btnBrowse_Click);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(3, 66);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(422, 13);
this.label2.TabIndex = 3;
this.label2.Text = "*If the path is not pointing to the latest version of Discord then click browse a" +
"nd select it.";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(3, 79);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(161, 13);
this.label3.TabIndex = 4;
this.label3.Text = "*Installer will kill Discord process.";
//
// cbRestart
//
this.cbRestart.AutoSize = true;
this.cbRestart.Location = new System.Drawing.Point(6, 106);
this.cbRestart.Name = "cbRestart";
this.cbRestart.Size = new System.Drawing.Size(175, 17);
this.cbRestart.TabIndex = 5;
this.cbRestart.Text = "Restart Discord after installation";
this.cbRestart.UseVisualStyleBackColor = true;
this.cbRestart.CheckedChanged += new System.EventHandler(this.cbRestart_CheckedChanged);
//
// cbCanary
//
this.cbCanary.AutoSize = true;
this.cbCanary.Location = new System.Drawing.Point(6, 150);
this.cbCanary.Name = "cbCanary";
this.cbCanary.Size = new System.Drawing.Size(137, 17);
this.cbCanary.TabIndex = 6;
this.cbCanary.Text = "Install to DiscordCanary";
this.cbCanary.UseVisualStyleBackColor = true;
this.cbCanary.CheckedChanged += new System.EventHandler(this.cbCanary_CheckedChanged);
//
// cbPtb
//
this.cbPtb.AutoSize = true;
this.cbPtb.Location = new System.Drawing.Point(6, 173);
this.cbPtb.Name = "cbPtb";
this.cbPtb.Size = new System.Drawing.Size(125, 17);
this.cbPtb.TabIndex = 7;
this.cbPtb.Text = "Install to DiscordPTB";
this.cbPtb.UseVisualStyleBackColor = true;
this.cbPtb.CheckedChanged += new System.EventHandler(this.cbPtb_CheckedChanged);
//
// lblCanarywarning
//
this.lblCanarywarning.AutoSize = true;
this.lblCanarywarning.ForeColor = System.Drawing.Color.Red;
this.lblCanarywarning.Location = new System.Drawing.Point(149, 151);
this.lblCanarywarning.Name = "lblCanarywarning";
this.lblCanarywarning.Size = new System.Drawing.Size(97, 13);
this.lblCanarywarning.TabIndex = 8;
this.lblCanarywarning.Text = "(Canary not found!)";
this.lblCanarywarning.Visible = false;
//
// lblPtbwarning
//
this.lblPtbwarning.AutoSize = true;
this.lblPtbwarning.ForeColor = System.Drawing.Color.Red;
this.lblPtbwarning.Location = new System.Drawing.Point(149, 173);
this.lblPtbwarning.Name = "lblPtbwarning";
this.lblPtbwarning.Size = new System.Drawing.Size(85, 13);
this.lblPtbwarning.TabIndex = 9;
this.lblPtbwarning.Text = "(PTB not found!)";
this.lblPtbwarning.Visible = false;
//
// cbStable
//
this.cbStable.AutoSize = true;
this.cbStable.Location = new System.Drawing.Point(6, 127);
this.cbStable.Name = "cbStable";
this.cbStable.Size = new System.Drawing.Size(98, 17);
this.cbStable.TabIndex = 10;
this.cbStable.Text = "Install to Stable";
this.cbStable.UseVisualStyleBackColor = true;
this.cbStable.CheckedChanged += new System.EventHandler(this.cbStable_CheckedChanged);
//
// lblStablewarning
//
this.lblStablewarning.AutoSize = true;
this.lblStablewarning.ForeColor = System.Drawing.Color.Red;
this.lblStablewarning.Location = new System.Drawing.Point(149, 128);
this.lblStablewarning.Name = "lblStablewarning";
this.lblStablewarning.Size = new System.Drawing.Size(97, 13);
this.lblStablewarning.TabIndex = 11;
this.lblStablewarning.Text = "(Canary not found!)";
this.lblStablewarning.Visible = false;
//
// ConfigPanel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.lblStablewarning);
this.Controls.Add(this.cbStable);
this.Controls.Add(this.lblPtbwarning);
this.Controls.Add(this.lblCanarywarning);
this.Controls.Add(this.cbPtb);
this.Controls.Add(this.cbCanary);
this.Controls.Add(this.cbRestart);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.btnBrowse);
this.Controls.Add(this.tbPath);
this.Controls.Add(this.label1);
this.Name = "ConfigPanel";
this.Size = new System.Drawing.Size(538, 284);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox tbPath;
private controls.Button btnBrowse;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.CheckBox cbRestart;
private System.Windows.Forms.CheckBox cbCanary;
private System.Windows.Forms.CheckBox cbPtb;
private System.Windows.Forms.Label lblCanarywarning;
private System.Windows.Forms.Label lblPtbwarning;
private System.Windows.Forms.CheckBox cbStable;
private System.Windows.Forms.Label lblStablewarning;
}
}

View File

@ -0,0 +1,128 @@
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace BetterDiscordWI.panels {
public partial class ConfigPanel : UserControl, IPanel {
private FormMain _formMain;
private readonly Regex _matcher = new Regex(@"[0-9]+\.[0-9]+\.[0-9]+");
private static string StablePath => $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\Discord";
private static bool StableExists() => Directory.Exists(StablePath);
private static string CanaryPath => $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\DiscordCanary";
private static bool CanaryExists() => Directory.Exists(CanaryPath);
private static string PtbPath => $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\DiscordPTB";
private static bool PtbExists() => Directory.Exists(PtbPath);
public ConfigPanel() {
InitializeComponent();
}
public void ShowPanel() {
_formMain.btnBack.ShowEnable();
_formMain.btnCancel.ShowEnable();
_formMain.btnNext.ShowEnable("Install");
if (!CanaryExists()) {
lblCanarywarning.Show();
cbCanary.Enabled = false;
}
if (!PtbExists()) {
lblPtbwarning.Show();
cbPtb.Enabled = false;
}
if (!StableExists()) {
lblStablewarning.Show();
cbStable.Enabled = false;
}
if (!StableExists() && !CanaryExists() && PtbExists()) {
_formMain.btnNext.ShowDisable();
}
cbRestart.Checked = _formMain.RestartDiscord;
cbCanary.Checked = _formMain.Canary;
cbPtb.Checked = _formMain.Ptb;
cbStable.Checked = _formMain.Stable;
LocateDiscord();
Show();
}
public void HidePanel() {
Hide();
}
public void SetForm(FormMain formMain) => _formMain = formMain;
public string Title => "Installation";
public UserControl Control => this;
private void btnBrowse_Click(object sender, System.EventArgs e) {
var fbd = new FolderBrowserDialog {SelectedPath = tbPath.Text};
fbd.ShowDialog();
tbPath.Text = fbd.SelectedPath;
_formMain.DiscordPath = fbd.SelectedPath;
}
private void LocateDiscord() {
var finalPath = GetLatestVersion(cbPtb.Checked ? PtbPath : cbCanary.Checked ? CanaryPath : StablePath);
if (finalPath == string.Empty) finalPath = "Not found!";
tbPath.Text = finalPath;
_formMain.DiscordPath = finalPath;
_formMain.Stable = cbStable.Checked;
_formMain.Canary = cbCanary.Checked;
_formMain.Ptb = cbPtb.Checked;
}
private string GetLatestVersion(string path) {
var dirs = Directory.GetDirectories(path);
if (dirs.Length <= 0) return string.Empty;
var latest = dirs[0];
foreach (var dir in dirs) {
if (!_matcher.IsMatch(dir)) continue;
if (string.CompareOrdinal(dir, latest) > 0) latest = dir;
}
return latest;
}
private void cbCanary_CheckedChanged(object sender, EventArgs e) {
if (cbCanary.Checked) {
cbPtb.Checked = false;
cbStable.Checked = false;
}
LocateDiscord();
}
private void cbPtb_CheckedChanged(object sender, EventArgs e) {
if (cbPtb.Checked) {
cbCanary.Checked = false;
cbStable.Checked = false;
}
LocateDiscord();
}
private void cbRestart_CheckedChanged(object sender, EventArgs e) {
_formMain.RestartDiscord = cbRestart.Checked;
}
private void cbStable_CheckedChanged(object sender, EventArgs e) {
if (cbStable.Checked) {
cbCanary.Checked = false;
cbPtb.Checked = false;
}
LocateDiscord();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,11 @@
using System.Windows.Forms;
namespace BetterDiscordWI.panels {
internal interface IPanel {
void ShowPanel();
void HidePanel();
void SetForm(FormMain formMain);
string Title { get; }
UserControl Control { get; }
}
}

View File

@ -0,0 +1,98 @@
namespace BetterDiscordWI.panels {
partial class InstallPanel {
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
this.rtbStatus = new System.Windows.Forms.RichTextBox();
this.pbStatus = new System.Windows.Forms.ProgressBar();
this.cbDetailed = new System.Windows.Forms.CheckBox();
this.rtbDetailed = new System.Windows.Forms.RichTextBox();
this.SuspendLayout();
//
// rtbStatus
//
this.rtbStatus.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.rtbStatus.Location = new System.Drawing.Point(3, 3);
this.rtbStatus.Name = "rtbStatus";
this.rtbStatus.Size = new System.Drawing.Size(492, 126);
this.rtbStatus.TabIndex = 0;
this.rtbStatus.Text = "";
//
// pbStatus
//
this.pbStatus.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.pbStatus.Location = new System.Drawing.Point(67, 135);
this.pbStatus.Name = "pbStatus";
this.pbStatus.Size = new System.Drawing.Size(428, 23);
this.pbStatus.TabIndex = 1;
//
// cbDetailed
//
this.cbDetailed.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.cbDetailed.AutoSize = true;
this.cbDetailed.Location = new System.Drawing.Point(4, 138);
this.cbDetailed.Name = "cbDetailed";
this.cbDetailed.Size = new System.Drawing.Size(58, 17);
this.cbDetailed.TabIndex = 2;
this.cbDetailed.Text = "Details";
this.cbDetailed.UseVisualStyleBackColor = true;
this.cbDetailed.CheckedChanged += new System.EventHandler(this.cbDetailed_CheckedChanged);
//
// rtbDetailed
//
this.rtbDetailed.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.rtbDetailed.Location = new System.Drawing.Point(3, 3);
this.rtbDetailed.Name = "rtbDetailed";
this.rtbDetailed.Size = new System.Drawing.Size(492, 126);
this.rtbDetailed.TabIndex = 3;
this.rtbDetailed.Text = "";
this.rtbDetailed.Visible = false;
//
// InstallPanel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.rtbDetailed);
this.Controls.Add(this.cbDetailed);
this.Controls.Add(this.pbStatus);
this.Controls.Add(this.rtbStatus);
this.Name = "InstallPanel";
this.Size = new System.Drawing.Size(501, 166);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.RichTextBox rtbStatus;
private System.Windows.Forms.ProgressBar pbStatus;
private System.Windows.Forms.CheckBox cbDetailed;
private System.Windows.Forms.RichTextBox rtbDetailed;
}
}

View File

@ -0,0 +1,315 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using asardotnetasync;
namespace BetterDiscordWI.panels {
public partial class InstallPanel : UserControl, IPanel {
private FormMain _formMain;
private readonly SynchronizationContext _synchronizationContext;
private string _asarPath => $"{_formMain.DiscordPath}\\modules\\discord_desktop_core";
public InstallPanel() {
InitializeComponent();
_synchronizationContext = SynchronizationContext.Current;
}
private async Task<int> InstallTask() {
var asarExists = LocateAsar();
if (!asarExists) return 0;
Append("Killing Discord Processes");
var discordPname = _formMain.Canary ? "DiscordCanary" : _formMain.Ptb ? "DiscordPTB" : "Discord";
string discordExePath = null;
foreach (var process in Process.GetProcessesByName(discordPname)) {
Append($"Killing Discord process {process.Id}", true);
discordExePath = process.MainModule.FileName;
process.Kill();
}
if (await AsarExtract() != 1) return 0;
if (await InjectBd() != 1) return 0;
if (await DownloadBd() != 1) return 0;
if (await Verify() != 1) return 0;
if (_formMain.RestartDiscord && discordExePath != null) {
Append("Restarting Discord");
Process.Start(discordExePath);
}
Append("Finished installing BetterDiscord!");
return 1;
}
private async Task<int> AsarExtract() {
Append("Extracting core.asar");
var asarArchive = new AsarArchive($"{_asarPath}\\core.asar");
var asarExtractor = new AsarExtractor();
asarExtractor.FileExtracted += (s, e) => {
_synchronizationContext.Post(o => {
pbStatus.Value = (int)((AsarExtractEvent)o).Progress;
}, e);
Append(e.File.Path, true);
};
asarExtractor.Finished += (s, e) => {
Append($"Finished extracting core.asar");
};
try {
if (!Directory.Exists($"{_asarPath}\\app")) Directory.CreateDirectory($"{_asarPath}\\core");
await asarExtractor.ExtractAll(asarArchive, $"{_asarPath}\\core\\");
}
catch (Exception e) {
Debug.Print(e.Message);
}
return 1;
}
private async Task<int> InjectBd() {
var mainScreenPath = $"{_asarPath}\\core\\app\\mainScreen.js";
var indexPath = $"{_asarPath}\\index.js";
Append($"Injecting BetterDiscord to {_asarPath}\\core");
if (!File.Exists(mainScreenPath)) {
Append($"{mainScreenPath} does not exist! Cannot continue.");
_formMain.Fail();
return 0;
}
Append("Rewriting index.js");
File.WriteAllText(indexPath, "module.exports = require('./core');");
var lines = new List<string>();
foreach (var line in File.ReadAllLines(mainScreenPath)) {
lines.Add(line);
if (line.Contains("mainWindow = new")) {
lines.Add(" _betterDiscord2 = new _betterDiscord.BetterDiscord(mainWindow);");
}
}
lines.Insert(1, "var _betterDiscord = require('BetterDiscord');");
lines.Insert(2, "var _betterDiscord2;");
File.WriteAllLines(mainScreenPath, lines.ToArray());
Append("Finished injecting BetterDiscord");
return 1;
}
private async Task<int> DownloadBd() {
Append("Fetching latest hash");
// var hash = await Utils.GetHash();
// Append($"Latest hash: {hash}");
var repo = "Jiiks";
var branch = "stable16";
var channel = $"https://github.com/{repo}/BetterDiscordApp/archive/{branch}.zip";
var dest = $"{_formMain.DiscordPath}\\modules\\discord_desktop_core\\BetterDiscord.zip";
Append("Downloading BetterDiscord package");
using (var wc = new WebClient {Headers = Utils.Headers}) {
wc.DownloadProgressChanged += (sender, args) => {
_synchronizationContext.Post(e => {
var state = (DownloadProgressChangedEventArgs) e;
pbStatus.Value = state.ProgressPercentage;
}, args);
};
Append($"Using channel: {channel}", true);
Append($"Downloading to: {dest}", true);
await wc.DownloadFileTaskAsync(channel, dest);
}
Append("Finished downloading BetterDiscord package");
await ExtractBd(dest, $"{_formMain.DiscordPath}\\modules\\discord_desktop_core\\node_modules");
return 1;
}
private async Task<int> ExtractBd(string path, string dest) {
if (Directory.Exists($"{dest}\\BetterDiscord")) {
Append("Deleting old BetterDiscord");
Directory.Delete($"{dest}\\BetterDiscord", true);
}
if (Directory.Exists($"{dest}\\BetterDiscordApp-stable16")) {
Append("Deleting old BetterDiscordApp-stable16");
Directory.Delete($"{dest}\\BetterDiscordApp-stable16", true);
}
Append("Extracting BetterDiscord package");
if (!File.Exists(path)) {
Append($"BetterDiscord package does not exist in: {path}. Cannot continue.");
_formMain.Fail();
return 0;
}
var zar = ZipFile.OpenRead(path);
if (!Directory.Exists(dest)) {
Directory.CreateDirectory(dest);
}
zar.ExtractToDirectory(dest);
zar.Dispose();
if (!Directory.Exists($"{dest}\\BetterDiscordApp-stable16")) {
Append($"BetterDiscord package does not exist in: {dest}\\BetterDiscordApp-stable16. Cannot continue.");
_formMain.Fail();
return 0;
}
Append("Renaming package dir", true);
Directory.Move($"{dest}\\BetterDiscordApp-stable16", $"{dest}\\BetterDiscord");
if (File.Exists(path)) {
Append($"Deleting temp file {path}");
File.Delete(path);
}
return 1;
}
private async Task<int> Verify() {
Append("Verifying installation");
var mainScreenPath = $"{_asarPath}\\core\\app\\mainScreen.js";
var indexPath = $"{_asarPath}\\index.js";
Append("Verifying: Discord files");
if (!File.ReadAllText(indexPath).Contains("module.exports = require('./core');")) {
Append($"{indexPath} NOT OK! Verification failed!");
_formMain.Fail();
return 0;
}
var mainScreen = File.ReadAllText(mainScreenPath);
if (!mainScreen.Contains("var _betterDiscord = require('BetterDiscord');") && mainScreen.Contains("var _betterDiscord2;") && mainScreen.Contains("_betterDiscord2 = new _betterDiscord.BetterDiscord(mainWindow);")) {
Append($"{mainScreenPath} NOT OK! Verification failed!");
_formMain.Fail();
return 0;
}
Append($"Verifying BetterDiscord package");
var modulePath = $"{_formMain.DiscordPath}\\modules\\discord_desktop_core\\node_modules";
if (!Directory.Exists(modulePath)) {
Append($"{modulePath} does not exist! Verification failed!");
_formMain.Fail();
return 0;
}
var bdPath = $"{modulePath}\\BetterDiscord";
if (!Directory.Exists(modulePath)) {
Append($"{modulePath} does not exist! Verification failed!");
_formMain.Fail();
return 0;
}
var currentPath = $"{bdPath}\\lib";
if (!Directory.Exists(currentPath)) {
Append($"{currentPath} does not exist! Verification failed!");
_formMain.Fail();
return 0;
}
var bdFiles = new[]{"betterdiscord.js", "package.json", "lib\\BetterDiscord.js", "lib\\config.json", "lib\\Utils.js"};
foreach (var bdFile in bdFiles) {
if (File.Exists($"{bdPath}\\{bdFile}")) continue;
Append($"{bdPath}\\{bdFile} does not exist! Verification failed!");
_formMain.Fail();
return 0;
}
Append("Verification successful");
return 1;
}
public void ShowPanel() {
_formMain.btnBack.HideDisable();
_formMain.btnNext.HideDisable();
_formMain.btnCancel.ShowDisable("Exit");
rtbStatus.Text = "";
Task.Run(InstallTask).ContinueWith(result => {
Debug.WriteLine($"Install task finished with code: {result.Result}");
if (result.Result == 0) _formMain.Fail();
_synchronizationContext.Post(o => {
_formMain.btnCancel.ShowEnable("Exit");
}, result);
});
}
private bool LocateAsar() {
Append($"Searching for Discord core in: {_asarPath}");
if (!File.Exists($"{_asarPath}\\core.asar")) {
Append($"core.asar does not exist in: {_asarPath}!");
Append("Unable to continue installation.");
return false;
}
Append($"Located core.asar in: {_asarPath}");
return true;
}
public void HidePanel() {
}
public void SetForm(FormMain formMain) => _formMain = formMain;
public string Title => "Installing";
public UserControl Control => this;
private void Append(string text, bool detailed = false) {
_synchronizationContext.Post(o => {
if (!detailed) {
rtbStatus.AppendText((string) o);
rtbStatus.AppendText(Environment.NewLine);
}
rtbDetailed.AppendText((string)o);
rtbDetailed.AppendText(Environment.NewLine);
rtbStatus.ScrollToCaret();
rtbDetailed.ScrollToCaret();
}, text);
}
private void cbDetailed_CheckedChanged(object sender, EventArgs e) {
rtbDetailed.Visible = cbDetailed.Checked;
rtbStatus.Visible = !cbDetailed.Checked;
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,101 @@
namespace BetterDiscordWI.panels {
partial class LicensePanel {
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LicensePanel));
this.radioAccept = new System.Windows.Forms.RadioButton();
this.radioDecline = new System.Windows.Forms.RadioButton();
this.label1 = new System.Windows.Forms.Label();
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
this.SuspendLayout();
//
// radioAccept
//
this.radioAccept.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.radioAccept.AutoSize = true;
this.radioAccept.Location = new System.Drawing.Point(413, 286);
this.radioAccept.Name = "radioAccept";
this.radioAccept.Size = new System.Drawing.Size(59, 17);
this.radioAccept.TabIndex = 0;
this.radioAccept.Text = "Accept";
this.radioAccept.UseVisualStyleBackColor = true;
//
// radioDecline
//
this.radioDecline.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.radioDecline.AutoSize = true;
this.radioDecline.Checked = true;
this.radioDecline.Location = new System.Drawing.Point(478, 286);
this.radioDecline.Name = "radioDecline";
this.radioDecline.Size = new System.Drawing.Size(61, 17);
this.radioDecline.TabIndex = 1;
this.radioDecline.TabStop = true;
this.radioDecline.Text = "Decline";
this.radioDecline.UseVisualStyleBackColor = true;
//
// label1
//
this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.label1.Location = new System.Drawing.Point(3, 5);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(480, 13);
this.label1.TabIndex = 2;
this.label1.Text = "Please read the following License Agreement and accept the terms before continuin" +
"g the installation.";
//
// richTextBox1
//
this.richTextBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.richTextBox1.Location = new System.Drawing.Point(3, 21);
this.richTextBox1.Name = "richTextBox1";
this.richTextBox1.Size = new System.Drawing.Size(533, 259);
this.richTextBox1.TabIndex = 3;
this.richTextBox1.Text = resources.GetString("richTextBox1.Text");
//
// LicensePanel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.richTextBox1);
this.Controls.Add(this.label1);
this.Controls.Add(this.radioDecline);
this.Controls.Add(this.radioAccept);
this.Name = "LicensePanel";
this.Size = new System.Drawing.Size(542, 306);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.RadioButton radioAccept;
private System.Windows.Forms.RadioButton radioDecline;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.RichTextBox richTextBox1;
}
}

View File

@ -0,0 +1,40 @@
using System.Windows.Forms;
namespace BetterDiscordWI.panels {
public partial class LicensePanel : UserControl, IPanel {
private FormMain _formMain;
public string Title => "License Agreement";
public UserControl Control => this;
public LicensePanel() {
InitializeComponent();
radioAccept.CheckedChanged += (sender, args) => {
if (radioAccept.Checked) {
_formMain.btnBack.HideDisable();
_formMain.btnNext.ShowEnable();
_formMain.btnCancel.ShowEnable();
return;
}
_formMain.btnBack.HideDisable();
_formMain.btnNext.ShowDisable();
_formMain.btnCancel.ShowEnable();
};
}
public void SetForm(FormMain formMain) => _formMain = formMain;
public void ShowPanel() {
radioAccept.Checked = false;
radioDecline.Checked = true;
_formMain.btnBack.HideDisable();
_formMain.btnNext.ShowDisable();
_formMain.btnCancel.ShowEnable();
Show();
}
public void HidePanel() => Hide();
}
}

View File

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="richTextBox1.Text" xml:space="preserve">
<value>Copyright (c) 2015-Present Jiiks
https://jiiks.net
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</value>
</data>
</root>

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2015-present Jiiks | Jiiks.net
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -2,23 +2,47 @@
var agif = function () {};
agif.prototype.convert = function () {
$(".image canvas").each(function() {
var src = $(this).attr("src");
if(src != undefined) {
$(this).replaceWith('<img src="'+src+'"></img>');
// Autoplay GIFs
agif.prototype.convert = function (target) {
// Handle GIF
$(target).find(".image:has(canvas)").each(function () {
var image = $(this);
var canvas = image.children("canvas").first();
// Replace GIF preview with actual image
var src = canvas.attr("src");
if(src !== undefined) {
image.replaceWith($("<img>", {
src: canvas.attr("src"),
width: canvas.attr("width"),
height: canvas.attr("height"),
}).addClass("image kawaii-autogif"));
}
});
// Handle GIFV
$(target).find(".embed-thumbnail-gifv:has(video)").each(function () {
var embed = $(this);
var video = embed.children("video").first();
// Remove the class, embed-thumbnail-gifv, to avoid the "GIF" overlay
embed.removeClass("embed-thumbnail-gifv").addClass("kawaii-autogif");
// Prevent the default behavior of pausing the video
embed.parent().on("mouseout.autoGif", function (event) {
event.stopPropagation();
});
video[0].play();
});
};
agif.prototype.onMessage = function () {
this.convert();
};
agif.prototype.onSwitch = function () {
this.convert();
};
agif.prototype.onMessage = function () {};
agif.prototype.onSwitch = function () {};
agif.prototype.start = function () {
this.convert();
this.convert(document);
};
agif.prototype.observer = function (e) {
this.convert(e.target);
};
agif.prototype.load = function () {};
@ -35,8 +59,8 @@ agif.prototype.getDescription = function () {
return "Autoplay gifs without having to hover.";
};
agif.prototype.getVersion = function () {
return "0.1.0";
return "1.0.0";
};
agif.prototype.getAuthor = function () {
return "Jiiks";
};
return "noodlebox";
};

View File

@ -6,7 +6,7 @@ var clockPlugin = function () {};
clockPlugin.prototype.start = function () {
BdApi.clearCSS("clockPluginCss");
BdApi.injectCSS("clockPluginCss", '#clockPluginClock { position:absolute; color:#FFF; background:#333333; padding:0 12px 0 10px; min-width:70px; }');
BdApi.injectCSS("clockPluginCss", '#clockPluginClock { position:absolute; color:#FFF; background:#333333; padding:0 12px 0 13px; min-width:55px; max-width:55px; z-index:100; }');
var self = this;
this.clock = $("<div/>", { id: "clockPluginClock" });
$("body").append(this.clock);
@ -23,6 +23,28 @@ clockPlugin.prototype.start = function () {
var current_time = [h,m,s].join(':');
self.clock.html(current_time);
};
this.ticktock12 = function() {
var suffix = "AM";
var d = new Date();
var h = d.getHours();
var m = self.pad(d.getMinutes());
var s = self.pad(d.getSeconds());
if(h >= 12) {
h -= 12;
suffix = "PM";
}
if(h == 0) {
h = 12;
}
h = self.pad(h);
var current_time = [h,m,s].join(":") + suffix;
self.clock.html(current_time);
};
this.ticktock();
this.interval = setInterval(this.ticktock, 1000);
};

View File

@ -2,34 +2,33 @@
var dblClickEdit = function () {};
dblClickEdit.prototype.handler = function(e) {
const message = e.target.closest('[class^=messageCozy]') || e.target.closest('[class^=messageCompact]');
if (!message) return;
const btn = message.querySelector('[class^=buttonContainer] [class^=button-]');
if (!btn) return;
btn.click();
const popup = document.querySelector('[class^=container][role=menu]');
if (!popup) return;
const rii = popup[Object.keys(popup).find(k => k.startsWith('__reactInternal'))];
if (!rii || !rii.memoizedProps || !rii.memoizedProps.children || !rii.memoizedProps.children[1] || !rii.memoizedProps.children[1].props || !rii.memoizedProps.children[1].props.onClick) return;
rii.memoizedProps.children[1].props.onClick();
};
dblClickEdit.prototype.onMessage = function () {
};
dblClickEdit.prototype.onSwitch = function () {
};
dblClickEdit.prototype.start = function () {
$(document).on("dblclick.dce", function(e) {
var target = $(e.target);
if(target.parents(".message").length > 0) {
var msg = target.parents(".message").first();
var opt = msg.find(".btn-option");
opt.click();
var popout = $(".option-popout");
if(popout.children().length == 2) {
popout.children().first().click();
} else {
popout.hide();
}
}
});
document.addEventListener('dblclick', this.handler);
};
dblClickEdit.prototype.load = function () {};
dblClickEdit.prototype.unload = function () {
$(document).off("dblclick.dce");
document.removeEventListener('dblclick', this.handler);
};
dblClickEdit.prototype.stop = function () {
$(document).off("dblclick.dce");
document.removeEventListener('dblclick', this.handler);
};
dblClickEdit.prototype.getSettingsPanel = function () {
return "";
@ -42,8 +41,8 @@ dblClickEdit.prototype.getDescription = function () {
return "Double click messages to edit them";
};
dblClickEdit.prototype.getVersion = function () {
return "0.1.0";
return "0.2.1";
};
dblClickEdit.prototype.getAuthor = function () {
return "Jiiks";
};
};

View File

@ -9,9 +9,10 @@ emoteBlacklist.prototype.onSwitch = function () {
emoteBlacklist.prototype.start = function () {
window.ebEnabled = true;
var self = this;
var em = localStorage["emoteBlacklist"];
if(em == undefined) return;
JSON.parse(em).forEach(function(emote) {
var em = bdPluginStorage.get("emoteBlacklist", "blacklist");
if(em === null) return;
em.forEach(function(emote) {
self.remove(emote);
self.add(emote);
});
@ -35,21 +36,20 @@ emoteBlacklist.prototype.stop = function () {
};
emoteBlacklist.prototype.clear = function() {
var self = this;
var em = localStorage["emoteBlacklist"];
if(em == undefined) return;
var em = JSON.parse(em);
var em = bdPluginStorage.get("emoteBlacklist", "blacklist");
if(em === null) return;
em.forEach(function(emote) {
self.remove(emote);
});
};
emoteBlacklist.prototype.getSettingsPanel = function () {
var em = localStorage["emoteBlacklist"];
var em = bdPluginStorage.get("emoteBlacklist", "blacklist");
var html = '';
html += '<h2>Emote Blacklist</2>';
html += '<textarea id="emoteBlistTa" style="width:100%; min-height:200px;">';
if(em != undefined) {
JSON.parse(em).forEach(function(item) {
if(em !== null) {
em.forEach(function(item) {
html += item + "\n";
});
}
@ -64,7 +64,7 @@ emoteBlacklist.prototype.save = function() {
$("#emoteBlistTa").val().split("\n").forEach(function(item) {
blist.push(item);
});
localStorage["emoteBlacklist"] = JSON.stringify(blist);
bdPluginStorage.set("emoteBlacklist", "blacklist", blist);
if(window.ebEnabled) {
this.start();
}

Some files were not shown because too many files have changed in this diff Show More