Compare commits
603 Commits
Author | SHA1 | Date |
---|---|---|
Alexei Stukov | 4707671795 | |
Alexei Stukov | 222c2347fd | |
Alexei Stukov | 0d81028a3c | |
Alexei Stukov | 7b99b7d7f1 | |
Modder4869 | fa20c57f86 | |
Alexei Stukov | 884ea57c14 | |
Alexei Stukov | a6d81c2f25 | |
Alexei Stukov | e85e3a49d9 | |
Alexei Stukov | b62ab6259e | |
Alexei Stukov | 82232fa9c6 | |
Modder4869 | 57e16e3b43 | |
Modder4869 | 7f6cd474fd | |
Alexei Stukov | 718ab4fb7d | |
Modder4869 | c187ed3127 | |
Alexei Stukov | 4966be2020 | |
Samuel Elliott | 1d7627bce7 | |
Jiiks | e9e3627339 | |
Jiiks | 8688a9ea7d | |
Jiiks | 2a29984950 | |
Jiiks | cf1a9ecb91 | |
Jiiks | 4114a6ee26 | |
Alexei Stukov | 55a6fb8697 | |
Alexei Stukov | 5344fd2b1e | |
Zack Rauen | 7322ea8ba9 | |
pohky | 4a377d9648 | |
Jiiks | 1a6648ebf0 | |
Jiiks | 9ab77a8217 | |
pohky | 1d07436569 | |
pohky | f91dff5c1b | |
David | a160359413 | |
pohky | ebe69a5369 | |
DeathStrikeV | 0831320b61 | |
David | 4df677c28d | |
David | aee8aa7483 | |
Alexei Stukov | 1cc631b29d | |
Alexei Stukov | 626d41480c | |
pohky | caaa0aba8b | |
pohky | daec28f2b0 | |
pohky | 6d1baa0639 | |
DeathStrikeV | 31e94d72f7 | |
David | 055b3b9a25 | |
DeathStrikeV | c0fd7e41cc | |
David | 187b39dac1 | |
DeathStrikeV | 10f686a71f | |
DeathStrikeV | eabad3bced | |
David | 6daeeaf866 | |
David | 255caea48e | |
pohky | a46fb246ed | |
David | 054efe9e75 | |
DeathStrikeV | 07f5c3b6d5 | |
David | 895f987ca9 | |
David | cefa91aa13 | |
DeathStrikeV | 0271df21c9 | |
David | a6b89cf205 | |
David | a74e425a8e | |
David | 191bfaca02 | |
David | de1a63f7bd | |
David | 39e7982c64 | |
David | ccbebd6855 | |
David | 192184e4d1 | |
DeathStrikeV | 94622aa854 | |
David | 051edcf619 | |
David | 3c1c8f27a4 | |
David | 11ca29c2fb | |
David | 4eb5c183a5 | |
David | bf041b54ef | |
DeathStrikeV | 3c53865150 | |
David | db66110556 | |
DeathStrikeV | d1371a5383 | |
David | c5e0886690 | |
DeathStrikeV | 6d77162321 | |
David | 5ebeb06520 | |
David | 35dadec203 | |
Alexei Stukov | 9f1314e75c | |
David | a21cb93d3b | |
DeathStrikeV | 6cf7f8583d | |
DeathStrikeV | 3787744a71 | |
David | 358c8e288d | |
DeathStrikeV | e5a8224c49 | |
DeathStrikeV | d34db2cbc2 | |
David | c5abd4703a | |
David | b63b4a31f3 | |
DeathStrikeV | 8f0c9b5158 | |
DeathStrikeV | 715480c429 | |
BlazingSky | 12444400a0 | |
BlazingSky | 9d7e1bae32 | |
DeathStrikeV | 3fb10a820a | |
Alexei Stukov | 565ff12946 | |
Alexei Stukov | da082999cb | |
Alexei Stukov | 4fc5abe092 | |
Alexei Stukov | ecc8b3baa1 | |
Alexei Stukov | 319fd6b12b | |
David | cf6a9ca3b7 | |
Alexei Stukov | df8b319275 | |
David | 19b37a9feb | |
David | 633e2fb986 | |
David | b24b1b7cda | |
David | ab58d87acd | |
Alexei Stukov | db7f9911c9 | |
DeathStrikeV | 21cc2c8beb | |
DeathStrikeV | b805ec8b2c | |
DeathStrikeV | c8f21ae02e | |
David | 154d916a9e | |
DeathStrikeV | e4681e2a23 | |
David | e5aeea60e9 | |
David | 37c3f12178 | |
David | 72e9d2f455 | |
David | e3c8befb25 | |
DeathStrikeV | 8e9b59521a | |
DeathStrikeV | 1c882bc52d | |
David | a33a2b205d | |
David | 0c014877ea | |
pohky | d5522e547c | |
DeathStrikeV | 1e997efa28 | |
David | 01eb06ab23 | |
David | 42ee775176 | |
David | 187966d4b0 | |
DeathStrikeV | 50edc74c55 | |
BlazingSky | 29d8bba9a9 | |
David | 2382b1e130 | |
David | e67e4ee7b9 | |
David | 1bf65e5706 | |
Alexei Stukov | 4dfc413227 | |
Alexei Stukov | 7a9ac5b035 | |
pohky | 678a756dd6 | |
Alexei Stukov | 1e8f45e825 | |
Alexei Stukov | 85f79d5259 | |
Alexei Stukov | 5f83b20f6b | |
Alexei Stukov | c9b6a11941 | |
Zerthox | 4a33c39e8b | |
Alexei Stukov | 05d379ba79 | |
DeathStrikeV | 8aa4a7c700 | |
BlazingSky | 04c0df30e7 | |
Alexei Stukov | 0ea7990226 | |
Alexei Stukov | a96a0384b2 | |
Alexei Stukov | bf6f826c9d | |
Alexei Stukov | 81bd8938fe | |
Alexei Stukov | 0255164f42 | |
Alexei Stukov | 4a7422039e | |
Alexei Stukov | 8dfd0f2a73 | |
Alexei Stukov | 5abe7c4a9e | |
Alexei Stukov | 1c75af3513 | |
Alexei Stukov | 214c77be13 | |
Alexei Stukov | 7c62116554 | |
Alexei Stukov | 4cb39d90c0 | |
Alexei Stukov | db34f5c6b0 | |
Alexei Stukov | 8bfd9cdaa5 | |
Alexei Stukov | e7aeb7d1af | |
Alexei Stukov | 327c08fd93 | |
Alexei Stukov | b933703f4f | |
pohky | a5089721db | |
DeathStrikeV | 5a51afd01e | |
Alexei Stukov | fc7a85a79c | |
Alexei Stukov | 707afde649 | |
Alexei Stukov | a85d8e19d9 | |
David | 1a367d83ba | |
Alexei Stukov | 05d55ea6fa | |
Alexei Stukov | 9859064dc6 | |
Alexei Stukov | 2d4416466c | |
Alexei Stukov | 6372743f9f | |
Alexei Stukov | 060c2ab0ec | |
Alexei Stukov | 91dd2e6ee7 | |
Alexei Stukov | eff75f27dc | |
Alexei Stukov | 8650b376ef | |
Alexei Stukov | f58ccdad4a | |
Alexei Stukov | 6e020a0298 | |
Alexei Stukov | bdb22e9fb6 | |
Alexei Stukov | f6cae7c238 | |
Alexei Stukov | ad86bbb8c8 | |
Alexei Stukov | 5bf01fa3c8 | |
Alexei Stukov | 2fbf1e9985 | |
Alexei Stukov | 2fbe862933 | |
Alexei Stukov | 2d554d0086 | |
Alexei Stukov | 3262eb58a9 | |
Alexei Stukov | b15f56212d | |
Alexei Stukov | 6d23660361 | |
Alexei Stukov | fbb0283148 | |
Alexei Stukov | 93ecab675d | |
Alexei Stukov | 8820d0e674 | |
Alexei Stukov | df7f12d5bd | |
DeathStrikeV | f01ea2473c | |
pohky | 32b6e6dc48 | |
DeathStrikeV | d71acb07fd | |
pohky | b92989ac14 | |
DeathStrikeV | d517bae2d3 | |
pohky | 889a415314 | |
David | 77d72d6284 | |
DeathStrikeV | 206685c29d | |
DeathStrikeV | 3b1c5ee3a8 | |
pohky | a17497d9a4 | |
DeathStrikeV | cc64dfa958 | |
DeathStrikeV | f7ab2a5b59 | |
pohky | 8230b05046 | |
DeathStrikeV | 29c91bdfdf | |
pohky | bd34bd6157 | |
Violetnred2 | 70ef5cd327 | |
DeathStrikeV | c3450d50c4 | |
DeathStrikeV | e4796621b7 | |
pohky | aefd07995d | |
DeathStrikeV | b7f46fd7f4 | |
DeathStrikeV | 36d68836d4 | |
Alexei Stukov | 897be73f09 | |
DeathStrikeV | 3e89697b4f | |
DeathStrikeV | b78666140a | |
DeathStrikeV | 52e8bc512d | |
DeathStrikeV | bb50c6f48e | |
Alexei Stukov | b02340a130 | |
Alexei Stukov | 319e6db4fc | |
Violetnred2 | 5c52b3b987 | |
Alexei Stukov | 72c2585e6a | |
Alexei Stukov | a64dfa8bf0 | |
Alexei Stukov | f35e867358 | |
David | b200229b26 | |
Alexei Stukov | 770eae466e | |
David | 6a86149b63 | |
DeathStrikeV | b6833d2962 | |
DeathStrikeV | a976753b93 | |
Zerthox | e0885c6d6a | |
DeathStrikeV | 717586cee1 | |
Jiiks | 23724784e2 | |
DeathStrikeV | e26b1db0c4 | |
DeathStrikeV | c687da23fe | |
DeathStrikeV | e509f16648 | |
DeathStrikeV | 1919061656 | |
Jiiks | 90fd6199a1 | |
jjtcm | d6aabd89ae | |
DeathStrikeV | 406ced863f | |
DeathStrikeV | 1d9e4753be | |
DeathStrikeV | aad61c5281 | |
DeathStrikeV | 3543b57f53 | |
Jiiks | fb927b093a | |
Jiiks | 01cfee0ebd | |
DeathStrikeV | c811e2a064 | |
DeathStrikeV | 92e992abd2 | |
Jiiks | d8feba59ea | |
Jiiks | 11190a8a4c | |
Jiiks | 143602a729 | |
Jiiks | 713e9e93d3 | |
Jiiks | beb013122f | |
Jiiks | f7fa19dcf8 | |
Jiiks | 44073ed15d | |
Jiiks | 031c64271a | |
Jiiks | 79d9c6f00c | |
Jiiks | 391b6a2085 | |
Jiiks | 0c22d475c3 | |
Jiiks | e8e52cf7c6 | |
Jiiks | b6e2ca2670 | |
NooB-AssassinZ3 | e06509ca0a | |
NooB-AssassinZ3 | cc4df4ada4 | |
Jiiks | de617fed27 | |
DeathStrikeV | 59c931191b | |
Zerthox | ca3859d343 | |
brodycas3 | 30df5f6158 | |
DeathStrikeV | f15b0dee3d | |
Nick Sarnie | ddda646afc | |
Nick Sarnie | be22c14356 | |
MKody | f08539d5f9 | |
MKody | ef10e075f6 | |
MKody | c6f85e545f | |
MKody | 0f2812bc10 | |
Jiiks | 513fb57621 | |
Jiiks | 0878f4ab00 | |
DeathStrikeV | dc18638567 | |
noodlebox | e793920ed9 | |
noodlebox | b6bdaedb6d | |
noodlebox | 3431d30ac2 | |
DeathStrikeV | c74e9c1030 | |
Jiiks | 5daf0bbdc5 | |
Jiiks | 604ec38101 | |
Jiiks | fcfd75346b | |
DeathStrikeV | 6768b064f7 | |
Ehsan Kia | 71124e0129 | |
noodlebox | 43aae6ac72 | |
noodlebox | 5a4e121e2b | |
SapiensAnatis | 810b0fcee2 | |
DeathStrikeV | 5120488766 | |
DeathStrikeV | 8e9ebaa853 | |
Jiiks | d862285c63 | |
Jiiks | 52c4114148 | |
Jiiks | 19feb05e9b | |
Jiiks | 47a36a2e56 | |
Jiiks | e1fd1f0df7 | |
Jiiks | 46fe0f7c37 | |
Jiiks | 00dfb68677 | |
Jiiks | 0a55c0edae | |
Jiiks | 33162a1798 | |
DeathStrikeV | a6f53183c1 | |
Jiiks | b0b24974e6 | |
Jiiks | 7ff3971168 | |
Jiiks | ba56f3bf6e | |
Jiiks | b7851955b2 | |
Jiiks | 5784e45e87 | |
Jiiks | 186d6c9bc5 | |
Jiiks | 6e1816d973 | |
DeathStrikeV | 5e23ad66af | |
DeathStrikeV | 788d20e452 | |
DeathStrikeV | 032b69d564 | |
DeathStrikeV | 01a55116b0 | |
DeathStrikeV | 31603634ce | |
Jiiks | 9c99e8a27d | |
DeathStrikeV | f2d4680698 | |
Jacob Foster | 028b96589e | |
Zerthox | b4bc6ff109 | |
DeathStrikeV | e21c1dc28a | |
DeathStrikeV | bebf352bd0 | |
Jiiks | 8369decbfc | |
DeathStrikeV | 1111b98767 | |
DeathStrikeV | ffb456c466 | |
DeathStrikeV | 68247caf66 | |
Zerthox | c65b760ca1 | |
DeathStrikeV | 8e4b5f6ee0 | |
DeathStrikeV | 6e08a4b1ed | |
DeathStrikeV | 0b26620901 | |
DeathStrikeV | d4c8f04331 | |
DeathStrikeV | 67f0257cb4 | |
pohky | a2de68ec1f | |
DeathStrikeV | 93115073e9 | |
DeathStrikeV | 19f5f9f7a5 | |
Jiiks | 131eab393d | |
Jiiks | 8f7cc5e06f | |
Jiiks | b46e797728 | |
DeathStrikeV | 42898de340 | |
Zerthox | 65fda6f4e7 | |
Zerthox | e15af62927 | |
DeathStrikeV | d2a7c6734a | |
Zerthox | 1b9eb941d2 | |
Zerthox | 59263be1b5 | |
DeathStrikeV | df2b647750 | |
DeathStrikeV | 4e0a23ec03 | |
DeathStrikeV | beae2087a8 | |
Jiiks | 2039252e69 | |
Elviss Strazdins | 1219eb76bc | |
DeathStrikeV | 31a1fcfc46 | |
DeathStrikeV | 37731b9fa7 | |
DeathStrikeV | 2d8120fc1e | |
DeathStrikeV | bd0e1b135e | |
Jiiks | 9a2b4fb8b2 | |
Jiiks | e7b9be97b0 | |
Jiiks | 5cea881ed9 | |
DeathStrikeV | e40b9fe82c | |
Jiiks | c14c4255eb | |
Jiiks | fec2679fc8 | |
Jiiks | 520ca3faea | |
Jiiks | c8e906b00d | |
Jiiks | 9bddcaa181 | |
Jiiks | aa4877d851 | |
Jiiks | a9a2d09ae0 | |
Jiiks | 422c18917c | |
Jiiks | ccdc5f1a9f | |
Jiiks | 080141e7d0 | |
Jiiks | b55bd54b29 | |
Jiiks | 8c0951a0ea | |
DeathStrikeV | bb5744dfe9 | |
DeathStrikeV | 5bf2597030 | |
DeathStrikeV | ade5cbc446 | |
DeathStrikeV | 35ca5f6339 | |
DeathStrikeV | 97c259f1c4 | |
DeathStrikeV | 8eedc29d71 | |
DeathStrikeV | 3975eabca0 | |
DeathStrikeV | 1b99b6289a | |
DeathStrikeV | 0b9fb52800 | |
DeathStrikeV | f1a0f11257 | |
DeathStrikeV | dea323a0b8 | |
Zerthox | c0bd71fe7d | |
DeathStrikeV | 85093234fa | |
DeathStrikeV | 13e21fb052 | |
DeathStrikeV | e592126078 | |
DeathStrikeV | 35de874ced | |
DeathStrikeV | cdc95aef68 | |
DeathStrikeV | 08cc4c5bc3 | |
DeathStrikeV | 5c514efa96 | |
DeathStrikeV | a9bc977764 | |
DeathStrikeV | 2fa3e7a4b5 | |
DeathStrikeV | 9b4f5f4366 | |
DeathStrikeV | 2b55554af1 | |
DeathStrikeV | 5aff38bf39 | |
Jiiks | 53d4989a79 | |
Jiiks | d23d331463 | |
DeathStrikeV | 020b1b8d4e | |
DeathStrikeV | e251a03914 | |
DeathStrikeV | 1faac18e8d | |
DeathStrikeV | a23878fd0b | |
Zerthox | 56773ae55f | |
Jiiks | dd28c89236 | |
DeathStrikeV | 14331ddee5 | |
DeathStrikeV | b1a06a519f | |
TakosThings | cc1938b14b | |
Jiiks | c4e0cc15c9 | |
Jiiks | 6651b5ac3f | |
DeathStrikeV | faa7b30df5 | |
DeathStrikeV | 9a638e7eb3 | |
DeathStrikeV | 06770ca1af | |
DeathStrikeV | 337a79efbb | |
Jiiks | fd3dab39de | |
Zerthox | 84092e1c6f | |
Jiiks | 77addb5b03 | |
DeathStrikeV | 68e56d9ea8 | |
Jiiks | 71b0077fc0 | |
DeathStrikeV | 2e64e4c47b | |
Léo | c4f4ac41e8 | |
Jiiks | 07f38008d8 | |
Ehsan Kia | 5c70075ca0 | |
Jiiks | e09fb169ae | |
Ehsan Kia | dc48d88d59 | |
Ehsan Kia | 227547d7e7 | |
DeathStrikeV | 00da2ef58c | |
DeathStrikeV | 195e8a9b77 | |
DeathStrikeV | 7cb778f884 | |
DeathStrikeV | 289abee257 | |
DeathStrikeV | 2c49e52f90 | |
DeathStrikeV | 07968430e3 | |
Alex | e10b78dc9b | |
Jiiks | a1f9f29198 | |
Jiiks | 0b614022ad | |
Jiiks | 821a9f8749 | |
Jiiks | 1bb83de279 | |
Jiiks | 48e55c9417 | |
Jiiks | 5dc6327fda | |
DeathStrikeV | e1470dab3e | |
DeathStrikeV | ab0e948fe4 | |
Jiiks | d5f16c0b2d | |
Alex | 66c24f246a | |
DeathStrikeV | 27b1978515 | |
Jiiks | 8df7431743 | |
Jiiks | c3443b5725 | |
DeathStrikeV | 5e466e79fd | |
Jiiks | 4f549676bc | |
Jiiks | cfd651eaab | |
Jiiks | 6d58d8f2f8 | |
Jiiks | 1a7d84a14c | |
Jiiks | 376471cb2d | |
Jiiks | 3eea2eacc3 | |
Jiiks | 9416be4105 | |
Jiiks | e7b56fe792 | |
Jiiks | 7f5986aa01 | |
Jiiks | fc53df5e4b | |
Jiiks | c5454a8f57 | |
DeathStrikeV | 3d381b7ca1 | |
DeathStrikeV | 469cb2a2da | |
DeathStrikeV | 8b57885002 | |
DeathStrikeV | 3429d6c8ca | |
Jiiks | 28ad0c0acc | |
Jiiks | 70c6eaca03 | |
DeathStrikeV | a80d16fbd8 | |
Ehsan Kia | 4fa0825bc7 | |
Ehsan Kia | 2db776f93a | |
DeathStrikeV | e330ff197d | |
DeathStrikeV | b002ae6130 | |
DeathStrikeV | 5c27d91fde | |
DeathStrikeV | 5f94a8b155 | |
DeathStrikeV | f18f353501 | |
DeathStrikeV | 0e2bf5b1c4 | |
DeathStrikeV | ea34f260df | |
DeathStrikeV | 56f590dbf4 | |
DeathStrikeV | 54709b608a | |
DeathStrikeV | aaea907eac | |
DeathStrikeV | ebb99040e4 | |
DeathStrikeV | d874f6becc | |
DeathStrikeV | f3d8865df5 | |
DeathStrikeV | 9098bca396 | |
DeathStrikeV | e7bda2e6c1 | |
Alex | a8534308b7 | |
Jiiks | 24eb3f3d9d | |
Ehsan Kia | ad2f98107a | |
noodlebox | b9b28c0bd9 | |
pohky | 2b361cbcc3 | |
Ehsan Kia | 39505125fd | |
Jiiks | 48d4a58102 | |
pohky | c51bb8cc43 | |
Ehsan Kia | 51ae2698c4 | |
pohky | 501f38357f | |
Jiiks | 2fc35436a4 | |
Jiiks | b87e0781f6 | |
Jiiks | fe1a30027a | |
pohky | eb58553ade | |
Jiiks | b28ef7abc5 | |
Jiiks | 8625b1bdbf | |
Yozora | 9ae3b5ba69 | |
pohky | 42971a5714 | |
pohky | 7bd1a219cd | |
CZauX | 336152802a | |
Yozora | d067bc2cfc | |
pohky | f751f540ec | |
pohky | bd576ef69c | |
pohky | d186bc9218 | |
pohky | ef8ca8fd15 | |
Jiiks | 9e4f6ccf25 | |
pohky | d377cef33c | |
pohky | 99afa4ccc7 | |
Ehsan Kia | 320a68f8cb | |
pohky | b09590e8e7 | |
Ehsan Kia | 4b63daaf48 | |
Jiiks | d26247bbd6 | |
pohky | 0ab1fe3f19 | |
pohky | 00ff05bfe0 | |
pohky | 2bd94b9ae4 | |
Ehsan Kia | 6d1b7667b8 | |
Jiiks | 51cf6e531c | |
Jiiks | e5d91a8564 | |
pohky | 91fcf59656 | |
pohky | 20337f3f36 | |
pohky | 7eac80b59f | |
pohky | 8c2e38662c | |
pohky | 31617f79b3 | |
pohky | 08ec6a4ddb | |
Ehsan Kia | 1a394c75c9 | |
pohky | b604daf201 | |
pohky | 2eb0f8d9c7 | |
pohky | 839c06d968 | |
Jiiks | 2b32ffac01 | |
pohky | 456852070e | |
Ehsan Kia | f2d76b2e99 | |
pohky | 4d63434d51 | |
pohky | d2a6b384d3 | |
Ehsan Kia | ba4402a4d4 | |
pohky | d36caf0599 | |
pohky | 40dbd67e80 | |
pohky | 19393f4480 | |
pohky | 9bf4b9dcb6 | |
pohky | c07f7ac73f | |
pohky | 3ba91bfbf3 | |
pohky | 1a48e6045f | |
Jiiks | 3c62a57b96 | |
Jiiks | 1a560a1656 | |
Jiiks | d2c5a95f13 | |
Jiiks | d81b806d6b | |
Jiiks | 9a97a5cc2e | |
pohky | 6998c5c131 | |
pohky | 01070c916c | |
Ehsan Kia | 136266be85 | |
Jiiks | 284838bb5c | |
Jiiks | 4fa8d75653 | |
Jiiks | ef3d2ad9b1 | |
pohky | 995868b5b9 | |
pohky | d8457795e4 | |
pohky | 8de42e7931 | |
Ehsan Kia | d8db32f389 | |
pohky | 22513f3d27 | |
pohky | 3470dc2594 | |
Ehsan Kia | f978d4b2d9 | |
pohky | 1a40b63d04 | |
Ehsan Kia | 4e20898cae | |
Jiiks | 849c139124 | |
Jiiks | c1af5fd726 | |
Jiiks | 1e79726b73 | |
pohky | 1dfd428995 | |
Jiiks | cfe00cd50d | |
Jiiks | 36d832d3e2 | |
pohky | 46f983f132 | |
pohky | f535aa5761 | |
pohky | ab07e14d7f | |
pohky | bdbc2c0110 | |
pohky | 00e64da94a | |
pohky | 0370e80071 | |
pohky | b25201b576 | |
Ehsan Kia | e6955f919d | |
Jiiks | 8205109f29 | |
Jiiks | b277ab2c7f | |
Jiiks | b68a850750 | |
pohky | b55607f1b2 | |
pohky | 3451215be9 | |
Jiiks | f649c729b2 | |
pohky | 8a786de8cc | |
pohky | e8e82cb02b | |
Jiiks | 329d8bc55e | |
pohky | 1137428be4 | |
pohky | d09d870d9e | |
Jiiks | ab7ccf061d | |
pohky | b343b5d7c9 | |
Jiiks | 13c1ab4be0 | |
Jiiks | 512ccd1904 | |
Jiiks | c4a1b2bc20 | |
Jiiks | 457f314ac3 | |
pohky | dde563e0eb | |
Jiiks | b742f86ee0 | |
Jiiks | 596b0e8490 | |
pohky | e9461a9830 | |
Jiiks | 178f2b464c | |
pohky | 220e75e29b | |
Ehsan Kia | c7fa09505d | |
pohky | d6c55d7e1b | |
pohky | 276b39e169 | |
pohky | 9c6b3629d3 | |
pohky | 5a636f6e9a | |
Jiiks | db31c2662a | |
pohky | 66d7636228 | |
Jiiks | ae9dcd6220 | |
Jiiks | f4461ed97f | |
pohky | 201d1fb22b | |
pohky | cb7176be5d | |
pohky | c3dff1ca6e | |
pohky | 6be4da2197 | |
pohky | 5add6c9a21 | |
pohky | 2f4716714d | |
Ehsan Kia | 5c3f653718 | |
pohky | 6b8f324199 | |
Jiiks | 199aa4fa45 | |
Jiiks | 2845884954 | |
Jiiks | 25e2d278a8 | |
pohky | c86be946ee | |
Jiiks | bdf889e14f | |
Jiiks | c61af06452 | |
Jiiks | 6d16dea9ac |
|
@ -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.
|
|
@ -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
|
||||
|
|
|
@ -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.
|
|
@ -0,0 +1,3 @@
|
|||
dist/
|
||||
pack.bat
|
||||
run.bat
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
|
@ -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>
|
|
@ -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>
|
|
@ -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);
|
||||
}
|
|
@ -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" }');
|
||||
});
|
|
@ -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>
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"windows": {
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"osx": {
|
||||
"version": "0.1.1"
|
||||
}
|
||||
}
|
|
@ -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();
|
|
@ -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;
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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;
|
|
@ -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();
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 170 KiB |
|
@ -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" />
|
|
@ -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")]
|
After Width: | Height: | Size: 170 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 4.4 MiB After Width: | Height: | Size: 4.4 MiB |
|
@ -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++;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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>
|
|
@ -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>
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Weavers>
|
||||
<Costura />
|
||||
</Weavers>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
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
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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")]
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 43 KiB |
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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>
|
After Width: | Height: | Size: 24 KiB |
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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.
|
|
@ -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";
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|