diff --git a/build.xml b/build.xml index 3834457b..3ce19d23 100644 --- a/build.xml +++ b/build.xml @@ -48,13 +48,6 @@ - - - - - - - @@ -108,4 +101,4 @@ - \ No newline at end of file + diff --git a/docs/assistant.png b/docs/assistant.png deleted file mode 100644 index 53c97aa3..00000000 Binary files a/docs/assistant.png and /dev/null differ diff --git a/docs/assistant.yaml b/docs/assistant.yaml deleted file mode 100644 index 6b7028ec..00000000 --- a/docs/assistant.yaml +++ /dev/null @@ -1,2 +0,0 @@ -# uncomment the next line to use a custom token server -# tokenServerUrl: "https://example.org/token/" \ No newline at end of file diff --git a/docs/assistant_capture_settings.jpg b/docs/assistant_capture_settings.jpg deleted file mode 100644 index 34fdf126..00000000 Binary files a/docs/assistant_capture_settings.jpg and /dev/null differ diff --git a/docs/assistant_clipboard.jpg b/docs/assistant_clipboard.jpg deleted file mode 100644 index e5633f71..00000000 Binary files a/docs/assistant_clipboard.jpg and /dev/null differ diff --git a/docs/assistant_compression_settings.jpg b/docs/assistant_compression_settings.jpg deleted file mode 100644 index 4a9c9897..00000000 Binary files a/docs/assistant_compression_settings.jpg and /dev/null differ diff --git a/docs/assistant_connected.jpg b/docs/assistant_connected.jpg deleted file mode 100644 index e78eb7ad..00000000 Binary files a/docs/assistant_connected.jpg and /dev/null differ diff --git a/docs/assistant_control.jpg b/docs/assistant_control.jpg deleted file mode 100644 index b4ed43d8..00000000 Binary files a/docs/assistant_control.jpg and /dev/null differ diff --git a/docs/assistant_copy_token.jpg b/docs/assistant_copy_token.jpg deleted file mode 100644 index 2408b9d4..00000000 Binary files a/docs/assistant_copy_token.jpg and /dev/null differ diff --git a/docs/assistant_create_token.jpg b/docs/assistant_create_token.jpg deleted file mode 100644 index 6eaa87dd..00000000 Binary files a/docs/assistant_create_token.jpg and /dev/null differ diff --git a/docs/assistant_fit_screen.jpg b/docs/assistant_fit_screen.jpg deleted file mode 100644 index 50d81f6a..00000000 Binary files a/docs/assistant_fit_screen.jpg and /dev/null differ diff --git a/docs/assistant_incoming_connection.jpg b/docs/assistant_incoming_connection.jpg deleted file mode 100644 index 1b692ad5..00000000 Binary files a/docs/assistant_incoming_connection.jpg and /dev/null differ diff --git a/docs/assistant_network_addresses.jpg b/docs/assistant_network_addresses.jpg deleted file mode 100644 index 3796faf5..00000000 Binary files a/docs/assistant_network_addresses.jpg and /dev/null differ diff --git a/docs/assistant_network_addresses_ex.jpg b/docs/assistant_network_addresses_ex.jpg deleted file mode 100644 index d27587d4..00000000 Binary files a/docs/assistant_network_addresses_ex.jpg and /dev/null differ diff --git a/docs/assistant_network_settings_noupnp.jpg b/docs/assistant_network_settings_noupnp.jpg deleted file mode 100644 index 86b1cb3c..00000000 Binary files a/docs/assistant_network_settings_noupnp.jpg and /dev/null differ diff --git a/docs/assistant_network_settings_token_server.jpg b/docs/assistant_network_settings_token_server.jpg deleted file mode 100644 index 357d7702..00000000 Binary files a/docs/assistant_network_settings_token_server.jpg and /dev/null differ diff --git a/docs/assistant_network_settings_upnp.jpg b/docs/assistant_network_settings_upnp.jpg deleted file mode 100644 index 6388d95a..00000000 Binary files a/docs/assistant_network_settings_upnp.jpg and /dev/null differ diff --git a/docs/assistant_start.jpg b/docs/assistant_start.jpg deleted file mode 100644 index cdc18b9c..00000000 Binary files a/docs/assistant_start.jpg and /dev/null differ diff --git a/docs/assistant_take_screenshot.jpg b/docs/assistant_take_screenshot.jpg deleted file mode 100644 index 7ab0f64e..00000000 Binary files a/docs/assistant_take_screenshot.jpg and /dev/null differ diff --git a/docs/assistant_token_server.jpg b/docs/assistant_token_server.jpg deleted file mode 100644 index c28519bc..00000000 Binary files a/docs/assistant_token_server.jpg and /dev/null differ diff --git a/docs/assistant_windows_key.jpg b/docs/assistant_windows_key.jpg deleted file mode 100644 index 71a7dcad..00000000 Binary files a/docs/assistant_windows_key.jpg and /dev/null differ diff --git a/docs/assisted.png b/docs/assisted.png deleted file mode 100644 index 28e28eac..00000000 Binary files a/docs/assisted.png and /dev/null differ diff --git a/docs/assisted.yaml b/docs/assisted.yaml deleted file mode 100644 index 746c1a0b..00000000 --- a/docs/assisted.yaml +++ /dev/null @@ -1,6 +0,0 @@ -host: "localhost" -port: 8080 -# uncomment the next line to prevent auto connection at startup -# autoConnect: false -# uncomment the next line to use a custom token server -# tokenServerUrl: "https://example.org/token/" \ No newline at end of file diff --git a/docs/assisted_network.jpg b/docs/assisted_network.jpg deleted file mode 100644 index 043e1226..00000000 Binary files a/docs/assisted_network.jpg and /dev/null differ diff --git a/docs/assisted_ready.jpg b/docs/assisted_ready.jpg deleted file mode 100644 index 1be65b60..00000000 Binary files a/docs/assisted_ready.jpg and /dev/null differ diff --git a/docs/assisted_share_screens.jpg b/docs/assisted_share_screens.jpg deleted file mode 100644 index 0bd11261..00000000 Binary files a/docs/assisted_share_screens.jpg and /dev/null differ diff --git a/docs/assisted_token.jpg b/docs/assisted_token.jpg deleted file mode 100644 index 0c26cb77..00000000 Binary files a/docs/assisted_token.jpg and /dev/null differ diff --git a/docs/assisted_token_server.jpg b/docs/assisted_token_server.jpg deleted file mode 100644 index 667dbd2d..00000000 Binary files a/docs/assisted_token_server.jpg and /dev/null differ diff --git a/docs/assisted_uac.jpg b/docs/assisted_uac.jpg deleted file mode 100644 index e465dce4..00000000 Binary files a/docs/assisted_uac.jpg and /dev/null differ diff --git a/docs/bullet.gif b/docs/bullet.gif deleted file mode 100644 index f3f133bb..00000000 Binary files a/docs/bullet.gif and /dev/null differ diff --git a/docs/check.png b/docs/check.png deleted file mode 100644 index cf6299bb..00000000 Binary files a/docs/check.png and /dev/null differ diff --git a/docs/dayon.banner.png b/docs/dayon.banner.png deleted file mode 100644 index 6986b5e3..00000000 Binary files a/docs/dayon.banner.png and /dev/null differ diff --git a/docs/dayon.connection.diagram.drawio b/docs/dayon.connection.diagram.drawio deleted file mode 100644 index 15ac9407..00000000 --- a/docs/dayon.connection.diagram.drawio +++ /dev/null @@ -1,2 +0,0 @@ - -7T1Zd6LK1r8mj30WAmp8VDGGfBbGaGLry10GOAgO5AqG4dd/e9eAoqaT7k5ium/1WumSoqhxzwNcaO1V2t3MnuYkdNzlhao46YVmXKhqRdd0KLAmYzV1UeFtfIc32lUM/dzllQqv3fqOG5UaxmG4jP2ncqUdrteuHZfqZptNmJSb/Rsuy6M+zTz3qGJoz5bHtWPfiees9lKt7+qvXd+bi5ErtQa78zizF94m3K75eBeq9i/9x26vZqIvvtBoPnPCZG9QrXOhtTdhGLNfq7TtLnFvxbax565euFvMe+Ou47c8cPnt2/X8cTidxKbmON7N2qhXvml8cs+z5dYV66CzjTOxQ64DG8Yv1+EaihZdtosdK3AVbuJ56IXr2bIXhk9QWYHKwI3jjB/3bBuHUDWPV0t+Nwq3G9u9dTf+yo3dzfBpZvtrD25W4aa7dpp4srvxoObKXy75ePFs47nxCw8fbwvfKTYkq3r8zzR98Gvf1nk8fu4vrElj6n3TLzn40e5/0FBj7XBfDo8T0MQNYVabDBps3OUs9p/LgDbj8OoV7YpHb0Mf5qwqHLf0Kj8cjll6rVbugm8ie2r/5A86qjW0UkfV+uU/2qVeq1TZ/3q5W769h93Cj73V7aoomJ0GuR/t3o8gDlDlCX/6K4q8rWd3E/uAsr3Zo7u8DSM/9sM13H8M4zhc7TVoLn0Pb8QIhi36eDN6YmQDIWcmLv71UwTfFh/BcGbx7EJrskv1Knr2LtRWCuCqtm+vLXWatfTHcbq1c8WfXd8pthE+9zRHc7KqRrLqs72yn0nQTEi7kTsr2zevp0t7bT09qnrDDDp4/TT97rQfNQ+umx5pN5U+/TO96bg6n6zSZW98M5+o8dpeNSqPq0HDXFWXTtZMTKPpWYaHf/6tPwncbqdutpueaaTJ5PtdaHanT4/dpGH6pGIZ0ytLgfG68PxCUax2kpOOpzwEnXSSN2Pi61nP6Gz7bUXpGYPY6no5WZGsF5gRaScKu4fl3ZjkrZrpA060bnxLn4wiD0e9vW7Nna7nTVfL6NFQfDOfKIPgoWv5sBK4Ho0GSc8wtaExD3qj5tbyk6Q36sSkrSu0fJikZEyS4l4wiMkwSXujq5DkNwG0U3tGM4I6vIdl6gSdyiAfpNCv2gsmkWXQZzMrSxSYdWZpod/L9ZWpzef9rInzvLS7V8qs3VrNxml0OzQDK/eqxFgapt9a3A5vLOgD+rky+13Cd6UZW20l7QUelorjK9rMGCRO4BiWAfPIF1viw3i0Lc4F1zlIXd98PjiV9d6J5FY+0KzOpHxybT7H1UPgtFs6zA/WYnruSIEnBgAtztP0+i6E+pTAvs66D09Tda5gu+MT4aNm07GlmNcIXwvoYQElUWC12mx8p8zgZMjIBLiYL2djJ3Tw+nDm7dLO0V0iIw9W/gCnAicUwOkN9RxOISZZktmZkuMp9odY3phkND8FL+3GWoxyy7ADWrxIpBGR3fSHVFVQR7VMHHVOLJMdExcEfb7Hv0XdKTJconQ/S9Yqx5wUFuduIirQLNz1D/nqjoV2drW/z2Zf46S/ziyr5+KVv3VI1aMzakaRH8Wwx7/KgxirOWRABWf663nQHt3pqEBvqki1rKG54xDKTZfkk2QAFM5RlwvgHqJtOB0v17PrAV7rb+E1tt4fNavY047XDBTkNQRoN/IKMoQy46XqpaRDsv4QuOCQ8oqcMJ6hWNev84y7xaTaN2D1nGcQ5Ee5A3zNRF4APOw+tnyl0htNVfgLyailWotivMyivIJoQDEVLE/wigMObnXvFibwi4Hg4Djf1Ooiv7SB5ykpcG4Yr6P3jJagysi5K71ggaUGXD6yhsjBFxHMo2rnC+BnSbU3WhokJxEZLbZ0ftjvUAc+RoCid5Q3zS2410hgirll0K8yyDsajk3HMGCOtDShzoqQP/cCZ0xGSxjXjC0V5/WgktED3FNUlEiA1wKft2OA3JigfBC0IionLLzsbWc0bVv5Xad8Rih7DHAu7Iwy3DMnB95dAXih+2Pn97gvUH83IoGHbfM+yhJYnhh3oi6ziZou93i71jcGGuwn7IdFeThi0kRDzmumMJ8MMeEEVHetJ3tlRdNhSTpRrLxThacCF3lz0MReEZcyArhkB1A33J3QHifVWssDimRTvoOUhhOjouL92a5WOzPbFdqDVCfeX51IiLFQ+9BOEKM+JRgOICjZAnIng9ykqoOVIaGzt5TotbGNDUh4v7W6gIAGtFWBgBlIqHSdqhgo8CPBGurVRyQaQyQCVwEV+ul9vGb3gRhs+2NUBsy439Yzs5sA4uoaIC4S/QwVAoLKBCX8OHYnx7YE5khWSIBIhO1xHNbvzcvj3ANzGCZ6L1iC0N/BdelU0KdrTMT6y2LuZU+DE811AXy/h1+1RqWEYBWlcYRgwmizj2Ci7v0RTOrrEsH+IgRr6F8Lv7T6mRVDezkDHcgezf11ST+s/EhgeF3vq32SkbRyWTpPOOA3GUnfy5qp1o7Io4nS1tqNpUr5TmRSGyhmbhlHikdOhXlQglCpQyULlJ0I5sv/WjkqFUAKMyRj5IrkTDFCZezuTabNZmblTvuuXaibFXwaVSxQVYBAK9VecA8jodoCxDe4GsFMYBQgngaoWgGoFqgqQh0b1RpZxn3E6xQLifl16I1GJhBUNLRxQo7ElqpFZkzNodRUiteeN8nQREm4OdXkhH0QA2FWkcBaY3ovO+hD59fwrBXs7qHpFVQi1n9GDXzQFsZI6HxoeztiTADKLh/XaOJzKS9hT5oee2bCx+5sUf3mBsMKnRdfF1ObxXoGdH3s2UEx736bMSNmbGwF7LliLYdro2okNxvzNRLGCOkZtYJiD6m6TO9lnEkyZkWvm9FeiWsE5kYSyvxYPc4rLcrAQfU74YZzZqqm5d1ePXuO+OI+Mlci1paye3Tf2ZiUoeI+dRA+2DlTlRXhBdstA9ZO9Dkp1oIMd5Ljc3QvkSErbP0JwhbCh1LsszgT2ueC3qOwlLU4bCQ72BN7iuWKHOwzZewag0O2J/zsd2tk4yR0Dr6ew1nxswT48vE+QVN+zmE4ZfeL/WNj0WuPninbv0Fp3bQtxTlxZodnwuByNzY/m2If6VqVAo4YfLL9p3DsHOJMyuCU4ge9NpkbIeXPVihdoGNQoQ37yHGf+kiBYM0AQyoKZHtwyfDUwDa43wMQ7jguG9x9UsCsiXtXxfXA3jCYRgHLoOeQ0/twpmyvPL6P9B6DmYz1RXGSwZDOzpQLjXQsmMeYCpUIi+K8cn6dMzhn8G0J+Ga0gLpmqLBZwoMOH5+dFcxN4KLK4JuvI2MCLJsbPce0wAdG38R5quz88QzuORx22JwFLaG4qoi5MWdFt7ivsLmW6UV/2DJIQM8nZ+YxarqjQq6ohzlqrt9CUxPCTwq4lhdwaxS0KSrobreYs8L2T2FmOy4U763p8D5dkzU8pGHCESPaLoMdXUwYrtH7Yn3LPRo6iMVesHu2oPniN6NDQ0bPLbGGHe4Lmo/9cf5A8TIu4+SkUEYYbeDwwOiheI7R4TE/62FxVhpfS7ajsxMGC+w5Cp/knipD2Aecj1UzOwooFxSHqgWdFbTc53sq6OJY0GGO/35Bj3M214IfZmhK5DQrtqDdHr8q0woBQ2PBnzl8Ir+ncLrAcap8r/Qdn0QTrSLoNO+f0/YRwkEB4xU+diTG7gvaweGhL/i/UZx30ZbRuvkb+NOguGcJWjwUvO2AR+5oNZOLijPe0VkKWwxXsx3cE6rM7mAzKZ2XtZs7o/nlsfbmXfDbU+tW9vZrT7YYFPyXw3XG6V/C5ynoFN9v+jvd7fdCOEKRXuzxzD26xNfMaKigQ2a0wx1OIylu3FN6zvdbEfSK0vfdWek73KFwrHL6L2CFjmvt0WqOAwf03Y4En7EKvON9cBzot9m5FPSJ8pRJzJT/wZa6IIIbg7vh0ayuUJc49oVzQhcLx8N9t8Kx0bpVhFC1w2W42XkpP9WkrR2aBC7PbdOuH+mUG/e/WzeKz+xMhsV9x+f/qYrLCe+OXhhp6Sorrj7KCa2+OWJL/VJuaDHvIz/0bC2tBr9sNXhU0+pUbWzLLsuFTowmjNl6no2rCs6ZuQhtj4xA1s07rAzuPRLslXnnyAUI6953O7as3FTNoNTm0MHHnHlAIbkzL+0LZ94LwTc7NyN1KVJHOnMpUudgdjoEaD/I5mccy0R9T8eyt3MstwvHcv66Y5kocCLZoX0HOK/K5qCkNDQNue4ILS9Cs0DNBjkV4aUVMe7ogLTzwBzOXRrKplrjJCusEFR64RIVlfIslPZocBrsATy7ZA5ov2WS4KSdqGuXQhIsw8ZzPR2WFcy+3wSP3Xs4RYR2U6cuXgz0QsfxtUkx4gDSTkPRziW8g6Lh4d4mz9Mjh3kjcsfO86O/g97parqCeQDGLLfONcF5IQfPTaMDUghJTab1ZFCy61O2sufH6+UacHov0GOQk8Uku/Nhdt3G0+P6LqcObGoTa2ZMfyRoM/MQBy10XEA9t5fx+nt0bEAJ8kg+8BiumlCibDF4PcxvNFDvRk5rFw6AuHxFeAkni/a3GywBmm4YJI06KQ1qQ1l7ZGEYIso2EYVqRgt4efWyY+JLSTR1YX0vnBxnlmgaP44q/yCBBfjpJj4QPWjdnvDxccKJkDleFU7Ud3eV/J5DSkZUyABtGaAtA7TfmwmdW63Wjl21d0Ds3fzbc7hFzTpyN7C8C6THWtpEDuTG2836ZaVbksG3kcE9hLM65J4odyD8vgrauRdZCo3g1WmEaZboPRpjguVStVbcPUEJ0SKiJjXjJiRo4mTmvYiZAvGekj3QmJMmxpxUmbjZYTEnoNwcEYkX5kNGS0CjFndzIeGk5rUqLdcTlZpAuWkRHc+AihFZeSjiptw9l/J4mSpDTa7YrCextSBILEG4382Pqah03BOoW2YyTK2jjj8Q2YdGJ5kIRwKqOXRGWN789M451El5J4RiahCEXazgOMw5MjgWjl9STNdlpbSToHp+eu8LxWVPURmg0181GYHXTdwnVmqsHksCSusA4JCwGCmAXxb1DSUyiCG/9nmZsXrRzjpUqk7AgkVjqpKs3xYmYmpGrlIGOkRzO3V/6sAUFcq6gwmaXzlzAiZJmZOpAolWhPkcVBLuIpsG1OzPXenMpIuuAyTxngdKFlN6gwWNWiZogqVMmWC0ecZhkJnnsyTj5uEKjROjJl/CYNagpniVwijMlcFnknA3nDD/C1emaueDwrRuibCBFUm5+V64j6qU/QyFq5bvi0Hjx4Sru0LdvkAHqDuNzn2gUdM0W5PCoMsEvH9gbh1qHifpjJqenX3BhZvr7wt3M/k+wd/CnZtzcYqauJlrbuLBWiJ2j7lHQIDZAmVi4hjdK4AzqooCjaBmfqj/fizE9FT7SPy6WU60gccMPwWjh9Wh0LejglbgqcwwtRMlDjIi8NR3I+bJs61N17ce1TbfIxLu0O6tVqvnZdD6qWTk2myFPHL9GGFhh6vVdg0sNHYpW567OBHbdqM9Ll1+5KJIwP6KEXZv0VFfPOuPDq47DEbWLrV/quVO3pqDXFH117r64LxjvXICuqRAJwOZ/9BA5iPkrJ05klmkBkkEkwj2NyDYgXh0fvz6IzMF3u+1K3rjS9nJ9WMnvoz8l5H/MvJfRv7LyH8Z+S8j/2Xkv4z8l5H/MvJfRv7LyP8/I/L/7C+REyrur4Qo+E84o7WDmwJ6vjS9yWAFGawggxVksIIMVvgLgxWqFf28rLp67O3aS9Ljb6tHjvq/kKn3qkmen+I35R+1IRzxvxucUA4vrVUPTvrNb0c/6EfkKrwSlrDrRzQM//03cn83dEH/z3+Nxvca0ds3y0a9bT144fTbWbIn9oFIV0tgtF/xIijBVfGK/jfCVykYpuxt2o+J+T1/k3jd/av+ptrXShoV85budZmXIfMyZF7Gr+dllD8rUrtUzyxJHedlyLeyy7eyy7eyy7eyy7ey/9Jb2WsnXmr7qSS9Vv1f1Fh+Nnz/dVWl/oeqKscvMJKqilRVpKoiVZXfYmtn11Quz8PWPsoq+87pYTX13dLDTnT1welh1WPXu+RZMnvlj81eOULOc3/oovaGTw1LBJMI9qcg2IFD+vz4deyQlvlIMh9J5iPJfCSZjyTzkWQ+ksxHkvlIMh9J5iPJfCSZj/Rn5CPVzv3K1Jo0in6YLvnSVw+4xCa+enDPv3rQUq2uhy4rJh1mDOsxYKNnAHdcEyZZZSDNGdOi7SAHicHwWP7HkAVa0HfvvymIw9QH+V6gTY5uuTsT35u/C7ahFEzH0rqaZExrMDl1QDcbSpl3IUHqyFxwEcN+D0vFCTqYd4JuNuagzL0ty28Bqcc/HRB0HPRhGVY+vaIZCjzowyqCPogI+sg/0BZUrZdj6urK5XmNQfVjY5BEXIm4EnEPEFdVvxriahJxJeJKxP1ZxNXrx6Ly5yKuTM+RiCsR96dFZbVSOS/iNo7f4zij6SfREf5+RrBX6sd7mbtwNdm7swtdxgsRuXze71zVefrOq0HKdb7RXyRIuf5S2pH8CKf8CKf8CKf8CKf8CKf8COc75tnWG2dOyqqf+/3h7y14vLs8cTo2XTtQNS8btXIXHxyZXj8WUKVmKbOpZDaVzKb6LYZ0KZxE52JIl5UjOvZ3Zgn/Oo8TGW+vKteXX+sj0mLekmdJniV5luRZ75QBfH6Wpf1ROtRnZwBfVt4tA/hEVx+sZ11KD55MUPyLEhQPkfOUAepTPW2XVYlgEsH+HgQ7iNY+P34dezRlBrDMAJYZwDIDWGYAywxgmQEsM4BlBrDMAJYZwDIDWGYA/xkZwJcn0ho+1+AtM4BlWoNMa3gVcQ/TGhrKmfORGvJ1ixJxJeK+iriHiYTnR9zjDGD5ORz5ORz5ORz5ORz5OZxfihqqnCDpn6pENY4jS2SqoUw1lKmGMtVQphrKVMN3z+zQaudmeMcfAJvZtvv0Bb6N/qEvS3jrd9CVf0Sw6W8G4NarB2+M1OvlLt4afnvUkYi0Ps9n0E9DlXxjgxSjpBglxSgpRkkx6hPEqLN/RrcwXOxxPGDCER2LMT7bPYcQ9ee9pUrEZr+eSKu+UZT7nETaxrH/XXoDpDdAegOkN0B6A34th1j5vBzi2u19VF8PnIf/uwkbHS1Ozdndt1NveK7NVkiT148RFhv3v1s3OuLz5UYXwnH9tXKRS2zeXuL87dHcXx9w+0pxtgeM9sRhf0DaclnQK3KPfzppWTvs6P2SluFyE4bxfvPN7GlOQsfFFv8P \ No newline at end of file diff --git a/docs/dayon.connection.diagram.svg b/docs/dayon.connection.diagram.svg deleted file mode 100644 index 9e31b2bc..00000000 --- a/docs/dayon.connection.diagram.svg +++ /dev/null @@ -1,3 +0,0 @@ - - -
enters token
enters token
AssistedInternet
requests token
requests token
AssistantRendez-vous serverreturns token
 communicates the access token 
 communicates the access token 
InternetRendez-vous serverreturns ip and port
requests connection
requests connection
AssistedInternet
assists
assists
AssistantInternetAssistedAssistant
accepts connection
accepts connection
Assistant
gets assistance
gets assistance
Assisted
 requests assistance 
 requests assistance 
Text is not SVG - cannot display
\ No newline at end of file diff --git a/docs/dayon.png b/docs/dayon.png deleted file mode 100644 index 28eb337c..00000000 Binary files a/docs/dayon.png and /dev/null differ diff --git a/docs/dayon.screen.ms.store.png b/docs/dayon.screen.ms.store.png deleted file mode 100644 index b03904e0..00000000 Binary files a/docs/dayon.screen.ms.store.png and /dev/null differ diff --git a/docs/dayon.screen.png b/docs/dayon.screen.png deleted file mode 100644 index 26aeb19a..00000000 Binary files a/docs/dayon.screen.png and /dev/null differ diff --git a/docs/dayon.screen.store.png b/docs/dayon.screen.store.png deleted file mode 100644 index cd152ab0..00000000 Binary files a/docs/dayon.screen.store.png and /dev/null differ diff --git a/docs/dayon_fingerprints.jpg b/docs/dayon_fingerprints.jpg deleted file mode 100644 index 95f28b45..00000000 Binary files a/docs/dayon_fingerprints.jpg and /dev/null differ diff --git a/docs/dayon_start_chat.jpg b/docs/dayon_start_chat.jpg deleted file mode 100644 index 05beb5cf..00000000 Binary files a/docs/dayon_start_chat.jpg and /dev/null differ diff --git a/docs/de_download.html b/docs/de_download.html deleted file mode 100644 index 1908dab2..00000000 --- a/docs/de_download.html +++ /dev/null @@ -1,317 +0,0 @@ - - - - - - - - - Dayon! - Fernwartung für Familie und Freunde - - - - - - - -
-
- EN - FR - SV - 汉语 -
- -
-

Download

-

- Windows 10/11 Anwender laden sich die App am einfachsten direkt vom - Microsoft Store. -

- -

- - German badge - -

- -

- Sich selbständig aktuell haltende Pakete mit breiter Hardwareunterstützung sind im Snap Store, - auf Flathub und via - ppa:regal/dayon verfügbar. -
-

- -

- - Get it from the Snap Store - -

- - Get it from the Flathub - -

- -

- Ansonsten finden sie auf GitHub und - SourceForge die aktuellsten Installationspakete für ihre Plattform. -

- -

- - Download Dayon! (active) - -

- -

- Windows: - ab Version 1.9 existieren vier unterschiedliche Installationspakete, die eigentliche Installation ist selbsterklärend. Sie haben die Wahl - zwischen einem Installer mit oder ohne integrierter JRE (OpenJDK 11 LTS basiert). Das Paket mit integrierter JRE eignet sich bloss für 64Bit - Windows Varianten. Daneben existieren zwei separate "Quick Launch" Versionen für den Assistenten und den Assistierten. - Diese beiden portablen Versionen benötigen keine Installation. Um bei diesen Versionen möglichen Probleme mit der Benutzerkontensteuerung zu - vermeiden, wird empfohlen den Assistierten mit Administratorenrechten zu starten. -

- -

- Debian, Ubuntu und Derivate: damit sie Dayon! nicht händisch um aktuell halten müssen, wird eine - Installation via ppa:regal/dayon - oder als Snap empfohlen. -
- PPA: sudo add-apt-repository ppa:regal/dayon, sudo apt-get update - und schliesslich sudo apt-get install dayon. -
- Snap: sudo snap install dayon. Alternativ können sie manuell herunter geladene - .deb Pakete mittels dem Befehl sudo dpkg -i dayon*.deb via Terminal installieren. -

- -

- Linux: entweder die sich selbständig aktuell haltende Snap App via - Snap Store oder mittels sudo snap install dayon installieren. -
- Alternativ das herunter geladene .tgz Paket mittels tar xzvf entpacken. - Im Zielverzeichnis das Shellskriptsetup.sh ausführen. -
- Die installierte JRE resp. JDK wird automatisch detektiert. Die JRE ist nicht im .tgz-Paket enthalten. - Sollte die Autodetektierung aus irgendeinem Grund fehlschlagen, so überprüfen sie das Vorhandensein einer JRE - und definieren sie deren Pfad in der Variable JAVA_HOME im Skript (dayon.sh). - Beachten sie, dass die.tgz Pakete bloss auf diversen Debian und Ubuntu Versionen getestet worden sind. -

- -

- macOS/OS X: - das .dmg Paket öffnen und den Assisted oder den Assistant auf das Programme-Icon ziehen. - Gegebenenfalls muss noch eine passende Java JRE 11 (oder neuer) installiert werden.
- Alternativ: das .tgz Paket an einen Ort ihrer Wahl entpacken. Ev. einen Alias für dayon_assisted.sh - und dayon_assistant.sh erstellen und auf den Desktop kopieren. (Voraussetzung: ebenfalls eine installierte JRE 11 oder neuer). -
- Wichtig: Ab macOS Catalina und neuer, müssen sie die Berechtigung zur Bildschirmerfassung explizit gewähren: - Systemeinstellungen > Sicherheit und Datenschutz > Datenschutz > Bildschirmaufnahme -

- -

Changelog

-

- Dayon! v14 Candid Clover (7. März 2024) - * -

- - -

Dayon! v13 Beard Butter (5. November 2023)

- - -

Dayon! v12 Adorable Asteroid (16. April 2023)

- - -

Dayon! v11 Ballsy Beaver (31. Oktober 2021)

- - -

- Dayon! v1.10 Lucky Lobster (27. März 2020) - * -

- - -

- Dayon! v1.9 Promiscuous Potato (11. Dezember 2019) - * -

- - -

- Dayon! v1.8 Truganini (18. Mai 2019) - * -

- - -

- Dayon! v1.7 Tesler (21. Februar 2019) - * -

- - -

- Dayon! v1.6 Solenodon (19. Dezember 2018) - * -

- - -

- Dayon! v1.5 Pendragon (5. Mai 2017) - * -

- - -

- Dayon! v1.4 Skytale (3. Januar 2017) - * -

- - -

- Dayon! v1.3 Phoenix (10. Dezember 2016) - * -

- - -

- Dayon! v1.2 (3. Januar 2009) - * -

- - -

- Dayon! v1.1 (24. Dezember 2008) - * -

- - -

Dayon! v1.0 (4. Dezember 2008)

- - - - * Hauptversionen sind nicht untereinander kompatibel - -

- Historische Versionen (v1.0 bis v1.2) finden Sie da. -

-
- -
- - diff --git a/docs/de_index.html b/docs/de_index.html deleted file mode 100644 index e4f6e73e..00000000 --- a/docs/de_index.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - - - - Dayon! - Fernwartung für Familie und Freunde - - - - - - - -
-
- EN - FR - SV - 汉语 -
- -
-

Fernwartungsprogramm

-
-

- Dayon! ist ein Plattform übergreifendes, Open-Source Fernwartungs­programm. Ähnlich wie andere Programme - dieser Art, ermöglicht es den Zugriff und die Fernsteuerung von entfernten Computern. -

- -

- Im Gegensatz zu anderen Lösungen ist diese aber Open-Source, kostenlos und äusserts anwenderfreundlich. -

-

- Weitere Details dazu finden Sie da. -

-
- -

Features

-
-

Einfache Konfiguration

-

- Dayon! richtet sich auch an weniger versierte Computeranwender. Es - ermöglicht ihnen auf unkomplizierte Art und Weise Hilfe anzufordern. - Hierfür sind keine Netzwerkkonfigurationen notwendig (keine - Firewall-Einstellungen ändern, keine Routerkonfigurationen anpassen - und auch kein NAT einrichten). -

- -

Geringe Netzwerkbandbreite

-

- Dayon! reduziert die benötigte Bandbreite auf ein absolutes Minimum. - Die komprimierten und gecachten Bilder werden in Graustufen (bis zu - 256 Stufen) übermittelt. Dies ermöglicht eine nahezu - Echtzeit-Erfahrung via Internet. Für eine Hilfestellung aus der - Ferne reichen die Graustufenbilder allemal. -

-
- -

Status (14)

-

- Seit Release 1.9 (Promiscuous Potato) existiert nebst den - konventionellen Installationspaketen eine portable "quick launch" - Version. Diese ausschliesslich für Windows verfügbare "quick launch" - Version besteht aus zwei separaten Dateien - je eine für den - Assistenten und eine für den Assisterten. Sie heissen "quick launch", - weil man damit den Assistenten oder den Assistierten unter Windows - ohne vorgängige Installation direkt starten kann (erfordern allerdings das Vorhandensein einer JRE). - Sie sind 100%ig kompatibel zu den konventionellen Dayon! Versionen. - Seit Release 12 (Adorable Asteroid) existieren ähnliche portable Versionen auch für Linux. -

- Mangels entsprechender Hardware konnte ich die Funktion zur - Übertragung der Zwischenablage bloss mit Windows 10 und 11, Debian und Ubuntu - testen - Feedback von macOS Anwendern wäre sehr willkommen! -

- -

Hintergrund

-

- Marc Polizzi entwickelte Dayon! während seiner Zeit in den - Philippinen, als er mit seiner Familie und seinen Freunden in Europa - via Skype kommunizierte. -

- -

- Er wollte ihnen weiterhin bei ihren alltäglichen Computerproblemen - helfen, ohne dass sie hierfür ihre Firewall oder DSL-/Kabelrouter um - konfigurieren mussten, nur damit er auf ihren Desktop zugreifen - konnte. Also hat er in seiner Freizeit ein möglichst einfach zu - bedienendes Programm entwickelt. Aufgrund der hohen Netzwerklatenz und - der damals eher bescheidenen Upstream-Bandbreite hat er ein - spezielles Augenmerk auf möglichst geringen Bandbreitenbedarf gelegt. -

- -

- Jahre später, bin ich auf - Sourceforge - auf das Programm aufmerksam geworden, als ich auf der Suche nach einem - Plattform übergreifenden Fernwartungsprogramm war. Ich fand rasch - gefallen an dem äusserst anwenderfreundlichen Konzept von Dayon!. Ich - musste aber bald feststellen, dass das Programm im Zusammenspiel mit - Windows 7 und neueren Versionen noch ein paar ziemlich schwerwiegende - Mängel aufwies. Dies war auch nicht weiter erstaunlich, datierte doch - die damals aktuellste Dayon! Version (1.2) von Anfangs 2009. So - entschied ich mich schlussendlich den Urheber zu kontaktieren. Mit - seiner ausdrücklichen Erlaubnis habe ich den Sourcecode des - Projekts Ende 2016 nach - GitHub - transferiert und entwickle es seither weiter. -

- -

- Dayon! bedeutet übrigens "Komm' rein!" auf Visayas - einem lokalen - Philippinischen Dialekt. -

-

Lizenz

-

- Dieses Programm ist Open-Source und unterliegt der - GPL Lizenz. - - Dayon! (active) Reviews - -

-
- - -
- - diff --git a/docs/de_privacy.html b/docs/de_privacy.html deleted file mode 100644 index 46f44dc4..00000000 --- a/docs/de_privacy.html +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - Dayon! - Fernwartung für Familie und Freunde - - - - - - - -
-
- EN - FR - SV - 汉语 -
- -
-

Datenschutzerklärung

-

100%iger Datenschutz

-

- Dayon! ist ein absolut kostenloses Open-Source-Programm, das für öffentliche Sicherheitsaudits zur Verfügung steht. - Die gesamte Kommunikation ist standardmässig verschlüsselt. - Das Programm sammelt keine personenbezogenen Daten und gibt solche auch nicht an Dritte weiter. -

-

Optionale Verwendung von Tokens

-

- Eine optionale Funktion für eine einfache Verbindung ist die Verwendung von Tokens. - Es wurde ein risikobasierter Ansatz gewählt, um die Risiken für die Privatsphäre bei der Nutzung dieser Funktion zu minimieren: - Die Standardkonfiguration für diese Funktion beruht auf der Verwendung eines Token-Servers eines Drittanbieters. - Die IP-Adresse eines Nutzers wird auf dem Server bis zu 7 Tage nach der letzten Nutzung gespeichert. Der einzige Zweck besteht darin, die Verbindung zwischen den beiden Parteien zu ermöglichen. - Der Server ist in der Schweiz gehostet. Verantwortlicher Datenverarbeiter ist dessen Betreiber. - Diese Funktion kann so konfiguriert werden, dass stattdessen ein selbst gehosteter Server verwendet wird, um die gemeinsame Nutzung von Daten mit einem Drittserver zu vermeiden. -

-
- -
- - diff --git a/docs/de_quickstart.html b/docs/de_quickstart.html deleted file mode 100644 index 3c1cd01e..00000000 --- a/docs/de_quickstart.html +++ /dev/null @@ -1,401 +0,0 @@ - - - - - - - - - Dayon! - Fernwartung für Familie und Freunde - - - - - - - -
-
- EN - FR - SV - 汉语 -
- -
-

Schnellstart

-

- Typischerweise kommuniziert der Assistent via Jitsi, telefonisch oder mittels eines - Instant-Messengers mit dem Assistierten, während Dayon! es dem Assistenten erlaubt, - live den Bildschirm des Assistierten zu sehen und die Kontrolle über dessen Maus und Tastatur zu übernehmen. -

- -

- Beachten Sie bitte, dass für diese Dokumentation englischsprachige Screenshots verwendet werden. Die - Applikation ist aber komplett auf Deutsch verfügbar und die Benutzeroberfläche wird aufgrund der - Anwendersprache lokalisiert. Die Symbole sind in allen Sprachen identisch. -

- -

- Achtung: Diese Dokumentation bezieht sich auf die jeweils aktuellste Programmversion.

-

- -

Assistent  Konfiguration Assistent

- -

- Der Assistent fungiert als eine typische Server-Anwendung (der Assistierte verbindet sich mit dieser). - Auf dieser Seite der Verbindung ist etwas Konfigurationsaufwand notwendig. Das Netzwerk des Assistenten - (der, welcher Hilfe anbietet) muss so konfiguriert werden, dass es vom Internet her erreichbar ist. -

- -

- Standardmässig horcht der Server auf Port 8080, Sie können diesen aber bei Bedarf ändern. - Seit Version 12, richtet Dayon! eine entsprechende Portweiterleitung selbständig ein. Voraussetzung dafür - ist aber, dass UPnP aktiviert ist. Ansonsten wird es weiterhin notwendig sein, den Port - (TCP) via NAT auf demRouter an den entsprechenden Rechner - weiterzuleiten.

- Bebilderte Schritt-für-Schritt-Anleitungen für das Einrichten von Portweiterleitungen für die gängigsten - Router Modelle finden Sie beispielsweise auf portforward.com. -

- -

- Optional: Port für eingehende Verbindungen anpassen: (links mit aktiviertem UPnP, rechts - ohne) -

- -

- Dayon! Assistent: Network Settings mit UPnP - Dayon! Assistent: Network Settings ohne UPnP -

- -

Token generieren und kopieren

- -

- Generieren Sie als Nächstes mittels Mausklick auf den Schlüssel ein Zugangstoken: -

- -

- Dayon! Assistent: Token erstellen -

- -

- Kopieren Sie das generierte Token mittels Mausklick in die Zwischenablage: -

- -

- Dayon! Assistent: Token kopieren -

- -

- Das wär's bereits - teilen Sie dieses Token dem Assistierten via Mail, IM oder - Telefon mit. -

- -

- Für ungeduldige: Hier erfahren Sie, wie Sie den Assistenten - empfangsbereit machen. -

- -

Alternative: verbinden ohne Token

- -

- Wenn Sie kein Token verwenden möchten, müssen Sie die öffentliche IP-Adresse ihres Rechners ermitteln. - Mit dieser kann sich der Assistierte dann verbinden. Klicken Sie dazu auf Ermittle meine IP-Adresse (öffentlich). - Fürs Testen im LAN können Sie auch einfach die private IP-Adresse nutzen: -

- -

- Dayon! Assistent: Network IP-Adressees -

- -

- Wie Sie im nächsten Bild erkennen, enthält das Menü auch eine Rubrik Kopiere IP-Adresse & - Portnummer, welche die IP-Adresse und die zuvor konfigurierte Portnummer in die Zwischenablage - beispielsweise einfach in ihre Chat-Sitzung (z.B. Jitsi) oder in eine E-Mail einfügen. -

- -

- Dayon! Assistent: Network IP-Adresse Actions -

- -

- - Beachten Sie, dass die IP-Adresse für den Assistenten irrelevant ist, da die Applikation an allen - verfügbaren Netzwerkschnittstellen horcht; Sie benötigen diese Angaben jedoch, um Sie dem Assistierten - zu kommunizieren. (mehr zu diesem Thema später). - -

- -

Start

- -

- Das wär's. Mit einem Klick auf den Play-Button (der erste von links) - machen Sie den Assistent empfangsbereit: -

- -

- Dayon! Assistent : Start -

- -

- Nun können Sie den Assistierten zum Verbinden auffordern. Kurz darauf dürften Sie über die - eingehende Verbindung informiert werden: -

- -

- Dayon! Assistent : Incoming Connection -

- -

- Nun sind Sie mit dem entfernten Computer verbunden und sehen dessen Desktop. - Vergleichen Sie unbedingt die Zertifikatsfingerabdrücke des Assistenten und des Assistierten. -
- Achtung: Sollten diese nicht übereinstimmen, dann ist die Verbindung nicht vertrauenswürdig! -

- -

-
-

- - -

Assistierter   Konfiguration Assistierter

- -

- Der Assistierte (Dayon!) ist eine Client-Anwendung, welche den Assistenten kontaktiert. Dadurch entfallen - allfällige Netzwerkkonfigurationen auf dieser Seite. -

- -

- Dayon! herunter laden und installieren. Danach die Dayon! Applikation starten. - (Sie sollten eine entsprechende Verknüpfung auf ihrem Desktop vorfinden) klicken Sie auf das "Play" Symbol. -

- -

- Dayon! Assistierter : Ready -

- -

- Tragen Sie das vom Assistenten mitgeteilten Token ein und quittieren Sie mit OK:
-

- -

- Dayon! Assistierter : Token -
- (sollten Sie sich vor kurzem bereits mit diesem Assistenten verbunden haben, dann können Sie das - Feld auch leer lassen) -

- -

Alternative: verbinden ohne Token

- -

- Tragen Sie stattdessen die vom Assistenten mitgeteilte IP-Adresse und Portnummer ein und quittieren Sie mit OK:
-

- -

- Dayon! Assistierter : Network
- (beide Eingabefelder können mittels Doppelklick geleert werden) -

- -

- Kurz nach dem Klick auf OK werden Sie mit ihrem Assistenten verbunden sein. Viel Vergnügen! -

-

- -

- Dayon! Assistent : Running -

- -

- Hinweis: Wenn Sie keine Verbindung herstellen können, indem Sie die obigen Anweisungen befolgen, - sollten Sie die Einstellungen überprüfen. -

- -

Verwalten der Sitzung

- -

- Wenn der Desktop des Assistierten nicht vollständig in das Fenster passt, können Sie die - Darstellung skalieren: -

- -

- Dayon! Assistent : Fit Screen Toggle -

- -

- Mittels Klick auf die open lock Schaltfläche rechts davon, können Sie das Seitenverhältnis des Bildschirms des Assistierten beibehalten. - Bitte beachten Sie, dass diese Funktion bei maximiertem Fenster keinen Effekt auf die Darstellung hat. -

- -

- Standardmässig ist die Fernsteuerung nicht aktiv; Sie können Sie jederzeit mit diesem - Symbol aktivieren bzw. deaktivieren: -

- -

- Dayon! Assistent : Control Toggle -

- -

Übertragen der Zwischenablage

-

- Mittels Klick auf die Up- resp. Down-Schaltfläche, kann die entweder die Zwischenablage des Assistenten - an den Assistierten (Up) oder die Zwischenablage des Assistierten an den Assistenten - (Down) übertragen werden. -

- -

- Dayon! Assistent : Clipboard transfer -

- -

-

Unterstützt werden zurzeit:

- - -

-

Windows- oder Cmd-Tastendruck übertragen

-

- Um das Drücken der *Windowstaste zu übertragen, klicken Sie in der Bedienleiste des Assistenten auf - die Windows-Schaltfläche: -

- -

- Dayon! Assistent : Windows Key -

- -

- Die Taste bleibt gedrückt, bis Sie die Schaltfläche erneut klicken. Auf diese Weise können Sie auch - Windows-Tastenkombinationen senden.
- Wenn Sie beispielsweise alle Fenster des Assistierten minimieren möchten, klicken Sie auf die - Windows-Schaltfläche, danach drücken Sie die M Taste und klicken schliesslich erneut auf die - Windows-Schaltfläche. -

- -

- *Hinweis: Falls auf dem verbundenen Assistierten macOS läuft, wird eine Cmd-Schaltfläche angezeigt resp. übertragen. -

- -

-

Ctrl-Tastendruck übertragen

-

- In den meisten Fällen wird die Ctrl-Taste wie jeder andere Tastendruck an den Assistierten übertragen, - es gibt jedoch Situationen, in denen dies nicht der Fall ist. Zum Beispiel wird die Kombination Ctrl + Alt + Delete im Allgemeinen - vom Betriebssystem des Assistenten direkt interpretiert und daher nicht übertragen. - In solchen Fällen bietet sich die [Ctrl] Schaltfläche neben der Windows-Schaltfläche in der Bedienleiste der Assistenten an, - die sich genauso verhält wie die Windowstaste: Die Taste bleibt so lange gedrückt, bis Sie erneut auf die Schaltfläche klicken. -
- Um also die Kombination Ctrl + Alt + Delete an den unterstützten zu senden, müssen Sie zuerst auf die Schaltfläche [Ctrl] klicken. - Drücken Sie dann gleichzeitig die Tasten Alt und Delete, lassen Sie sie los und klicken Sie schliesslich erneut auf die Schaltfläche [Ctrl]. -

- Achtung: Aufgrund von Beschränkungen des Betriebssystems, funktioniert das Übertragen von Ctrl + Alt + Delete an Assistierte, welche unter Windows laufen nicht!
- Verwenden Sie stattdessen die Kombination Windows + R welche eine vergleichbare Funktionalität bietet. -

- -

Bildschirmfoto des Assistierten aufnehmen

-

- Klicken Sie die "Kamera" Schaltfläche - das Bildschirmfoto wird ohne weitere Rückfrage direkt erstellt. - Die aufgenommene Grafik landet in der Zwischenablage des Assistierten, von wo aus sie zum Assistenten übertragen werden kann. -

- -

- Dayon! Assistent : Take screenshot -

- -

- Die Funktion "Bildschirmaufnahme zurücksetzen" (Mülleimersymbol) verwirft die übertragenen Bildschirmdaten und lädt sie erneut vom Assistierten. -

- -

Onlinemeeting starten, um direkt miteinander zu chatten

-

- Klicken Sie auf den Zertifikatsfingerabdruck des Assistierten und des Assistenten, um ein gemeinsames Online-Meeting in Jitsi Meeting zu starten. -

- -

- Dayon! start chat -

- -

Statistiken in der Statusleiste

- - Dayon! Assistant : Statistics - -

Die Statusleiste des Assistenten zeigt nebst der Tastaturbelegung folgende Zähler an:

-
    -
  1. Netzwerkbandbreite
  2. -
  3. - Kompressionsverhältnis: wie oft der Inhalt der initial erfassten - Kacheln (bloss Differenz) komprimiert wurde -
  4. - -
  5. - Anzahl Kacheln: Anzahl übermittelter Kacheln (inkl. Puffer-Treffer). -
  6. -
  7. - Anzahl übersprungener Bildschirmaufnahmen: Anzahl Bildschirmaufnahmen, welche wegen eines zu kurzen - Aktualisierungsintervall (für die entsprechende Hardware) übersprungen worden sind. - Um diese Anzahl zu reduzieren, erhöhen Sie das Erfassungsintervall. -
  8. - -
  9. - Anzahl kombinierter Bildschirmaufnahmen: Anzahl Bildschirmaufnahmen, - welche vor der Übertragung kombiniert worden sind. Dies ist ein - Anzeichen für ein zu kurzes Erfassungsintervall für die gewählte - Komprimierungsmethode. Am einfachsten das Erfassungsintervall - erhöhen und/oder eine schnellere Kompressionsmethode wählen. -
  10. - -
  11. Speicherbelegung
  12. -
  13. Dauer der aktuellen oder der letzten Sitzung
  14. -
- -

- Das wär's - weitere Informationen finden Sie auf der Seite Einstellungen! -

-
- -
- - diff --git a/docs/de_settings.html b/docs/de_settings.html deleted file mode 100644 index 979354e5..00000000 --- a/docs/de_settings.html +++ /dev/null @@ -1,213 +0,0 @@ - - - - - - - - - Dayon! - Fernwartung für Familie und Freunde - - - - - - - -
-
- EN - FR - SV - 汉语 -
- -
-

Einstellungen

- -

Assistent   Assistent

- -

- Hier kann der Assistent definieren, wie der Bildschirm des Assistierten - erfasst werden soll; Es kann sowohl der Intervall (in Millisekunden) zwischen - zwei Aufnahmen (Tick), als auch die Anzahl Graustufen definiert werden. - Beginnend mit Dayon! 15, können alternativ auch sRGB-Farben verwendet werden. In diesem Fall wird die Anzahl der Graustufen ignoriert. - Bitte beachten Sie, dass bei der Verwendung von "Farben" mehr Bandbreite und RAM auf der Assistierten Seite verbraucht wird. -

- -

- Dayon! Assistent: Capture Settings -

- -

- Da kann die Komprimierung festgelegt werden; Es stehen zwei verschiedene Methoden zur Auswahl: - ZIP und XZ. XZ erzielt einen wesentlich besseren Komprimierungsgrad, benötigt aber mehr Rechenleistung - (CPU-Last und Arbeitsspeicher), da der Algorithmus aufwändiger als ZIP ist und XZ in JAVA implementiert ist. - (während ZIP via nativem Code vom JDK implementiert ist). -

- -

- Zusätzlich wird ein Puffer (Cache) verwendet, um nicht immer aufs neue dieselben, - unveränderten Bitmaps übertragen zu müssen. Hierfür wird der Bildschirm in zahlreiche Kacheln - aufgeteilt. Jede dieser Kacheln kann separat gepuffert werden. Die maximale Anzahl zwischen gespeicherten - Kacheln kann definiert werden. Eine einzelne Kachel besteht aus 32x32 Pixel (Bildpunkten) in maximal - 256 Graustufen - das entspricht rund 1 KB. -

- -

- Dayon! Assistent : Compression Settings -

- -

Erweiterte Verbindungseinstellungen

-

- Dayon! Assistant: Token server -

- -

- Nebst der Portnummer, auf welcher der Assistent lauscht, kann im Netzwerkeinstellungsdialog auch der zu verwendende Token-Server konfiguriert werden. - Es kann entweder der Standard Token-Server oder ein benutzerdefinierter verwendet werden. Eine Liste der verfügbaren Token-Server finden Sie weiter unten. - Wichtig: Stellen Sie sicher, dass Sie auf der Seite des Assistenten und des Assistierten denselben Token-Server verwenden! -

- -

-
-

- -

Assisted   Assistierter

- -

UAC Einstellungen

-

- Damit der Assistent alle Systemdialoge sieht, müssen die UAC-Einstellungen (User Account Control) unter Windows angepasst werden. - Der Einfachheit halber ist der UAC-Einstellungsdialog direkt via der Benutzeroberfläche des Assistierten erreichbar. - Die zweitunterste Einstellung hat sich bewährt. -

- -

- Dayon! Assisted: UAC -

- -

Erweiterte Verbindungseinstellungen

-

- Dayon! Assisted: Token server -

- -

- Im Netzwerkeinstellungen-Dialog des Assistierten können Sie die Portnummer und die IP-Adresse des Assistenten manuell konfigurieren, falls Sie eine Verbindung ohne Token herstellen möchten.
- Sie können auch die automatische Verbindung aktivieren oder deaktivieren. Wenn diese Option aktiviert ist, stellt der Assistierte beim nächsten Start ohne weitere Rückfrage eine direkte Verbindung zum angegebenen Host her. - Auch der zu verwendende Token-Server kann hier konfiguriert werden. Es kann entweder der Standard Token-Server oder ein benutzerdefinierter Server eingestellt werden.
- Eine Liste der verfügbaren Token-Server finden Sie unten auf dieser Seite.
- Wichtig: Stellen Sie sicher, dass Sie auf der Seite des Assistierten denselben Token-Server wie beim Assistenten verwenden! -

- -

Automatische Verbindung des Assistierten via Kommandozeilenparameter

- -

- Der Hostname oder IP-Adresse und der Port des Assistenten können via Kommandozeilenparameter übergeben werden; ah=Host oder IP-Adresse und ap=Portnummer: -

- - - -

- Wird der Assisterte mit diesen Parametern gestartet, so verbindet er sich ohne Rückfrage direkt mit dem angegebenen Host "an.example.com" und dem Port "4242". -

- -

Dayon! via Konfigurationsdatei konfigurieren

-

- Seit Version v11.0.5, können die Verbindungsparameter in einer YAML-Datei hinterlegt werden. -

- Dadurch ist es möglich, Benutzereinstellungen zu überschreiben, da beim Start immer die Konfiguration aus der YAML gelesen und ausgewertet wird. Benutzer können zwar Änderungen innerhalb der Anwendung vornehmen, diese bleiben aber nur bis zum nächsten Start erhalten, wenn eine YAML-Konfiguration vorhanden ist. -

- Der primäre Anwendungsfall für YAML-Konfigurationen wäre für Organisationen, die einen selbst gehosteten Token-Server anstelle des öffentlichen Token-Servers verwenden möchten, oder einen bestimmten Host festlegen wollen, mit dem sich der Assistierte beim Start automatisch verbinden soll. -

- Die Struktur der YAML Datei des Assistierten ist äusserst einfach: -

-
-host: "an.example.com"
-port: 8080
-# autoConnect: false
-# tokenServerUrl: "https://example.org/token/"
-
- -

-

-

- -

- Auch der Assistent kann mittels YAML Datei vorkonfiguriert werden: -
-

- - Diese YAML Datei(en) können unter dem Namen assisted.yaml und - assistant.yaml entweder im Dayon! Heimverzeichnis, im Benutzerverzeichnis, - oder im selben Verzeichnis wie die .jar, resp..exe Datei abgelegt werden. - Diese Reihenfolge entspricht auch der Priorität, mit welcher Sie berücksichtigt werden, falls mehrere Konfigurationen existieren. (die erste gewinnt)
-

- -

Öffentliche Token-Server

- -

- Nachfolgend finden Sie eine Liste der verfügbaren öffentlichen Token-Server, die kostenlos genutzt werden können.
- Möchten Sie einen eigenen Token-Server betreiben und wollen Sie ihn in die Liste aufnehmen? Lassen Sie es mich wissen! -

- Überprüfen Sie die Verfügbarkeit eines Token-Servers, indem Sie den entsprechenden Link anklicken. Wenn direkt eine Versionsnummer angezeigt wird, ist er aktiv. -

- Eine Anleitung zum Betreiben eines eigenen Token-Servers finden Sie hier. -

- -
- -
- - diff --git a/docs/de_support.html b/docs/de_support.html deleted file mode 100644 index 0a794957..00000000 --- a/docs/de_support.html +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - - Dayon! - Fernwartung für Familie und Freunde - - - - - - - -
-
- EN - FR - SV - 汉语 -
- -
-

Hilfe

-

- Für Rückmeldungen bin ich Ihnen sehr dankbar! Posten Sie eine Frage oder erfassen Sie ein Issue auf GitHub. -

- -

Dayon! Heimverzeichnis

-

- Das Verzeichnis .dayon wird im Standardbenutzerverzeichnis des eingelogten Benutzers oder via - JAVA-Property definierten Benutzerverzeichnis user.home erstellt und enthält nebst den - gespeicherten Einstellungen auch die Logdatei(en). -

- -

CRC Checksumme

-

- Auf der Seite des Assistierten wird der Bildschirm in Kacheln - genannte Bereiche aufgeteilt. Bloss veränderte Kacheln werden über das Netzwerk zum - Assistenten gesendet. Um zu entscheiden ob sich eine Kachel seit der letzten - Erfassung verändert hat, wird ein CRC-Code berechnet (ein eindeutiger - Wert für die in einer Kachel enthaltenen Pixel). Dieses Verfahren ist - hinsichtlich der Verarbeitungsgeschwindigkeit nicht die optimale - Lösung. Es kann mitunter vorkommen, dass einige veränderte - Kacheln nicht an den Assistenten gesandt werden. -

- -

- Bis jetzt konnte rein durch intensives Testen Verfälschungen von - einigen Pixeln entdeckt werden. Visuell konnte bis anhin nichts - ernsthaft störendes festgestellt werden. Sollte in der Praxis in - dieser Hinsicht Mal etwas aus dem Ruder laufen, kann entweder die - Applikation des Assistierten neu gestartet, oder dessen Puffer zurückgesetzt werden. - (Abfallkübelsymbol). -

- -

Zertifikatsfingerabdrücke

-

- Um "Men in the Middle"-Angriffe zu verhindern, werden die Zertifikatsfingerabdrücke der beiden verbindenden Seiten angezeigt. - Die beiden Fingerabdrücke müssen übereinstimmen - tun sie es nicht, dann ist etwas Merkwürdiges im Gange. - Diese zusätzliche Sicherheitsfunktion wurde mit Version 13 von Dayon eingeführt. -

-

- Certificate Fingerprints -

-

- Achtung: Um die Verbindung mit älteren Clients (vor Version 13) zu ermöglichen, muss der Kompatibilitätsmodus - compatibility aktiviert werden.
- Dies ist eine Übergangslösung, bitte aktualisieren Sie die Assistierten so bald wie möglich. -

- -

Schematische Darstellung des Verbindungsaufbaus

-

- Dayon! connection diagram -

-
- -
- - diff --git a/docs/download.html b/docs/download.html deleted file mode 100644 index f6801440..00000000 --- a/docs/download.html +++ /dev/null @@ -1,316 +0,0 @@ - - - - - - - - - Dayon! - Remote assistance for your family and friends - - - - - - - -
-
- DE - FR - SV - 汉语 -
- -
-

Download

-

- Windows 10/11 - users can most conveniently install the app directly from the Microsoft Store. -

- -

- - English badge - -

- -

- Independently updated packages with broad hardware support are available in the Snap Store, - on Flathub and via - ppa:regal/dayon. -

- -

- - Get it from the Snap Store - -

- - Get it from the Flathub - -

- -

- Otherwise you can download the latest installation packages for your platform from GitHub - or SourceForge. -

- -

- - Download Dayon! (active) - -

- -

- Windows: - Two installers are available and the installation should be straightforward. One package comes bundled with an OpenJDK 11 (LTS) based - JRE and one without. The one with included JRE is for 64bit versions of Windows only. -
- Since release 1.9 there also exist two separate "quick launch" versions. One for the assistant and one for the assisted part. These - two portable versions do not require to be installed. In order to avoid possible problems with user account control in these versions, - it is recommended to start the assisted with administrator rights. -

- -

- Debian, Ubuntu and derivates: - So that you don't have to manually keep Dayon! up to date, installing it via ppa:regal/dayon - or as a snap is recommended. -
- PPA: - sudo add-apt-repository ppa:regal/dayon, sudo apt-get update and finally sudo apt-get install dayon. -
- Snap: sudo snap install dayon. Alternatively, you can install downloaded .deb - packages by tipping the command sudo dpkg -i dayon*.deb in a terminal. -

- -

- Linux: either install the independently updated snap app via - Snap Store or via sudo snap install dayon -
- Alternatively, unpack the downloaded .tgz package via tar xzvf. - Run the script setup.sh, located in the target directory. The location of the installed - JRE/JDK is going to be detected automatically. It is not bundled in the tgz. If it should for whatever reason fail to do so, then you can - set the JAVA_HOME in (dayon.sh) manually. - Note that the .tgz packages have only been tested on various Debian and Ubuntu versions. -

- -

- macOS/OS X: - Open the .dmg package and drag the Assisted or the Assistant onto the program icon. - If necessary, a suitable Java JRE 11 (or newer) must be installed.
- Alternatively: unpack the .tgz package to a location of your choice. For more convenience you may - want to create an alias for dayon_assisted.sh and dayon_assistant.sh and copy them to your desktop. (Requirement: JRE 11 or newer also installed). -
- Important: From macOS Catalina and newer, you must explicitly grant screen capture permission: - System Preferences > Security & Privacy > Privacy > Screen Recording -

- -

Change log

-

- Dayon! v14 Candid Clover (March 7th, 2024) - * -

- - -

Dayon! v13 Beard Butter (November 5th, 2023)

- - -

Dayon! v12 Adorable Asteroid (April 16th, 2023)

- - -

Dayon! v11 Ballsy Beaver (October 31th, 2021)

- - -

- Dayon! v1.10 Lucky Lobster (March 27th, 2020) - * -

- - -

- Dayon! v1.9 Promiscuous Potato (December 11th, 2019) - * -

- - -

- Dayon! v1.8 Truganini (May 18th, 2019) - * -

- - -

- Dayon! v1.7 Tesler (February 21th, 2019) - * -

- - -

- Dayon! v1.6 Solenodon (December 19th, 2018) - * -

- - -

- Dayon! v1.5 Pendragon (May 5th, 2017) - * -

- - -

- Dayon! v1.4 Skytale (January 3rd, 2017) - * -

- - -

- Dayon! v1.3 Phoenix (December 10th, 2016) - * -

- - -

- Dayon! v1.2 (January 3rd, 2009) - * -

- - -

- Dayon! v1.1 (December 24, 2008) - * -

- - -

Dayon! v1.0 (December 4, 2008)

- - - - * Major versions are not compatible between each other - -

-

- Legacy releases (v1.0 to v1.2) can be downloaded - here. -

-
- -
- - diff --git a/docs/favicon.ico b/docs/favicon.ico index 2d224f0e..e9cc2723 100644 Binary files a/docs/favicon.ico and b/docs/favicon.ico differ diff --git a/docs/fr_download.html b/docs/fr_download.html deleted file mode 100644 index 2e55b4c8..00000000 --- a/docs/fr_download.html +++ /dev/null @@ -1,311 +0,0 @@ - - - - - - - - - Dayon! - Assistance à distance pour votre famille et vos amis - - - - - - - -
-
- DE - EN - SV - 汉语 -
- -
-

Télécharger

-

- Les utilisateurs de Windows 10/11 - peuvent charger l'application directement depuis le Microsoft Store. -

- -

- - French badge - -

- -

- Des packages mis à jour indépendamment avec un large support matériel sont disponibles dans le Snap Store, - sur Flathub et via - ppa:regal/dayon. -
-

- -

- - Get it from the Snap Store - -

- - Get it from the Flathub - -

- -

- Sinon, vous pouvez télécharger les derniers packages d'installation pour votre plate-forme depuis - GitHub ou SourceForge. -

-

- - Download Dayon! (active) - -

- -

- Windows : - Deux programmes d'installation sont disponibles et l'installation devrait être assez directe. - Un paquet est livré avec un JRE à base de l'OpenJDK 11, l'autre sans. Ce avec JRE peut seulement être utilisé avec des versions de Windows de 64bit. -
- Depuis la version 1.9 il existe également deux versions distinctes de «lancement rapide» pour l’assistant et l’assisté. Ces deux versions - portables ne nécessitent pas d'installation. Afin d'éviter d'éventuels problèmes de contrôle de compte d'utilisateur dans ces versions, nous - vous recommandons de démarrer l'assisté avec les droits d'administrateur. -

- -

- Debian, Ubuntu et derivates : pour que vous n'ayez pas à tenir Dayon! à jour manuellement, en - l'installant via ppa:regal/dayon ou car un - snap est recommandé. -
- PPA : - sudo add-apt-repository ppa:regal/dayon, sudo apt-get update et enfin sudo apt-get install dayon. -
- Snap : sudo snap install dayon. Sinon, vous pouvez installer le package téléchargé - en exécutant sudo dpkg -i dayon*.deb. -

- -

- Linux : installez l'application snap mise à jour indépendamment via - Snap Store ou via sudo snap install dayon. -
- Alternativement, décompressez le .tgz package téléchargé via tar xzvf. Exécutez le script shell - setup.sh dans le répertoire cible. La location du JRE/JDK installé va être détecté automatiquement. - Il n'est pas livré dans le tgz. Si, pour quelque raison que ce soit, il ne le fasse pas, vous pouvez configurer JAVA_HOMEdans (dayon.sh) manuellement. - Notez que, j'ai testé ceci sur Debian et Ubuntu seulement. -

- -

- macOS/OS X : - Ouvrez le package .dmg et faites glisser l'Assistant ou l'Assistant sur l'icône du programme. - Si nécessaire, un Java JRE 11 approprié (ou plus récent) doit être installé.
- Alternativement : décompressez le package .tgz à une location de votre choix. Pour plus de commodité, créez - un alias pour dayon_assisted.sh et dayon_assistant.sh et copiez-les sur votre bureau. (Exigence : JRE 11 ou version ultérieure également installée). -
- Important : depuis macOS Catalina et versions ultérieures, vous devez explicitement accorder l'autorisation de capture d'écran : - Préférences système > Sécurité amp; confidentialité > Confidentialité > Capture d'écran -

- -

Journal des modifications

-

- Dayon! v14 Candid Clover (7 mars 2024) - * -

- - -

Dayon! v13 Beard Butter (5 novembre 2023)

- - -

Dayon! v12 Adorable Asteroid (16 avril 2023)

- - -

Dayon! v11 Ballsy Beaver (31 octobre 2021)

- - -

- Dayon! v1.10 Lucky Lobster (27 mars 2020) - * -

- - -

- Dayon! v1.9 Promiscuous Potato (11 décembre 2019) - * -

- - -

- Dayon! v1.8 Truganini (18 mai 2019) - * -

- - -

- Dayon! v1.7 Tesler (21 février 2019) - * -

- - -

- Dayon! v1.6 Solenodon (19 décembre 2018) - * -

- - -

- Dayon! v1.5 Pendragon (5 mai 2017) - * -

- - -

- Dayon! v1.4 Skytale (3 janvier 2017) - * -

- - -

- Dayon! v1.3 Phoenix (10 décembre 2016) - * -

- - -

- Dayon! v1.2 (3 janvier 2009) - * -

- - -

- Dayon! v1.1 (24 décembre 2008) - * -

- - -

Dayon! v1.0 (4 décembre 2008)

- - - * Les versions majeures ne sont pas compatibles entre elles -

- Les anciennes versions (v1.0 à v1.2) peuvent être téléchargées depuis ici. -

-
- -
- - diff --git a/docs/fr_index.html b/docs/fr_index.html deleted file mode 100644 index d0331826..00000000 --- a/docs/fr_index.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - - Dayon! - Assistance à distance pour votre famille et vos amis - - - - - - - -
-
- DE - EN - SV - 汉语 -
- -
-

Service d'Assistance à Distance

-
-

- Dayon! est un logiciel libre et multi-plateforme (JAVA) qui permet - de visualiser et controller un ordinateur à distance. D'un certain - coté, il est donc très similaire aux solutions de bureau à distance - (c'est-à-dire, remote desktop solutions) et de téléassistance. -

- -

- Mais je pense qu'il possède quelques caractéristiques qui le rendent utile. -

-

- Vous trouverez plus d'information sur cette page. -

-
- -

Caractéristiques

-
-

Installation Facile

-

- Dayon! est avant tout dédié aux personnes novices dans le monde des - ordinateurs. Sur la machine dont on veut visualiser l'écran à - distance, il n'y pas de configuration réseau à faire (c'est-à-dire, pare-feu, - routeur, NAT, etc..). Dayon! se comporte alors comme un client qui - se connecte vers l'extérieur. -

- -

Réseau à Faible Débit

-

- Dayon! transmet des images compressées de 256 niveaux de grix pour - minimiser au maximum l'utilisation du réseau. La qualité de ces - images est largement suffisante pour visualiser l'écran à distance - et expliquer les différents menus, icônes et découvrir les - différentes configurations de l'ordinateur distant. -

-
- -

Status (14)

-

- Depuis la version 1.9 (Promiscuous Potato), une version portable - "lancement rapide" est disponible en plus du programme - d'installation classique. Il existe deux binaires Windows "quick - launch" distincts, un pour l'assistée et un pour l'assistant. Ils sont - appelés "lancement rapide", car ils permettent de lancer la partie - assistée ou assistante sans installation (ils nécessitent cependant la présence d'un JRE). - Ils sont 100% compatibles avec les versions classiques de Dayon!. - Depuis la version 12 (Adorable Asteroid), des versions portables similaires - sont également disponibles pour Linux. -

- En raison du manque de matériel, je n'ai pu tester la fonction de - transfert du presse-papiers que sous Windows 10 et 11, Debian et Ubuntu. Les - commentaires des utilisateurs de macOS seraient les bienvenus ! -

- -

Pourquoi Dayon!

-

- Marc Polizzi avait développé Dayon! pour aider ces parents et amis en - Europe à utiliser leur ordinateur, quand il vivait aux Philippines. -

-

- Il ne voulait pas qu'ils installent leur pare-feu et le routeur - DSL/câble et NAT et tout ce qui est nécessaire pour qu'il puisse - accéder à leur machine à l'aide d'une connexion de bureau à distance. - Donc, il a décidé de mettre en œuvre quelque chose de très simple dans - son temps libre et en même temps prendre en compte une faible bande - passante et un réseau de haute latence. -

- -

- Quelques années plus tard, j'ai trouvé ce programme sur - Sourceforge - quand je cherchais une solution d'assistance à distance - multi-plateforme. En utilisant Dayon! pour aider les utilisateurs - exécutant Windows 7 et plus ultérieures, j'ai réalisé qu'il avait - quelques failles graves. Comme la dernière version (1.2) a été publié - au début de 2009, j'ai décidé de contacter l'auteur. Avec sa - permission, j'ai déplacé le code source du projet vers - GitHub - à la fin de 2016 et j'ai repris le développement. -

- -

- À propos, Dayon! veut dire Entrez ! en Visayas - un dialecte du coin aux Philippines. -

-

License

-

- Dayon! est un programme libre utilisant une license - GPL. - - Dayon! (active) Reviews - -

-
- -
- - diff --git a/docs/fr_privacy.html b/docs/fr_privacy.html deleted file mode 100644 index 63000ac3..00000000 --- a/docs/fr_privacy.html +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - Dayon! - Assistance à distance pour votre famille et vos amis - - - - - - - -
-
- DE - EN - SV - 汉语 -
- -
-

Déclaration de protection des données

-

100% de confidentialité

-

- Dayon! est un programme open source entièrement gratuit, disponible pour des audits de sécurité publics. - Toutes les communications sont cryptées par défaut. - Le programme ne collecte ni ne partage aucune donnée personnelle identifiable avec des tiers. -

-

Utilisation facultative des jetons d'accès

-

- L'utilisation des jetons d'accès est une fonction facultative qui facilite la connectivité. - Une approche fondée sur les risques a été adoptée pour garantir des risques minimaux pour la vie privée lors de l'utilisation de cette fonction : - La configuration par défaut de cette fonctionnalité repose sur l'utilisation d'un serveur des jetons d'accès tiers. - L'adresse IP d'un utilisateur est stockée dans le serveur jusqu'à 7 jours après sa dernière utilisation. Le seul but est de permettre aux deux parties de se connecter. - Le serveur est hébergé en Suisse. Le responsable du traitement des données est l'opérateur. - Cette fonction peut être configurée pour utiliser un serveur auto-hébergé à la place, afin d'éviter de devoir partager des données avec un serveur tiers. -

-
- -
- - diff --git a/docs/fr_quickstart.html b/docs/fr_quickstart.html deleted file mode 100644 index ce6dd871..00000000 --- a/docs/fr_quickstart.html +++ /dev/null @@ -1,379 +0,0 @@ - - - - - - - - - Dayon! - Assistance à distance pour votre famille et vos amis - - - - - - - -
-
- DE - EN - SV - 汉语 -
- -
-

Premier Pas

-

- Typiquement, l'assistant discute avec l'assisté en utilisant Jitsi, le téléphone, - son IM préféré, ou n'importe quel autre outil. Ensuite, en démarrant Dayon! il peut visualiser en direct - l'écran de l'ordinateur de l'assisté. -

- -

- Notez que les images sur cette page correspondent à la version anglaise, mais que l'application elle-même - est complètement traduite. Je pense que cela ne devrait pas vous empêcher de comprendre l'essentiel. -

- -

- Attention : cette documentation fait référence à la dernière version du programme. -

-

- -

Assistant  Mise en route coté assistant

- -

- Dayon! assistant agit comme une application serveur typique (l'assisté va se connecter) et en tant que tel, vous devez configurer votre réseau - pour le rendre visible du monde extérieur.

- Par défaut, le serveur écoute le port 8080, mais vous pouvez le modifier si nécessaire. - Depuis la version 12, Dayon! crée indépendamment une règle de transfert de port correspondante. La condition préalable est que UPnP soit activé. - Sinon, il sera toujours nécessaire de rediriger le port (TCP) via NAT sur le routeur vers l'ordinateur correspondant. -

- Consultez portforward.com pour un guide étape par étape des modèles de routeur les plus courants. -

- -

- Optional : Ajuster le port pour les connexions entrantes : (à gauche avec UPnP, à droite sans) -

- -

- Dayon! Assistant : Network Settings avec UPnP - Dayon! Assistant : Network Settings sans UPnp -

- -

Générer et copier des jetons

- -

- Générez un jeton d'accès en cliquant sur la clé : -

- -

- Dayon! Assistant : Create Token -

- -

- Copiez le code d'accès généré dans le presse-papiers d'un simple clic de souris : -

- -

- Dayon! Assistant : Copy Token -

- -

- C'est tout - communiquez ce code d'accès à l'assisté par courrier, messagerie instantanée ou téléphone. -

- -

- Pour les impatients :Ici, - vous apprendrez comment faire en sorte que l'assistant écoute la connexion entrante. -

- -

Variante alternative : connexion sans jeton d'accès

- -

- Si vous ne souhaitez pas utiliser de jeton, vous devez déterminer l'adresse IP publique de votre ordinateur. - L'assisté peut alors s'y connecter. Pour cela, cliquez sur Trouver mon adresse IP (publique). - Vous pouvez également simplement utiliser l'adresse IP privée pour tester sur le LAN : -
- Dayon! Assistant : Network IP Addresses -

- -

- Comme vous pouvez le voir sur l'image suivante, le menu contient différentes actions vous permettant de copier - dans le clipboard l'IP Address & Port Number. - Il vous sera ainsi facile de coller dans une session Jitsi (ou autre) ou dans un message email. -

- -

- Dayon! Assistant : Network IP Address Actions -

- -

- - Noter que cette addresse IP n'est pas requise pour l'assistant. En effet, l'application écoute sur toutes les interfaces réseaux - disponibles ; mais la personne assisté va avoir besoin de ces informations. - -

- -

Prise en route

- -

- C'est à peu près tout. Après un clic sur le bouton play (le premièr à gauche) - l'assistant est prêt à recevoir des données : -

- -

- Dayon! Assistant : Start -

- -

- Vous pouvez maintenant demander à l'assisté de se connecter. Vous serez alors promptement requis d'accepter une nouvelle connexion : -

- -

- Dayon! Assistant : Incoming Connection -

- -

- Vous êtes maintenant connecté et vous surveillez l'ordinateur distant. - Veuillez comparer les empreintes digitales de l'assistant et de l'assisté. -
- Attention : s'ils ne correspondent pas, la connexion n'est pas fiable ! -

- -

-
-

- -

Assisted  Mise en route coté assisté

- -

- Dayon! assisté se comporte comme un client qui appelle le monde extérieur ; - à ce titre, il n'y a pas de configuration réseau à faire. -

- -

- Il faut télécharger et installer Dayon!. Ensuite, démarrez Dayon! - (vous devriez avoir un raccourci sur le bureau) et cliquez sur l'icône de lecture. -

- -

- Dayon! Assisted : Ready -

- -

- Saisissez le code d'accès communiqué par l'assistant et validez par OK :
-

- -

- Dayon! Assistied : Token
- (si vous vous êtes déjà connecté à cet assistant récemment, vous pouvez laisser le champ vide) -

- -

Variante alternative : connexion sans jeton d'accès

- -

- Entrez l'addresse IP et le numéro de port communiqué par l'assistant cliquez sur le bouton "OK" :
-

- -

- Dayon! Assisted : Network
- (les deux champs de saisie peuvent être effacés en les double-cliquant) -

- -

- Vous serez alors promptement connecté à l'assistant qui sera déjà en train de regarder votre écran. Bonne session! -

-

- -

- Dayon! Assistant : Running -

- -

- Remarque : Si vous ne parvenez pas à vous connecter en suivant les instructions ci-dessus, - vous devez vérifier les paramètres. -

- -

Gérer la séance

- -

- Si le bureau de l'assisté ne rentre pas dans votre fenêtre, il peut être réduit : -

- -

- Dayon! Assistent : Fit Screen Toggle -

- -

- En cliquant sur le bouton open lock directement à sa droite, - vous pouvez conserver le rapport hauteur/largeur de l'écran assisté. Veuillez noter que cette fonction n'a aucun effet sur l'affichage lorsque la fenêtre est agrandie. -

- -

- Par default, le mode de contrôle à distance n'est pas activé ; vous pouvez l'activer avec l'icône suivante : -

- -

- Dayon! Assistant : Control Toggle -

- -

Transfert de presse-papiers

-

- En cliquant sur le bouton haut ou bas, le presse-papiers de l'assistant peut être transféré vers - l'assisté (haut) ou le presse-papiers de l'assisté vers l'assistant (bas). -

- -

- Dayon! Assistant : Clipboard transfer -

- -

-

Actuellement pris en charge sont :

- - -

-

Transmettre la pression de la touche Windows ou Cmd

-

- Pour transmettre la pression de la touche *Windows, cliquez sur le symbole Windows dans le panneau de - configuration de l'assistant : -

- -

- Dayon! Assistant : Windows Key -

- -

- La touche reste enfoncée jusqu'à ce que vous cliquiez à nouveau sur le symbole. Cela vous permet d'envoyer des - raccourcis clavier Windows.
- Si vous avez besoin, par exemple, de réduire toutes les fenêtres sur l'assisté, vous cliquez sur - le symbole Windows, appuyez sur la touche M, puis cliquez à nouveau sur le symbole Windows. -

- -

- *Remarque : Si l'assisté est exécuté sur macOS, la touche/le bouton Cmd est affiché/transféré à la place. -

- -

-

Transmettre la pression de la touche Ctrl

-

- Alors que la plupart du temps, la touche Ctrl est transmise à l'assisté comme n'importe quelle autre frappe, - il y a des situations où ce n'est pas le cas. Par exemple la combinaison Ctrl + Alt + Suppr est généralement - "capturé" par le système d'exploitation de l'assistant et donc non transmis. - Dans de telles occasions, le bouton [Ctrl] à côté du bouton Windows dans le panneau de configuration des assistants devient pratique. - Le comportement est le même qu'avec le bouton Windows : la touche reste enfoncée jusqu'à ce que vous cliquiez à nouveau sur le bouton. -
- Donc pour envoyer la combinaison Ctrl + Alt + Suppr à l'assisté, vous devez d'abord cliquer sur le bouton [Ctrl], - puis appuyez simultanément sur les touches Alt et Suppr, relâchez-les et enfin, cliquez à nouveau sur le bouton [Ctrl]. -

- Attention : En raison de restrictions du système d'exploitation, la combinaison Ctrl + Alt + Suppr - ne fonctionne pas sur les assistés qui fonctionnent sous Windows !
- Utilisez plutôt la combinaison Windows + R qui offre des fonctionnalités similaires. -

- -

Prendre une capture d'écran à la côte de l'assisté

-

- Cliquez sur le bouton "Caméra" - la capture d'écran sera prise directement sans autre question. - Le graphique capturé se retrouve dans le presse-papier de l'assisté, d'où il peut être transféré à l'assistant. -

- -

- Dayon! Assistent : Take screenshot -

- -

- La fonction « Réinitialiser l'enregistrement d'écran » (symbole de la poubelle) supprime les données d'écran transmises et les recharge depuis l'assistant. -

- -

Démarrez une réunion en ligne pour discuter en face à face

-

- Cliquez sur l'empreinte digitale du certificat de l'assisté et de l'assistant pour démarrer une réunion en ligne conjointe dans Jitsi Meeting. -

- -

- Dayon! start chat -

- -

Compteurs de statistiques

- Dayon! Assistant : Statistics -

- La barre d'état de l'assistant affiche, en plus de la disposition du clavier, les compteurs suivants : -

-
    -
  1. Bande passante réseau
  2. -
  3. Compression Ratio : combien de fois la capture initiale (diff only) a été comprimé
  4. -
  5. - Number of Tiles : le nombre de carreaux étant également transmis sur le réseau ou servis depuis le cache. -
  6. -
  7. - Number of Skipped Capture : le nombre de captures d'écran qui ont été - ignorées En raison d'un taux trop élevé (c'est-à-dire, une valeur de - cotation faible) pour les CPU. Pour minimiser cette, vous devez - ralentir le taux de capture en utilisant une valeur plus grande. -
  8. -
  9. - Number of Merged Capture : le nombre de captures d'écran fusionnées - avant d'être transmis. Ceci est dû à un taux de capture trop élevé - pour le courant méthode de compression. Pour minimiser ce nombre, - vous devez ralentir la capture taux et/ou changer la méthode de - compression en utilisant un plus rapide. -
  10. -
  11. Utilisation de la mémoire
  12. -
  13. Durée de la session d'assistance active ou de la dernière
  14. -
- -

- C'est tout ! Vous trouverez plus d'information sur la page paramètres. -

-
- -
- - diff --git a/docs/fr_settings.html b/docs/fr_settings.html deleted file mode 100644 index dfdce578..00000000 --- a/docs/fr_settings.html +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - - - - Dayon! - Assistance à distance pour votre famille et vos amis - - - - - - - -
-
- DE - EN - SV - 汉语 -
- -
-

Paramètres

- - -

Assistant  Coté assistant

- -

- Cette forme vous permet de configurer la façon dont l'écran est capturé ; vous pouvez configurer - l'interval de temps (en milliseconde) entre deux captures (aka. tic-tac) ainsi que le nombre de niveaux de gris. - Moins de niveaux veut dire moins d'information à transmettre sur le réseau (au détriment de la qualité des images). - À partir de Dayon ! 15, les couleurs sRGB peuvent également être utilisées comme alternative. Dans ce cas, le nombre de niveaux de gris est ignoré. - Veuillez noter que l'utilisation des "Couleurs réelles" consomme plus de bande passante et plus de RAM du côté de l'assisté. -

- -

- Dayon! Assistant : Capture Settings -

- -

- Vous pouvez ensuite configuer la méthode de compression ; deux méthodes sont disponibles : - ZIP et XZ. XZ va donner les meilleurs résultats, mais demandent plus de CPU et memoire ; elle est - bien plus compliquées que ZIP et est de plus implémentées en JAVA (ZIP étant implémenté en code natif dans le JDK). -

- -

- En plus de la compression, un cache est utilisé pour ne pas envoyer plusieurs fois des images identiques - comme, quand on ouvre et ferme un menu (i.e., l'image sous le menu n'a pas besoin d'être renvoyée). Pour cela, l'écran est divisé - en carreaux, chacun pouvant être caché. Vous devez définir le nombre maximum de carreaux dans le cache. - Noter que des carreaux représente 32x32 points de 256 niveaux de gris, ce qui fait 1 KO. -

- -

- Dayon! Assistant : Compression Settings -

- -

-
-

- -

Assisted  Coté assisté

- -

Paramètres UAC

-

- Pour que l'assistant puisse voir toutes les boîtes de dialogue du système, les paramètres UAC (User Account Control) doivent être ajustés sous Windows. - Par souci de simplicité, la boîte de dialogue des paramètres UAC est accessible directement via l'interface utilisateur assisté. - Le deuxième réglage le plus bas s'est avéré efficace. -

- -

- Dayon! Assisted: UAC -

- -

Paramètres de connexion avancés

-

- Dayon! Assisted: Token server -

- -

- Dans la boîte de dialogue des paramètres réseau de l'assisté, vous pouvez configurer manuellement le numéro de port et l'adresse IP de l'assistant si vous souhaitez vous connecter sans jeton.
- Vous pouvez également activer ou désactiver la connexion automatique. Si cette option est activée, au prochain démarrage de l'assistant, il établira une connexion directe avec l'hôte spécifié sans autre invite. - Le serveur de jetons à utiliser peut aussi être configuré ici. Le serveur de jetons standard ou un serveur personnalisé peut être défini.
- Une liste des serveurs de jetons disponibles se trouve au bas de cette page.
- Important : Assurez-vous d'utiliser le même serveur de jetons du côté assisté que l'assistant ! -

- -

Connexion automatique de l'assisté via les paramètres de ligne de commande

- -

- Le nom d'hôte ou l'adresse IP et le port de l'assistant peuvent être transmis via des paramètres de ligne de commande ; ah=hôte ou adresse IP et ap=numéro de port : -

- - - -

- Si l'assisté est démarré avec ces paramètres, il se connecte directement à l'hôte spécifié "an.example.com" et au port "4242" sans requête. -

- -

Dayon ! Configurer via le fichier de configuration

-

- Depuis la version v11.0.5, les paramètres de connexion peuvent être stockés dans un fichier YAML. -

- Cela permet d'écraser les paramètres utilisateur, car la configuration est toujours lue et évaluée à partir du YAML au démarrage. - Bien que les utilisateurs puissent apporter des modifications au sein de l'application, celles-ci ne sont conservées jusqu'au prochain - lancement que si une configuration YAML est présente. -

- Le principal cas d'utilisation des configurations YAML concerne les organisations qui souhaitent utiliser un serveur de jetons - auto-hébergé au lieu du serveur de jetons public, ou qui souhaitent spécifier un hôte spécifique auquel l'assisté doit se connecter automatiquement au démarrage. -

- La structure du fichier YAML de l'assisté est extrêmement simple : -

-
-host: "an.example.com"
-port: 8080
-# autoConnect: false
-# tokenServerUrl: "https://example.org/token/"
-
- -

-

-

- -

- L'assistant peut également être préconfiguré à l'aide d'un fichier YAML : -
-

- - Ces fichiers YAML peuvent être appelés assisted.yaml et - assistant.yaml soit à Dayon ! répertoire personnel, dans le répertoire utilisateur, - ou stocké dans le même répertoire que le fichier .jar ou .exe. - Cet ordre correspond également à la priorité avec laquelle ils seront pris en compte si plusieurs configurations existent. (le premier gagne)
-

- -

Serveurs de jetons publics

- -

- Vous trouverez ci-dessous une liste des serveurs de jetons publics disponibles et dont l'utilisation est gratuite.
- Voulez-vous exécuter votre propre serveur de jetons et souhaitez-vous l'ajouter à la liste ? Faites-le-moi savoir ! -

- Vérifiez la disponibilité d'un serveur de tokens en cliquant sur le lien correspondant. Si un numéro de version est affiché directement, il est actif. -

- Les instructions pour exécuter votre propre serveur de jetons peuvent être trouvées ici. -

- -
- -
- - diff --git a/docs/fr_support.html b/docs/fr_support.html deleted file mode 100644 index adaaa267..00000000 --- a/docs/fr_support.html +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - Dayon! - Assistance à distance pour votre famille et vos amis - - - - - - - -
-
- DE - EN - SV - 汉语 -
- -
-

Aide

-

- Vos commentaires et réactions sont très bienvenus - vous pouvez ouvrir une question sur GitHub. -

- -

Dayon! Répertoire de base

-

- Le répertoire .dayon est créé dans le répertoire de base par défaut de l'utilisateur - connecté ou dans le répertoire référencé par la propriété JAVA user.home - et contient les préférences utilisateur enregistrées et fichier(s) de journal par défaut. -

- -

Somme de contrôle CRC

-

- Sur le côté de l'assistée, l'écran est divisé en différentes zones appelées tuiles. - Seules les tuiles qui ont été modifiées depuis la capture précédente sont envoyées sur le Côté assistant. - Pour déterminer si une tuile est différente, je suis en train de calculer un code CRC (C'est-à-dire, - une valeur entière unique représentant les pixels de la tuile) qui n'est pas parfaite Par souci de rapidité. - Il se peut donc que certaines tuiles changées ne soient pas envoyées à l'assistant. -

- -

- Jusqu'à présent, j'ai détecté ce problème lors de tests forts pour très peu de pixels. Visuellement, je n'ai - rien remarqué de sérieux. Mais au cas où les choses vont fou, vous pouvez ensuite redémarrer - L'aide ou avant d'essayer l'action reset (l'icône poubelle) - Qui devrait effacer toutes les données en cache et renvoyer une capture plein écran à partir de zéro. -

- -

Empreintes des certificats

-

- Pour éviter les attaques "Men in the Middle", les empreintes digitales des certificats des deux côtés qui se connectent sont affichées. - Les deux empreintes digitales doivent correspondre - si elles ne correspondent pas, cela signifie que quelque chose d'étrange est en cours. - Cette fonction de sécurité supplémentaire a été introduite dans la version 13 de Dayon. -

-

- Certificate Fingerprints -

-

- Attention : Pour garantir la connectivité avec les anciens clients antérieurs à la version 13, le mode de compatibilité - compatibilité doit être activé.
- Il ne s'agit que d'une solution provisoire, veuillez informer vos clients dès que possible. -

- -

Etablissement de la connexion

-

- Dayon! connection diagram -

-
- -
- - diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index de73e28c..00000000 --- a/docs/index.html +++ /dev/null @@ -1,149 +0,0 @@ - - - - - - - - - Dayon! - Remote assistance for your family and friends - - - - - - - -
-
- DE - FR - SV - 汉语 -
- -
-

Remote Assistance Service

-
-

- Dayon! is an open-source and cross-platform (JAVA) solution that - allows watching and controlling a remote computer. In this sense, it - is very much similar to existing remote desktop solutions. -

- -

But I guess it's got some features that makes it valuable.

-

- You'll find more details on this page. -

-
- -

Features

-
-

Check mark Easy Setup

-

- Dayon! is dedicated to people who are quite new in the computer - world. There's no need to set up the network (i.e., no firewall - setup, no router configuration, no NAT setup) on their computer. - Dayon! is acting there as a client connecting to the monitoring - computer. -

- -

Check mark Low Network Bandwidth

-

- Dayon! is sending compressed and cached gray (up to 256 levels) - pictures to minimize the network usage offering as much as possible - a real-time experience over the Internet. Those pictures are far - enough for monitoring and explaining the different menus, icons and - discovering the computer setup, etc... -

-
- -

Status (14)

-

- Since release 1.9 (Promiscuous Potato), a portable "quick launch" - version is available in addition to the conventional installation - program. There are two separate "quick launch" Windows binaries, one - for the assisted and one the assistant. They are called "quick - launch", because they allow the assisted or assistant part to be run - without prior installation (require the presence of an JRE, however). - They are 100% compatible with the conventional Dayon! Versions. - Since release 12 (Adorable Asteroid), similar portable versions are - available for Linux as well. -

- Due to the lack of Apple hardware, the clipboard transfer feature - could only be tested with Windows 10 and 11, Debian and Ubuntu - Feedback - from macOS users would be very welcome! -

- -

Rational

-

- Marc Polizzi has developed Dayon! when he was living in the - Philippines and was communicating with his family and friends back in - Europe over Skype. -

- -

- He didn't want them to set up their firewall, DSL/cable router and NAT - and whatever else required for him to access their computer over a remote - desktop connection. So he decided to implement something very simple in - his spare time while also considering a low-bandwidth, high-latency network. -

- -

- Several years later, I found this program on - Sourceforge - when I was looking for free cross-platform remote assistance solution. - While using Dayon! to assist users running Windows 7 and later, I - realised that it had some serious flaws. As the latest version (1.2) - has been released back in early 2009, I decided to contact the author. - With his consent I moved the source code of the project to - GitHub - in late 2016 and took over the further development. -

- -

- By the way, Dayon! means "Come in!" in Visayas - a local Philippine dialect. -

-

License

-

- This program is a free software licensed under the - GPL license. - - Dayon! (active) Reviews - -

-
- -
- - diff --git a/docs/intro.png b/docs/intro.png deleted file mode 100644 index 6d4f586c..00000000 Binary files a/docs/intro.png and /dev/null differ diff --git a/docs/privacy.html b/docs/privacy.html deleted file mode 100644 index 727c4627..00000000 --- a/docs/privacy.html +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - Dayon! - Remote assistance for your family and friends - - - - - - - -
-
- DE - FR - SV - 汉语 -
- -
-

Privacy Statement

-

100% privacy

-

- Dayon! is an absolutely free open source program, available for public security audits. - All communications are encrypted by default. - The program does not collect or share any Personal Identifiable Data (PID) with third parties. -

-

Optional use of Tokens

-

- An optional function for easy connectivity is the use of Tokens. - A risk-based approach has been taken to ensure minimal privacy risks while using the function: - The default configuration for that functionality relies on the use of a third party Token server. - The IP address of a user is stored in the server up to 7 days after it is last used. The only purpose is to enable the two parties to connect. - The server is hosted in Switzerland. Responsible data processor is its operator. - This function can be configured to use a self-hosted server instead, to avoid having to share data with a third party server. -

-
- -
- - diff --git a/docs/quickstart.html b/docs/quickstart.html deleted file mode 100644 index 3a3b1c38..00000000 --- a/docs/quickstart.html +++ /dev/null @@ -1,399 +0,0 @@ - - - - - - - - - Dayon! - Remote assistance for your family and friends - - - - - - - -
-
- DE - FR - SV - 汉语 -
- -
-

Quick Start

-

- Typically, the assistant is communicating with the assisted using Jitsi, the phone, - their favorite IM, or whatever tool they like. Then starting Dayon! allows for watching live the - assisted computer screen. -

- -

- In this documentation, the screenshot show the English localisation of the app. - The application itself is also completely localised in French, German, Italian, Spanish, Swedish, Russian, Turkish and Chinese (simplified). - It will fall back to English, if the configured user language is none of the above. -

- -

- Caution: This documentation refers to the most recent program version. -

-

- -

Preparing & Connecting

- -

Assistant Set up the Assistant computer

- -

- Dayon! Assistant is acting as a typical server application (the assisted is going to connect to) and as - such you've to configure your network to make it visible from the outside world.

- By default, the server listens to Port 8080, but you can change this if necessary. - Since version 12, Dayon! creates a corresponding port forwarding rule independently. The prerequisite for this - is that UPnP is activated. - Otherwise, it will still be necessary to forward the port (TCP) via NAT on the - router to the corresponding computer. -

- Check out portforward.com for a step-by-step guide for the most - common router models. -

- -

- Optional: Adjust port for incoming connections: (on the left with UPnP, on the right without) -

- -

- Dayon! Assistant: Network Settings with UPnP - Dayon! Assistant: Network Settings without UPnP -

- -

Generate and copy token

- -

- Generate an access token by clicking on the key: -

- -

- Dayon! Assistant: Create Token -

- -

- Copy the generated access token to the clipboard with a click of the mouse: -

- -

- Dayon! Assistant: Copy Token -

- -

- That's it - communicate this Token to the assisted via mail, IM or phone. -

- -

- For the impatient: Here you'll learn, how to make the - assistant listening for incoming connections. -

- -

Alternative: connect without token

- -

- If you don't want to generate an access token, you have to determine which IP address you want - to share with the assisted to connect to the assistant; you should typically use your - public IP address.
- But for testing within your local network you might want to use a different one. You can retrieve your - public IP address by clicking the network button: -

- -

- Dayon! Assistant: Network IP Addresses -

- -

- As you can see on the following picture, the menu contains an item to copy to the clipboard the actual - IP Address & Port Number. It is then easy to paste it into a chat session - (e.g., Jitsi) or into an email. -

- -

- Dayon! Assistant: Network IP Address Actions -

- -

- - Note that this IP address is not required by the assistant application as it is listening on all the - available network interfaces; but you need to communicate it to the assisted. (more on this later). - -

- -

Press play

- -

- - After a click on the play button (the first from left) the assistant is ready to accept incoming connections: - -

- -

- Dayon! Assistant : Start -

- -

- Now you can ask the assisted to connect. You'll be shortly prompted to accept the incoming connection: -

- -

- Dayon! Assistant : Incoming Connection -

- -

- You are now connected to the remote computer and can see its desktop. Be sure to compare the certificate fingerprints of - the assistant and the assisted computer.
- Caution: If they do not match, the connection is not trustworthy! -

- -

-
-

- -

Assisted  Set up the Assisted computer

- -

- Dayon! Assisted is acting as a client application calling the outside world and as such there's no network configuration to set up. -

- -

- Download and install the Dayon! application. Then start the Dayon! Assisted application and click the "play" button. -

- -

- Dayon! Assisted : Ready -

- -

- Enter the token communicated by the assistant and acknowledge with OK:
-

- -

- Dayon! Assisted : Token
- (if you have already connected to this assistant recently, then you can leave the field empty) -

- -

-

Alternative variant (connect without token):

- Enter both the IP address and the port number as communicated by the assistant confirm with OK: -
-

- -

- Dayon! Assisted : Network -
- (both input fields can be cleared by double-clicking them) -

- -

- You'll then be shortly connected to the assistant that is monitoring your screen. Enjoy! -

-

- -

- Dayon! Assistant : Running -

- -

- Note: If you are unable to connect by following the instructions above, you should check that you have the right settings. -

- - -

Managing the session

- -

- If the desktop of the assisted doesn't fit into your window, it can be scaled down: -

- -

- Dayon! Assistent : Fit Screen Toggle -

- -

- By clicking on the open lock button to the right, - you can maintain the aspect ratio of the assisted screen. Please note that this function has no effect on the display when the window is maximized. -

- -

- By default, the remote control mode is off; you can switch it on and off using the - following icon: -

- -

- Dayon! Assistant : Control Toggle -

- -

-

Clipboard transfer

-

- By clicking on the up- or down button, the clipboard of the assistant - can either be transferred to the assisted (up) or the clipboard of the - assisted to the assistant (down). -

- -

- Dayon! Assistent : Clipboard transfer -

- -

-

Currently supported are:

- - -

-

Send a Windows or Cmd key press

-

- To send the press of the *Windows key, click the Windows button in the assistants control panel: -

- -

- Dayon! Assistent : Windows Key -

- -

- The key remains pressed until you click the button again. This allows you to send Windows key shortcuts. -
- If you need for example to minimize all windows on the assisted side, you would click the Windows - button, press the M key and then click the Windows button again. -

- -

- *Note: If the assisted is running on macOS, the Cmd key/button is displayed/transferred instead. -

- -

-

Send a Ctrl key press

-

- While most of the time, the Ctrl key gets transmitted to the assisted like any other keystroke, - there are situations where it's not. For example the combination Ctrl + Alt + Delete is generally - "captured" by the assistants operating system and thus not transmitted. - On such occasions the [Ctrl] button next to the Windows button in the assistants control panel becomes handy. - The behaviour is the same as with the Windows button: the key remains pressed until you click the button again. -
- So for sending the Ctrl + Alt + Delete combination to the assisted, you have to click the [Ctrl] button first, - then press the Alt and Delete keys together, release them and finally click the [Ctrl] button again. -

- Caution: Due to restrictions of the operating system, the combination Ctrl + Alt + Delete - does not work on assisted that run under Windows! Instead, use the combination Windows + R - which provides similar functionality. -

- -

Take a screenshot at the assisted

-

- Click the "Camera" button - the screenshot will be taken directly without further questions. - The captured graphic ends up in the clipboard of the assisted, from where it can be transferred to the assistant. -

- -

- Dayon! Assistent : Take screenshot -

- -

Reset screen capture

-

- The reset screen capture (trash bin icon) clears all cached screen data and reloads a new screen capture from assisted. -

- -

Start an online meeting to chat face to face

-

- Click on the certificate fingerprints on both assisted and assistant to start a joint online meeting in Jitsi. -

- -

- Dayon! start chat -

- -

Statistics Counters

- -

- Dayon! Assistant : Statistics -

- -

- The status bar of the assistant frame is displaying, in addition to the keyboard layout, the following counters: -

-
    -
  1. Network Bandwidth
  2. -
  3. - Compression Ratio: how many times the initial capture (diff only) has been compressed -
  4. -
  5. - Number of Tiles: the number of tile being transmitted over the network as well as the cache hits. -
  6. -
  7. - Number of Skipped Capture: the number of screen captures that have - been skipped because of a too high rate (i.e., low tick value) for - the CPU. To minimize that number you have to slow down the capture - rate using a bigger tick value. -
  8. - -
  9. - Number of Merged Capture: the number of screen captures that have - been merged before being transmitted. This is due to a capture rate - too high for the current compression method. To minimize that number - you have to slow down the capture rate and/or change the compression - method using a faster one. -
  10. - -
  11. Memory usage
  12. -
  13. Duration of the active or the last support session
  14. -
- -

- That's all folks! You can find more information on the settings page. -

-
- -
- - diff --git a/docs/settings.html b/docs/settings.html deleted file mode 100644 index 4d396c04..00000000 --- a/docs/settings.html +++ /dev/null @@ -1,209 +0,0 @@ - - - - - - - - - Dayon! - Remote assistance for your family and friends - - - - - - - -
-
- DE - FR - SV - 汉语 -
- -
-

Settings

- -

Assistant   Assistant computer

- -

- Use that form to set up how the assisted screen is going to be captured; you can - configure the time (in milliseconds) between two captures (aka. tick) as well as the number of gray levels. - Starting with Dayon! 15, also sRGB colors can be used. In that case, the number of gray levels are ignored. - Please note that the use of "True colors" consumes more bandwidth and uses more RAM on the assisted side. -

- -

- Dayon! Assistant: Capture Settings -

- -

- You can then set up the compression method; two methods are available: ZIP and XZ. XZ will obtain a (much) - better compression ratio but requires more CPU and RAM as it's much more complicated than ZIP and is implemented in JAVA - (ZIP is being implemented using some native code in the JDK). -

- -

- In addition, a cache is used that allows for not sending many times the same bitmap as for - example when opening and navigating menus (i.e., what's under the menus are not sent more than once). The screen is divided into many - tiles, each one being possibly cached. You've to define the maximum number of tiles in the cache. Note that a tile is currently 32x32 - pixels of 256 levels, that is 1K. -

- -

- Dayon! Assistant : Compression Settings -

- -

Extended connection settings

-

- Dayon! Assistant: Token server -

- -

- Besides the port number the assistant is listening on, the token server to be used can be configured in the network settings dialog. - Either the default token server or a custom one can be used. A list of available token servers can be found below. - Important: Make sure you use the same token server on the assistant and the assisted side! -

- -

-
-

- -

Assisted   Assisted computer

- -

UAC Settings

-

- In order for the assistant to see all system dialogs, the UAC (User Account Control) settings must be adjusted under Windows. - For convenience, the UAC settings dialog is directly accessible from the assisted UI. - The second-lowest setting for has proven to be useful. -

- -

- Dayon! Assisted: UAC -

- -

Extended connection settings

-

- Dayon! Assisted: Token server -

- -

- If you want to connect without a token, you can manually configure the assistant's port number and IP address - in the assisted's network settings dialog.
- You can also enable or disable the auto connection of the assisted. - If enabled, the assisted will connect directly to the specified host without further inquiry the next time you launch it .
- Additionally, you can specify the token server to be utilized. Either the standard token server or a custom server can be configured. - A list of available token servers can be found at the bottom of this page.
- Important: Make sure you utilize the same token server on both the assisted and the assistant side! -

- -

Automatic connection of the assisted via command line

- -

- The host name or IP address and port of the assistant can be passed via command line parameters, where ah=host or IP address, and ap=port number: -

- - - -

- If the assisted is started with these example parameters, it connects directly to the host "an.example.com" and port "4242". -

- -

Configuring Dayon! using configuration file

-

- Since version v11.0.5, the connection parameters can be stored in a configuration YAML file. -

- This makes it possible to override user settings since the configuration from the YAML is always read and evaluated on start up. Users can make changes inside the application, but these only last until the next start if a YAML configuration is in place. -

- The primary use case for YAML configurations would be for organisations that want to use a self-hosted token server instead of the public token server, or want to specify a particular host that the assisted should automatically connect to on startup. -

- The structure of the assisted YAML is extremely simple: -

- -
-host: "an.example.com"
-port: 8080
-# autoConnect: false
-# tokenServerUrl: "https://example.org/token/"
-
- -

-

-

- -

- The assistant also has a YAML configuration file. -
-

- - The YAML file(s) can be saved under the name assisted.yaml and assistant.yaml either in the Dayon! home directory, - in the user directory, or in the same directory as the .jar, resp. .exe file. - This order also corresponds to the priority with which they are taken into account in the case of multiple configurations exist. (first one wins) -

- -

Public token servers

- -

- Below you find a list of available public token servers that are free to use.
- Would you like to contribute and add your RVS to the list? let me know! -

- Check the availability of a token server by clicking on its link. If a version number is displayed directly, it is active. -

- You can find instructions on how to operate your own token server here. -

- -
- -
- - diff --git a/docs/stats_counters.jpg b/docs/stats_counters.jpg deleted file mode 100644 index 89a8c164..00000000 Binary files a/docs/stats_counters.jpg and /dev/null differ diff --git a/docs/style.css b/docs/style.css deleted file mode 100644 index 09388923..00000000 --- a/docs/style.css +++ /dev/null @@ -1,248 +0,0 @@ -body { - font:12px/20px Verdana, Arial, Helvetica, sans-serif; - text-align:center; - padding: 0; - margin: 0; -} - -img { - border:none; - vertical-align: bottom; -} - -#container { - text-align:left; - margin:0 auto; - width:75%; -} - -#top { - height:130px; - margin-top: 17px; - padding-bottom:1.0em; - background:url('dayon.png') no-repeat left; - text-align:right; -} - -#top a { - margin-left: 10px; - font-size:150%; - text-decoration:none; - color:#666; -} - -#top a:hover { - color:#307fe1; -} - -#menu { - text-align:center; -} - -#menu a, #menu a:visited { - border-left:1px solid #ccc; - font-size:150%; - padding:0 0.5em; - text-decoration:none; - color:#666; -} - -#menu a:last-child { - border-right:1px solid #ccc; -} - -#menu a:hover { - color:#307fe1; -} - -#content { - padding-top:1.0em; -} - -#content ul { - list-style-image:url('bullet.gif'); -} - -#content a:link, #content a:visited { - text-decoration:none; - color:#307fe1; -} - -#content a:hover { - color:#307fe1; - text-decoration:underline; -} - -#content h2 { - font-size:150%; -} - -#content h3 { - font-size:125%; -} - -#content h4 { - font-size:110%; -} - -#intro { - min-height:120px; - background:url('intro.png') no-repeat 5px 5px; -} - -#intro p { - margin-left:220px; - font-size:130%; -} - -#features { - border:1px dashed #666; - border-radius:4px; - background-color:#f2f7fb; - padding:0 10px; -} - -#footer { - padding:2.0em 0; - text-align:center; -} - -.red { - color:red; -} - -pre, -code { - font-weight:bolder; -} - -.no, -.no * { - text-decoration:none !important; - color:#000 !important; -} - -h1 { - text-align: center; - letter-spacing: 1px; - word-spacing: 0.15em; - font-size: 3em; - line-height: 1.4; - transform: translateY(52%); -} - -#toggle { - display: none; -} - -.hamburger { - position: absolute; - top: 4.8em; - right: 5%; - margin-left: -2em; - margin-top: -45px; - width: 2em; - height: 45px; - z-index: 5; -} - -.hamburger div { - position: relative; - width: 3em; - height: 7px; - border-radius: 3px; - background-color: #ccc; - margin-top: 8px; - transition: all 0.3s ease-in-out; -} - -.nav { - position: fixed; - width: 100%; - height: 100%; - background-color: #222; - top: -100%; left: 0; right: 0; bottom: 0; - overflow: hidden; - transition: all 0.3s ease-in-out; - transform: scale(0); -} - -.nav-wrapper { - position: relative; - overflow: hidden; - overflow-y: auto; - height: 100%; -} - -nav { - text-align: left; - margin-left: 5%; -} - -nav .ls a { - margin-top: 22px; - margin-right: 10%; -} - -nav a { - position: relative; - text-decoration: none; - color: #ddd; - font-size: 2em; - display: inline-block; - margin-top: 1.25em; - transition: color 0.2s ease-in-out; - letter-spacing: 1px; -} - -nav a:before { - content: ''; - height: 0; - position: absolute; - width: 0.25em; - background-color: #fff; - left: -0.5em; - transition: all 0.2s ease-in-out; -} - -nav a:hover { - color: white; -} - -nav a:hover:before { - height: 100%; -} - -#toggle:checked + .hamburger .top-bun { - transform: rotate(-45deg); - margin-top: 25px; -} - -#toggle:checked + .hamburger .bottom-bun { - opacity: 0; - transform: rotate(45deg); -} - -#toggle:checked + .hamburger .meat { - transform: rotate(45deg); - margin-top: -7px; -} - -#toggle:checked + .hamburger + .nav { - top: 0; - transform: scale(1); -} - -@media all and (max-width:800px){ - #container { - width:95%; - } - - #top, #menu { - display: none; - } - - .hamburger { - margin-top: -50px; - } -} \ No newline at end of file diff --git a/docs/support.html b/docs/support.html deleted file mode 100644 index f0ba4cae..00000000 --- a/docs/support.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - Dayon! - Remote assistance for your family and friends - - - - - - - -
-
- DE - FR - SV - 汉语 -
- -
-

Support

-

- Your feedback is more than welcome! Post your question or open a new issue on GitHub. -

-

Dayon! Home Directory

-

- The directory .dayon is created within the default home directory of the logged-in user or - within the directory referenced by the JAVA property user.home and contains the saved user - preferences and default log file(s). -

- -

CRC Checksum

-

- On the assisted side, the screen is divided into different areas - called tiles. Only tiles that have changed from the previous capture are sent over - the network to the assistant side. To determine if a tile is different - I'm currently computing a CRC code (i.e., a unique integer value representing the pixels of the tile) - that is not perfect for the sake of speed. So it might happen that some changed - tiles are not sent to the assistant. -

- -

- Until now, I've detected that issue during strong testing for very few - pixels. Visually, I've not noticed anything serious. But in case - things are going mad you can then restart the assisted or before try - the reset action (trash bin icon) - that should clear every cached data and resend a full screen capture - from scratch. -

- -

Certificate fingerprints

-

- To prevent "men in the middle" attacks, the certificate fingerprints of the two connecting sides are displayed. - The two fingerprints must match - if they don't, then something strange is going on. - This additional security feature was introduced with version 13 of Dayon!. -

-

- Certificate Fingerprints -

-

- Caution: To ensure connectivity with older clients before version 13, the compatibility mode - compatibility needs to be activated.
- This is only an interim solution, please update your clients as soon as possible. -

- -

Connection establishment

-

- Dayon! connection diagram -

-
- -
- - diff --git a/docs/sv_download.html b/docs/sv_download.html deleted file mode 100644 index ccfd066e..00000000 --- a/docs/sv_download.html +++ /dev/null @@ -1,303 +0,0 @@ - - - - - - - - - Dayon! - Distanshjälp för din familj och dina vänner - - - - - - - -
-
- DE - FR - EN - 汉语 -
- -
-

Ladda ned

-

- Windows 10/11 - Användare kan enklast installera appen direkt i Microsoft Store. -

- -

- - Swedish badge - -

- -

- Separat uppdaterade installationsprogram med brett hårdvarustöd finns tillgängliga i Snap Store, - on Flathub och via - ppa:regal/dayon. -

- -

- - Get it from the Snap Store - -

- - Get it from the Flathub - -

- -

- Annars kan du ladda ned de senaste installationsprogrammen för olika plattformar från GitHub - eller SourceForge. -

- -

- - Download Dayon! (active) - -

- -

- Windows: - Två installationsprogram är tillgängliga (som alternativ till Microsoft Store) och de bör båda två fungera utan några problem. Det ena installationsprogrammet installerar samtidigt en JRE baserad på OpenJDK 1.8 (endast för 64-bits Windows) medan det andra installationsprogrammet installerar programmet utan JRE. -
- Sedan version 1.9 finns det också två separata "Snabbstartsversioner" av programmet. Dessa två program är portable versioner som inte kräver någon installation. Det ena är för hjälpgivaren och det andra är för hjälptagaren. För att undvika eventuella rättighetsproblem när dessa versioner körs, så rekommenderas det att starta hjälptagaren med administratörsrättigheter. -

- -

- Debian, Ubuntu och varianter som bygger på dem: - För att själv slippa uppdatera Dayon! manuellt, så rekommenderas du att installera appen via ppa:regal/dayon eller som en snap. -
- PPA: - sudo add-apt-repository ppa:regal/dayon, sudo apt-get update och slutligen sudo apt-get install dayon. -
- Snap: sudo snap install dayon. Alternativt, så kan du installera nedladdade .deb paket genom terminalkommandot sudo dpkg -i dayon*.deb. -

- -

- Linux: Installera antingen den separat updaterade snap-appen via - Snap Store eller via sudo snap install dayon -
- Alternativt, packa upp det nedladdade .tgz-paketet via tar xzvf. - Kör scriptet setup.sh, som följer med. JRE/JDK kommer att installeras automatiskt, men ligger inte med inne i tgz. Om JRE/JDK-installationen av någon anledning skulle misslyckas, så kan du sätta JAVA_HOME i (dayon.sh) manuellt. Observera att .tgz paketen bara har testats på olika Debian och Ubuntu. -

- -

- macOS/OS X: - Öppna paketet .dmg och dra Assisted eller Assistent till programikonen. - Vid behov måste en lämplig Java JRE 11 (eller nyare) installeras.
- Alternativt: Extrahera .tgz-paketet till valfri folder. För ökad enkelhet kan du sedan skapa ett alias för dayon_assisted.sh och dayon_assistant.sh som du kopierar till ditt skrivbord. (JRE 11 eller senare krävs) -
- Viktigt: För macOS Catalina och senare versioner så måste du aktivt ge rättighet att spela in skärmen: System Preferences > Security & Privacy > Privacy > Screen Recording -

- -

Ändringslogg

-

Dayon! v14 Candid Clover (7 mars 2024)

- - -

Dayon! v13 Beard Butter (5 november 2023)

- - -

Dayon! v12 Adorable Asteroid (16 april 2023)

- - -

Dayon! v11 Ballsy Beaver (31 oktober 2021)

- - -

- Dayon! v1.10 Lucky Lobster (27 mars 2020) - * -

- - -

- Dayon! v1.9 Promiscuous Potato (11 december 2019) - * -

- - -

- Dayon! v1.8 Truganini (18 maj 2019) - * -

- - -

- Dayon! v1.7 Tesler (21 februari 2019) - * -

- - -

- Dayon! v1.6 Solenodon (19 december 2018) - * -

- - -

- Dayon! v1.5 Pendragon (5 maj 2017) - * -

- - -

- Dayon! v1.4 Skytale (3 januari 2017) - * -

- - -

- Dayon! v1.3 Phoenix (10 december 2016) - * -

- - -

- Dayon! v1.2 (3 januari 2009) - * -

- - -

- Dayon! v1.1 (24 december 2008) - * -

- - -

Dayon! v1.0 (4 december 2008)

- - - - * Huvudversioner är inte komopatibla med varandra - -

-

- Äldre versioner(v1.0 till v1.2) kan laddas ned - här. -

-
- -
- - diff --git a/docs/sv_index.html b/docs/sv_index.html deleted file mode 100644 index 78f73380..00000000 --- a/docs/sv_index.html +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - - - - Dayon! - Distanshjälp för din familj och dina vänner - - - - - - - -
-
- DE - FR - EN - 汉语 -
- -
-

Distanshjälpstjänst

-
-

- Dayon! är en plattformsoberoende (JAVA) öppen källkodslösning som kan övervaka och styra en dator på distans. I detta avseende är den lik många andra lösningar för fjärrskrivbord (remote desktop). -

- -

Men jag antar att den har några funktioner som gör den värdefull.

-

- Du hittar fler detaljer på den här sidan. -

-
- -

Funktioner

-
-

Check mark Enkelt att komma igång

-

- Dayon! är avsedd för personer som är helt nya i datorvärlden. Det finns inget behov av att konfigurera nätverket (dvs. brandvägg, routerkonfiguration, NAT) på hjälpmottagarens dator. -Dayon! agerar där som en klient som ansluter till hjälpgivarens dator utan att användaren behöver förstå det tekniska. -

- -

Check mark Låga bandbreddskrav

-

- Dayon! skickar komprimerade och cachade gråskaliga skärmbilder (upp till 256 gråskalor) för minimerad bandbredd och för att i mesta möjliga mån erbjuda en realtidsupplevelse över Internet. Detta är fullt tillräckligt för att kunna se och arbeta med de olika menyerna och ikonerna liksom att hantera hjälptagarens datorinställningar, osv...

-
- -

Status (14)

-

- Sedan version 1.9 (Promiscuous Potato) finns, utöver det konventionella installationsprogrammet, en portabel "snabbstartsversion" tillgänglig. I Windows är det två separata "snabbstartsversioner", en för hjälpgivaren och en för hjälpmottagaren. De kallas "snabb" eftersom de kan köras utan att installeras först (kräver dock närvaro av en JRE). De är 100% kompatibla med övriga konventionella Dayon! Versioner. - Sedan version 12 (Adorable Asteroid) finns motsvarande portabla versioner även för Linux. -

- På grund av bristen på Apple-hårdvara kunde funktionen för överföring av urklipp - endast testas med Windows 10 och 11, Debian och Ubuntu - Feedback från - från macOS-användare skulle vara mycket välkommen! (Den svenska översättningen för "Download" har därför inte heller kunnat översättas vad gäller systeminställningarna för att ge rättigheter till programmet) -

- -

Bakgrund

-

- Marc Polizzi utvecklade Dayon! när han bodde i Filippinerna och kommunicerade med sin familj och sina vänner i - Europa via Skype. -

- -

- Han ville inte att de skulle behöva konfigurera sina brandväggar, DSL-/kabelroutrar, NAT - och allt annat som krävdes för att han skulle kunna komma åt deras datorer via en - fjärrskrivbordsanslutning (remote desktop). Så han bestämde sig för att implementera något mycket enkelt på - på sin fritid, samtidigt som han tog höjd för nätverk med låg bandbredd och långa svarstider (latency). - -

- -

- Flera år senare hittade jag det här programmet på Sourceforge - då jag letade efter en gratis plattformsoberoende lösning för distanshjälp. När jag använde Dayon! för att hjälpa användare som körde Windows 7 eller senare, insåg jag att programmet hade några allvarliga brister. Eftersom den senaste versionen (1.2) släppts i början av 2009 bestämde jag mig för att kontakta författaren. - Med hans samtycke flyttade jag källkoden för projektet till GitHub - i slutet av 2016 och tog över den fortsatta utvecklingen.

- -

- Dayon! betyder för övrigt "Kom in!" på Visayas - en lokal filippinsk dialekt. -

-

Licens

-

- Detta program är en fri programvara licensierad under GPL licens. - - Dayon! (active) Reviews - -

-
- -
- - diff --git a/docs/sv_privacy.html b/docs/sv_privacy.html deleted file mode 100644 index 79e297c5..00000000 --- a/docs/sv_privacy.html +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - Dayon! - Distanshjälp för din familj och dina vänner - - - - - - - -
-
- DE - FR - EN - 汉语 -
- -
-

Personlig integritet

-

100 % personlig integritet

-

- Dayon! är ett helt gratis program med öppen källkod, tillgängligt för offentliga säkerhetsrevisioner. - All kommunikation är krypterad som standard. - Programmet samlar inte in eller delar några personliga identifierbara data (PID) med tredje part. -

-

Valfri användning av tokens

-

- En valfri funktion för enkel anslutning är användningen av tokens. - Ett riskbaserat tillvägagångssätt har använts för att säkerställa minimala integritetsrisker när du använder funktionen: - Standardkonfigurationen för den funktionen är beroende av användningen av en tredjeparts Token-server. - En användares IP-adress lagras i servern upp till 7 dagar efter att den senast användes. Det enda syftet är att göra det möjligt för de två parterna att ansluta. - Servern är värd i Schweiz. Ansvarig databehandlare är operatören. - Den här funktionen kan konfigureras för att använda en server som är självvärd istället för att undvika att behöva dela data med en tredjepartsserver. -

-
- -
- - diff --git a/docs/sv_quickstart.html b/docs/sv_quickstart.html deleted file mode 100644 index 0d8424aa..00000000 --- a/docs/sv_quickstart.html +++ /dev/null @@ -1,366 +0,0 @@ - - - - - - - - - Dayon! - Distanshjälp för din familj och dina vänner - - - - - - - -
-
- DE - FR - EN - 汉语 -
- -
-

Komma igång

-

- Vanligtvis kommunicerar hjälpgivaren med hjälpmottagaren via Jitsi, telefon, chat eller vad de nu gillar bäst. Genom att starta Dayon! så kan hjälpgivaren se skärmen och styra hjälpmottagarens dator. -

- -

- I den här dokumentationen visar skärmdumpen den engelska språkversionen av programmet. - Programmet är också språkanpassat till franska, tyska, spanska, ryska och svenska. - Den återgår till engelska om det konfigurerade användarspråket inte är något av ovanstående. -

- -

- Observera: Denna dokumentation hänvisar till den senaste programversionen. -
-
-

- -

Hjälpgivare   Använda hjälpgivarens dator

- -

- Dayon! Hjäpgivare agerar som en typisk serverapplikation (som hjälptagaren ansluer till) och därför behöver du konfigurera ditt nätverk så att hjälpgivaren kan bli synlig för yttervärlden.

- Servern lyssnar som standard på Port 8080, men du kan ändra det om det skulle behövas. - Alltsedan version 12 skapar Dayon! portmappningsregeln (port forward) åt dig. Förutsättningen är att UPnP är aktiverat i ditt nätverk. - Annars måste portmappning (port forward) ändå ske, (TCP) via NATroutern till datorn. -

- Kolla in portforward.com för en steg-för-steg guide för de vanligaste routermodellerna. -

-

- Valfritt: Ändra port för inkommande anslutningar: (till vänster med UPnP, till höger utan UPnP) -

- -

- Dayon! Hjälpgivare: Nätverksinställning med UPnP - Dayon! Hjälpgivare: Nätverksinställning utan UPnP -

- -

- Skapa en anslutningsnyckel genom att klicka på nyckeln: -

- -

- Dayon! Hjälpgivare: Skapa anslutningsnyckel -

- -

- Kopiera den skapade anslutningsnyckeln till urklipp med ett musklick: -

- -

- Dayon! Hjälpgivare: Kopiera anslutningsnyckel -

- -

- Det var allt - meddela anslutningsnyckeln till hjälptagaren via epost, chat eller telefon. -

- -

- För den otålige: Här får du lära dig hur du får - hjälpgivaren att lyssna efter inkommande anslutningar. -

- -

Alternativ variant: anslut utan anslutningsnyckel

-

- Om du inte vill generera en åtkomsttoken måste du bestämma vilken IP-adress du vill meddela den hjälptagaren - för att ansluta till hjälpgivaren; du ska normalt sett ange din publika IP-adress. - Men för att testa inom ditt lokala nätverk kanske du vill använda ett annat. Du kan hämta din publika IP-adress - genom att klicka på nätverksknappen: -

- -

- Dayon! Hjälpgivare: IP-Adress -

- -

- Som du kan se i den följande bilden, så innehåller menyn alternativet "kopiera till urklipp" redan IP-adressen och Porten. Det gör att det är lätt att klistra in det i en chat session - (t.ex. Jitsi) eller till ett e-postmeddelande. -

- -

- Dayon! Hjälpgivare: IP-Adresshandlingar -

- -

- - Observera att denna IP-adress inte är ett krav, då hjälpgivaren lyssnar på alla tillgängliga nätverksanslutningar; men du behöver meddela det till hjälptagaren ändå (mer om det senare). - -

- -

- Det var allt vad gäller nätverksinställningar; -
- För den otålige: Här lär du dig hur du får hjälpgivaren att lyssna efter inkommande anslutningar. -

- -

- - Det var det mesta. Efter ett klick på "play"- knappen (längst upp till vänster) så är - hjälpgivaren klar att ta emot inkommande förfrågningar om anslutning: - -

- -

- Dayon! Hjälpgivare : Start -

- -

- Nu kan du be hjälptagaren att ansluta. Strax därefter kommer du att bli ombedd att acceptera den inkommande anslutningen: -

- -

- Dayon! Hjälpgivare : Inkommande anslutning -

- -

- Du är nu ansluten och övervakar den andra datorn på distans. Glöm inte att jämföra hjälpgivare och hjälptagare fingeravtryck. -
- Varning: Om de inte matchar är anslutningen inte pålitlig! -

- -

-
-

- -

hjälptagare   Använda hjälptagarens dator

- -

- Dayon! Hjälptagare är en klientapplikation som anropar yttervärlden. Därför behövs ingen särskild nätverkskonfigurering göras för att kunna installera och använda programmet. -

- -

- Ladda ned och installera Dayon!. Starta sedan Dayon! Hjälptagare (du borde ha en genväg på skrivbordet) och klicka "play"-knappen uppe till vänster. -

- -

- Dayon! Hjälptagare : Klar -

- -

- Ange anslutningsnyckeln som hjälpgivaren gett dig och bekräfta med OK: -
-

- -

- Dayon! Hjälptagare : Anslutningsnyckel -
- (om du redan anslutit till denna hjälpgivare nyligen, så kan du lämna fältet tomt) -

- -

Alternativ variant: anslut utan anslutningsnyckel

-

- Ange både den IP-adress och den port som hjälpgivaren gett dig och bekräfta med OK: -
-

- -

- Dayon! Hjälptagare : Nätverk -
- (båda fälten kan rensas genom att dubbelklicka i dem) -

- -

- Du kommer att anslutas till hjälpgivaren inom kort, som sedan kan se din skärm. Grattis! -
-

- -

- Dayon! Hjälpgivare : Aktiv -

- -

- Obs: Om du inte kan ansluta genom att följa instruktionerna ovan bör du kontrollera att du har rätt inställningar. -

- -

Hantera sessionen

- -

- Om skärmbilden hos hjälptagaren inte ryms i ditt fönster, så kan det anpassas till ditt fönster: -

- -

- Dayon! Hjälpgivare : Växla skärmläge -

- -

- Genom att klicka på knappen öppna lås, - behåller du bildförhållandet från hjälptagarens skärm. Observera att denna funktion inte har någon effekt när fönstret hos hjälpgivaren är maximerat. -

- -

- Som standard är distanskontroll av; du kan växla mellan av och på med följande knapp: -

- -

- Dayon! Hjälpgivare : Växla distanskontroll -

- -

Urklippsöverföring

-

- Genom att klicka på upp- eller ned-pilen, så kan antingen hjälpgivarens urklipp överföras till hjälptagaren (upp) eller hjälptagarens urklipp överföras till hjälpgivaren (ned). -

- -

- Dayon! Hjälpgivare : Urklippsöverföring -

- -

-

Nuvarande stöd:

- - -

-

Att överföra en tryckning på Windows- eller Cmd-tangenten

-

- För att överföra ett tryck på *Windows-tangenten, så musklicka på Windowssymbolen i hjälpgivarens kontrollpanel: -

- -

- Dayon! Hjälpgivare : Windows-tangent -

- -

- Tangenten fortsätter att vara intryckt till dess att du klickar på Windowssymbolen igen. Det ger dig möjligheten att överföra snabbkommandon som innehåller Windows-tangenten. -
- Om du exemplvis behöver minimera alla fönster hos hjälptagaren, så klickar du på Windowssymbolen, trycker på M-tangenten på ditt tangentbord och sedan klickar du på Windowssymbolen igen. -

- -

- *Notera: Om hjälptagaren kör macOS visas/överförs Cmd-knappen/tangenten istället. -

- -

-

Att överföra en tryckning på Ctrl-tangenten

-

- Oftast överförs Ctrl-tangenten till hjälptagaren på samma sätt som alla andra tangenttryckningar, - tryck sedan på tangenterna Alt och Delete samtidigt, släpp dem och klicka slutligen på knappen [Ctrl] igen. - men intealltid. Till exempel blir kombinationen Ctrl + Alt + Delete "fångad" av hjälpgivarens operativsystem och överförs därmed inte. - Vid sådana tillfällen är [Ctrl]-knappen (bredvid Windows-knappen) hos hjälpgivaren praktisk att ha. - Funktionen är densamma som för Windows-knappen: tangenten förblir nedtryckt tills du klickar på knappen igen. -
- Så för att skicka tangentkombinationen Ctrl + Alt + Delete till hjälptagaren, måste du först klicka på knappen [Ctrl], - sedan trycka ned tangenterna Alt och Delete samtidigt, därefter släppa dem och slutligen klicka på knappen [Ctrl] igen. -

- Varning: På grund av begränsningar i Windows skickas inte kombinationen Ctrl + Alt + Del till - hjälptagare!
- Använd istället tangentkombinationen Windows + R som ger motasvarande funktionalitet. -

- -

Ta en skärmdump hos den hjälptagaren

-

- Klicka på knappen "kamera" - skärmdumpen tas direkt. - Bilden hamnar i hjälptagarens urklipp, varifrån den kan överföras till hjälpgivaren. -

- -

- Dayon! Assistent : Take screenshot -

- -

Starta ett onlinemöte

-

- Klicka på certifikatets fingeravtryck hos både hjälptagaren och hjälpgivare för att starta ett gemensamt onlinemöte i Jitsi Meeting. -

- -

- Dayon! start chat -

- -

Mätare

- Dayon! Hjälpgivare : Mätare -

- Statusfältet i nederkanten av hjälpgivarens fönster visar, utöver tangentbordets språklayout, ett antal mätare. -

-
    -
  1. Bandbreddsanvändning
  2. -
  3. - Kompressionsgrad: hur många gånger urpsprungsbilden (dess förändringar) har komprimerats -
  4. -
  5. - Antal mottagna sektioner: antalet sektioner som överförts och träffprocent för cache. -
  6. -
  7. - Antal skippade skärmbilder: antalet avläsningar som har skippats pga. för högt värde för CPUn (dvs för lågt satt tick). För att minska antalet så behöver du öka tick för att inte avläsa skärmen lika ofta. -
  8. - -
  9. - Antal sammanfogade skärmbilder: antalet avläsningar som har sammanfogats innan de överförts. Detta beror på att tick satts för lågt för den valda komprimeringsmetoden. För att minska värdet så behöver du öka tick för att inte avläsa skärmen lika ofta eller byta till en snabbare komprimeringsmetod. -
  10. - -
  11. Använt minne av totalt tillgängligt
  12. -
  13. Sessionslängd för aktiv anslutning eller den senaste anslutningen
  14. -
- - -
- -
- - diff --git a/docs/sv_settings.html b/docs/sv_settings.html deleted file mode 100644 index 74f4ee7e..00000000 --- a/docs/sv_settings.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - - - - Dayon! - Distanshjälp för din familj och dina vänner - - - - - - - -
-
- DE - FR - EN - 汉语 -
- -
-

Settings

- -

Hjälpgivare  Hjälpgivarens dator

- -

- Använd formuläret för att ange hur hjälptagarens skärm blir avläst; du kan anpassa (i millisekunder) tiden mellan två avläsningar (eller "tick") liksom antal gråskalor i bilden. - Från och med Dayon! 15 kan sRGB-färger också användas som ett alternativ. I detta fall ignoreras antalet gråtoner. - Observera att användningen av "Sanna färger" förbrukar mer bandbredd och mer RAM på hjälpgivare-sidan. -

- -

- Dayon! Hjälpgivare: Skärmbildsinställning -

- -

- Sedan kan du välja metod för komprimering; två metoder finns att välja på: ZIP och XZ. XZ uppnår en (mycket) bättre kompression, men tar mer kraft från CPU och internminne pga. dess komplexitet och att den utförs i JAVA. -

- -

- Dessutom, används en cache för att inte behöva sända samma bitmap flera gånger, t.ex. när menyer öppnas och navigeras (dvs. det som finns i undermenyer skickas inte mer än en gång). Skärmbilden är indelad i många sektioner, där varje kan bli cachad. Du kan definiera det maximala antalet sektioner i cachen. Observera att en sektion i nuvarande version är 32x32 pixlar i 256 gråskalor, vilket motsvarar c:a 1K. -

- -

- Dayon! Assistant : Komprimeringsinställningar -

- -

Utökade anslutningsinställningar

-

- Dag! Assistent: Tokenserver -

- -

- Förutom portnumret som hjälpgivare lyssnar på, kan tokenservern som ska användas konfigureras i dialogrutan för nätverksinställningar. - Antingen standardtokenservern eller en anpassad kan användas. En lista över tillgängliga tokenservrar finns nedan. - Viktigt: Se till att du använder samma tokenserver på assistenten och den assisterade sidan! -

- -

-
-

- -

hjälptagare   Hjälptagarens dator

- -

UAC-inställningar

-

- För att hjälpgivare ska se alla systemdialogrutor måste UAC-inställningarna (User Account Control) justeras under Windows. - För enkelhetens skull är dialogrutan för UAC-inställningar direkt tillgänglig från det hjälptagare användargränssnittet. - Den näst lägsta inställningen för har visat sig vara användbar. -

- -

- Dayon! hjälptagare: UAC -

- -

Utökade anslutningsinställningar

-

- Dayon! hjälptagare: tokenservrar -

- -

- I dialogrutan för nätverksinställningar för den hjälptagare kan du konfigurera portnumret och IP-adressen för hjälpgivare manuellt, om du vill - ansluta utan token.
- Du kan också aktivera eller inaktivera den automatiska anslutningen för den hjälptagare. - Om den är aktiverad kommer den hjälptagare att ansluta direkt till den givna värden utan ytterligare förfrågan, nästa gång du startar den hjälptagare.
- Du kan också konfigurera tokenservern som ska användas. Antingen kan standardtokenservern eller en anpassad server ställas in. - En lista över tillgängliga tokenservrar finns längst ner på den här sidan.
- Viktigt: Se till att du använder samma token-server på den hjälptagare som på den hjälpgivare sidan! -

- -

- -

Automatisk anslutning av hjälptagaren via command line parametrar

-

- Värdnamn (Host Name) eller IP-adress och port för hjälpgivaren kan överföras via command line parametrar, där ah=värdnamn eller IP-adress och ap=portnummer: -

- Om hjälptagaren startas med dessa parametrar, så ansluter den direkt till värden "an.example.com" och porten "4242". -

- -

Konfigurerar Dayon! via konfigurationsfil

-

- Alltsedan version v11.0.5, så kan anslutningsparametrar (connection parameters) lagras i en YAML fil. -

- Detta gör det möjligt att åsidosätta användarinställningar eftersom konfigurationen från YAML alltid läses och utvärderas vid uppstart. Användare kan göra ändringar i applikationen, men dessa varar bara till nästa start om en YAML-konfiguration finns på plats. -

- Det primära användningsfallet för YAML-konfigurationer skulle vara för organisationer som vill använda en egenvärdig tokenserver istället för den offentliga tokenservern, eller som vill ange en viss värd som den assisterade automatiskt ska ansluta till vid start. -

- Strukturen för den hjälptagaren YAML är extremt enkel: -

- -
-host: "an.example.com"
-port: 8080
-# autoConnect: false
-# tokenServerUrl: "https://example.org/token/"
-
- -

-

-

- -

- Hjälpgivare har också en YAML-konfigurationsfil. -
-

- Denna fil kan sparas under namnet assisted.yaml antingen i Dayon! hemmafolder (home directory), in användarfoldern (user directory), eller i samma folder som .jar, resp. - .exe filerna. Detta återspeglar också den prioritetsordning som gäller om flera filer finns. (den första vinner) -
-

- -

Offentliga tokenservrar

-

- Nedan hittar du en lista över tillgängliga offentliga token-servrar som är gratis att använda.
- Vill du bidra och lägga till din RVS på listan? meddela mig! -

- Kontrollera tillgängligheten för en token-server genom att klicka på dess länk. Om ett versionsnummer visas direkt är det aktivt. -

- Du kan hitta instruktioner om hur du använder din egen token-server här. -

- -
- -
- - diff --git a/docs/sv_support.html b/docs/sv_support.html deleted file mode 100644 index 434ab252..00000000 --- a/docs/sv_support.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - Dayon! - Distanshjälp för din familj och dina vänner - - - - - - - -
-
- DE - FR - EN - 汉语 -
- -
-

Support

-

- Din feedback är mer än välkommen - posta dina frågor eller öppna ett nytt ärende på GitHub. -

- -

Dayon! Hemmafolder (Home Directory)

-

- Foldern .dayon skapas som standard i den inloggade användarens hemmafolder eller i den folder som anges i JAVA egenskapen (property) user.home. Där sparas användarinställningar och loggfiler. -

- -

CRC-checksumma (Bildproblem)

-

- Hjälptagarens skärmbild är nedbruten i många små delar som kallas sektioner. Endast de sektioner som har ändrats sedan den senaste avläsningen av skärmen skickas över till hjälpgivaren. För att avgöra om en sektion har ändrats så använder jag för tillfället en CRC-checksumma (dvs. ett unikt heltal som representerar pixlarna i sektionen). Det är inte en perfekt lösning vad gäller hastighet och det kan hända att några förändrade sektioner inte överförs till hjälpgivaren. -

- -

- Hittills har problemet endast uppstått för enstaka pixlar under hårda stresstester. Visuellt har jag inte sett något allvarligt, men om allt går knas så kan du pröva att använda funktionen Återställ skärmbild som du hittar vid klick på (papperskorgsknappen). Det borde rensa all data i cachen och överföra en helt ny skärmbild. Annars får du pröva att starta om hjälptagaren. -

- -

Fingeravtryck för certifikat

-

- För att förhindra man-in-the-middle attacker, så visas fingeravtrycket för på datorers certifikat. - De två fingeravtrycken måste matcha - annars är det något skumt som pågår. - Denna säkerhetsfunktion las till i och med version 13 av Dayon!. -

-

- Fingeravtryck -

-

- Varning: För att möjliggöra anslutningsmöjlighet till gamla versioner (före version 13) , så måste Kompatibelt läge compatibility vara aktiverat.
- Detta är endast en tillfällig lösning, uppdatera dina klientinstallationer så snart som möjligt. -

- -

Hur anslutningar sker

-

- Dayon! Anslutningsschema -

-
- -
- - diff --git a/docs/zh_download.html b/docs/zh_download.html deleted file mode 100644 index 834f8880..00000000 --- a/docs/zh_download.html +++ /dev/null @@ -1,319 +0,0 @@ - - - - - - - - - Dayon! - 为您的家人和朋友提供远程协助 - - - - - - - -
-
- DE - FR - SV - EN -
- -
-

下载

-

-     Windows 10/11用户可以直接从 - 微软应用商店(Microsoft Store) 安装Dayon!。 -

- -

- - English badge - -

- -

-     兼容大多数硬件设备的独立更新包可以从 - Snap StoreFlathub - 还有 Dayon!的PPA源 ppa:regal/dayon 获得。 -

- -

- - Get it from the Snap Store - -

- - Get it from the Flathub - -

- -

-     此外,您还能从 - GitHub - 或者 - - SourceForge - - 获取适用于您设备的最新安装包。 -

- -

- - Download Dayon! (active) - -

- -

-     Windows: - 我们提供了两种安装包助您轻松部署Dayon!。一种是捆绑了JRE(基于OpenJDK 11 LTS)的安装包,另一种则没有。注意:捆绑了JRE的安装包仅适用于64位版本的Windows。 -
- 从1.9版本开始,我们还提供了“快速启动”版本。一个是主控端(Assistant),另一个是被控端(Assisted)。这两个便携式版本无需安装,可直接运行(为了避免UAC可能导致的潜在问题,建议以管理员权限启动Dayon![右击-以管理员身份运行])。 -

- -

-     Debian, Ubuntu及其衍生的Linux发行版: - 推荐通过 PPA源 - ppa:regal/dayon - 或者 - Snap Store - 安装Dayon!,这样您可以轻松保持 Dayon! 版本最新。 -
-     PPA: 添加PPA源 sudo add-apt-repository ppa:regal/dayon 然后更新软件包列表 sudo apt-get update - 最后安装Dayon!: sudo apt-get install dayon。 -
-     Snap: sudo snap install dayon。 -
-     DEB Package: 或者,您可以自行下载 .deb 后缀的安装包,然后在终端输入 sudo dpkg -i dayon*.deb - 或者 sudo apt install ./dayon*.deb 进行安装。 -

- -

-     其他Linux发行版: - 除了通过 Snap Store 或者 sudo snap install dayon - 安装Snap版本的Dayon!外,您还可以自行下载压缩包进行安装(并非源代码!): -
- 使用 tar xzvf 解压下载的 .tgz 后缀的压缩包,然后运行 setup.sh 脚本。 - 由于tgz压缩包中没有捆绑JRE,所以脚本将自动检测已安装的JRE/JDK。如果出于某种原因未能成功检测,您可以在 dayon.sh - 中手动指定 JAVA_HOME。注意: .tgz 压缩包仅在众多的Debian和Ubuntu发行版上进行了测试。 -

- -

-     Mac OS/OS X: - 打开.dmg软件包并将“Assisted”或“Assistant”拖到程序图标上。如有必要,必须安装合适的 Java JRE 11(或更高版本)。 -
- 或者:将.tgz包解压到您想要的位置。方便起见,您可能想为 dayon_assisted.sh dayon_assistant.sh - 创建别名并将它们复制到桌面。(要求:设备已安装 11 或更高版本的JRE )。 -
-     重要提示: 从 macOS Catalina 或更高版本开始,您必须明确授予 - dayon_assisted.sh 屏幕捕获权限: 系统偏好设置 > 安全和隐私 > 隐私 > 屏幕捕获 -

- -

更新日志

-

- Dayon! v14 Candid Clover (2024年3月7日) - * -

- - -

Dayon! v13 Beard Butter (2023年11月5日)

- - -

Dayon! v12 Adorable Asteroid(2023年4月16日)

- - -

Dayon! v11 Ballsy Beaver 更新内容(2021年10月31日)

- - -

- Dayon! v1.10 Lucky Lobster 更新内容(2020年3月27日) - * -

- - -

- Dayon! v1.9 Promiscuous Potato 更新内容(2019年12月11日) - * -

- - -

- Dayon! v1.8 Truganini 更新内容(2019年5月18日) - * -

- - -

- Dayon! v1.7 Tesler 更新内容(2019年2月21日) - * -

- - -

- Dayon! v1.6 Solenodon 更新内容(2018年12月19日) - * -

- - -

- Dayon! v1.5 Pendragon 更新内容(2017年5月5日) - * -

- - -

- Dayon! v1.4 Skytale 更新内容(2017年1月3日) - * -

- - -

- Dayon! v1.3 Phoenix 更新内容(2016年12月10日) - * -

- - -

- Dayon! v1.2 更新内容(2009年1月3日) - * -

- - -

- Dayon! v1.1 更新内容(2008年12月24日) - * -

- - -

Dayon! v1.0 (2008年12月4日)

- - - * 标记表示版本之间彼此不兼容! -

-

- 更早的Legacy(v1.0 到 v1.2)版本可以在 这里 下载。 -

-
- -
- - diff --git a/docs/zh_index.html b/docs/zh_index.html deleted file mode 100644 index d4b1768a..00000000 --- a/docs/zh_index.html +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - Dayon! - 为您的家人和朋友提供远程协助 - - - - - - - -
-
- DE - FR - SV - EN -
- -
-

远程协助服务

-
-

-     Dayon! 是一个开源和跨平台 (JAVA) 的远程解决方案,允许您观看和控制远程计算机。或许,它与现有的远程桌面解决方案(Teamviewer、Anydesk…)非常相似。 -

-

-     但我想 Dayon! 有自己的特色,这也是它的价值所在。 -

-

-     更多详情请查看 这个页面。 -

-
-

功能

-
-

轻松配置和部署 —— 一键运行

-

-     Dayon! 是专为 零 计算机基础的用户而设计的。终端用户无需在他们的计算机上手动设置网络(无需配置防火墙、无需配置路由器、无需配置 NAT ), - 只需要打开Dayon! 客户端输入指定的地址,就能连接到开发者的远程计算机(客户端主动连接服务端)。 -

-

超低的网络带宽占用 —— 强大的低带宽、高延时网络适应能力

-

-     Dayon! 通过压缩算法和发送缓存的黑白(最高 256 色)图像以最大限度地减少网络资源使用,尽可能多地提供实时体验。 - Dayon! 所提供的黑白屏幕影像质量足以清除分辨菜单、图标和查看计算机设置等... -

-
-

状态 (14)

-

-     自版本 1.9(Promisceous Potato)开始,除常规安装程序外,我们还提供了便携式“快速启动”版本。有两个独立的 “快速启动” Windows 二进制文件, - 一个用户端(assisted),一个主控端(assistant)。之所以称为 “快速启动” 是因为它们无需安装即可运行(但是需要 JRE )。它们与常规的 Dayon 100% 兼容! - 版本。自版本 12(Adorable Asteroid)开始,类似的便携式版本也可用于 Linux 平台。 -

-     由于缺乏 Apple 设备,剪贴板传输功能仅在 Windows 10 和 11、Debian 和 Ubuntu 上进行了测试 - 非常欢迎 macOS 用户的反馈! -

-

讲个小故事…

-

-     Marc Polizzi 于菲律宾开发了Dayon! ,彼时,他通过 Skype(一种通讯软件) 与远在欧洲的家人和朋友联络。 -

-

-     他希望能够有个不需要任何额外操作(无需设置防火墙、DSL/路由器、NAT等)就能使用的远程桌面,以便他访问家人和朋友们的计算机。所以, - 他决定利用业余时间,开发一款能够适应低带宽和高网络延时的远程桌面应用 —— Dayon! 。 -

-

-     几年后,我在 Sourceforge - 上寻找免费的跨平台远程协助解决方案时发现了这个项目。 在使用 Dayon! 帮助 Windows 7 及更高版本 Windows 系统的用户时,我意识到它有一些严重的缺陷。 - 在2009年初新版本 Dayon! (1.2)发布后,我决定与作者联系。 在征得原作者同意后,我于2016年年底将项目的源代码转移至 - GitHub 并接管开发工作。 -

-

-     顺带一提, "Dayon!" 来源于菲律宾米沙鄢语(Visayas)中的 "请进!" (或者“进来”,原文是:Come in!) 。 -

-

许可证

-

-     该程序是根据 - GPL 许可证 授权的免费软件。 - - Dayon! (active) Reviews - -

-
- -
- - diff --git a/docs/zh_privacy.html b/docs/zh_privacy.html deleted file mode 100644 index 9548e41a..00000000 --- a/docs/zh_privacy.html +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - Dayon! - 为您的家人和朋友提供远程协助 - - - - - - - -
-
- DE - FR - SV - EN -
- -
-

隐私声明

-

100% 隐私保护

-

-     Dayon! 是一个完全免费的开源程序,可供公众进行安全审计。 - 所有通信默认采用加密方式进行。 - 该程序不会收集或与第三方共享任何个人可识别数据(Personal Identifiable Data - PID)。 -

-

访问令牌功能(可选)

-

-     为了方便连接,您可以使用访问令牌功能。 - 我们采用风险为本(risk-based approach - RBA,或称为基于风险、風險基礎)方法,以确保使用该功能时将隐私风险降到最低: - 此功能的默认配置依赖于第三方令牌服务器。 - 用户最后一次使用的 IP 地址信息至多在服务器上存储 7 天,这么做的目的仅为双方能够建立连接。 - 服务器位于瑞士,由运营商负责数据处理。 - 访问令牌功能允许您使用自托管的令牌服务器,从而避免与第三方服务器共享数据。 -

-
- -
- - diff --git a/docs/zh_quickstart.html b/docs/zh_quickstart.html deleted file mode 100644 index 698e385b..00000000 --- a/docs/zh_quickstart.html +++ /dev/null @@ -1,433 +0,0 @@ - - - - - - - - - Dayon! - 为您的家人和朋友提供远程协助 - - - - - - - -
-
- DE - FR - SV - EN -
- -
-

快速入门

-

-     设想的情景:帮助者(使用 Dayon! 主控端 Assistant) - 使用远程桌面应用 Dayon! 帮助 被帮助者(下文或称为用户,使用 Dayon! 用户端 Assisted) - 解决计算机方面的问题 。 -

- -

-     通常,帮助者 使用 QQ、微信、Jitsi、电话或者其他即时通讯工具与 用户(被帮助者) 进行交流, - 然后使用 Dayon!实时观看 用户 的计算机屏幕并进行操作指导,必要时还能进行远程操作。 -

- -

-     此文档中,截图展示的是 Dayon!的英文界面。目前 Dayon!还支持法语、德语、意大利语、西班牙语、瑞典语、俄语、土耳其语和中文(简体)。 - 如果用户配置的语言不是上述某种, Dayon!将默认使用英语。 -

-

-     注意:此文档基于最新版的程序书写。 -
- - - -     中国大陆用户注意:由于一些众所周知的原因(中国人口基数大,IPv4 - 资源有限,不是所有人都拿得到公网 IP ), - Dayon!的访问令牌(access token)功能可能用不了。解决方法也很简单,一可以使用诸如FRP、Ngrok、 - 花生壳等内网穿透工具(可以自己买服务器部署,也可以使用别人搭好的。内网穿透服务国内很多,免费的付费的都有,需要的请自行百度,这里不提供); - 二可以自己组装VPN网络,比如使用OpenVPN、ZeroTier等工具。我(译者)个人使用的是FRP和ZeroTier这两个工具,如果你是在内网使用 - Dayon!,那可以忽略前面这些。 -

-

- -

准备与连接

- -

Assistant  配置 Assistant - 主控端

- -

-     Dayon! Assistant - 主控端 是一个典型的服务器应用程序(接收来自 Assisted - 用户端 的连接请求), - 因此您需要配置您的网络使其对外可见。 -

- 默认情况下,服务器监听 8080 端口,如有必要,您可以更改此设置。 - 自版本 12 起,Dayon! 将独立创建相应的端口转发规则。 - 前提是已启用 UPnP,否则仍需要通过 路由器 上的 NAT 将端口(TCP)转发到相应的计算机。 -

-     在 portforward.com 可以查询到详细的常见型号的路由器配置指南。 -

-     (译者注:上面说了那么多,说白就是你要让你的计算机暴露在公网,让用户可以访问得到你。 - 如果你有公网IP,这自然是最方便的。如果你和我一样,没有公网IP,那可以使用内网穿透、VPN等。 - 比如FRP、Ngrok、OpenVPN、ZeroTier等,有些是需要自己有服务器才能搭建,而有些则不需要, - 而且网上有很多热心网友贡献的免费通道,请自行百度,谢谢) -

- -

-     可选:调整监听传入连接的端口号:(左图启用 UPnP,右图则没有) -

- -

- Dayon! Assistant: Network Settings with UPnP - Dayon! Assistant: Network Settings without UPnP -

- -

生成并复制访问令牌

- -

-     通过单击密钥图标的按钮生成访问令牌: -

- -

- Dayon! Assistant: Create Token -

- -

-     再次单击鼠标将生成的访问令牌复制到剪贴板: -

- -

- Dayon! Assistant: Copy Token -

- -

-     就酱紫 - 通过邮件、IM 或电话将此 访问令牌 发送给 被帮助者(使用‘Assisted - 用户端’的用户) 。 -

- -

-     对于那些不耐烦的人: 戳 这里 直达 Assistant - 主控端 如何开始监听会话。 -

- -

其他可选:不使用访问令牌进行连接

- -

-     如果您不想生成访问令牌,您需要确定要与 被帮助者(使用‘Assisted - 用户端’的用户) 共享的 - IP 地址(用于 Assisted - 用户端 连接到 Assistant - 主控端 ); - 这个 IP 地址一般是您的 公网 地址。 -
- 但是,如果在本地网络中进行测试,您可能希望使用另一个 IP 地址(即内网地址)。 - 您可以通过点击网络图标的按钮来获取您的公共 IP 地址(即公网地址): -

- -

- Dayon! Assistant: Network IP Addresses -

- -

-     如您在下图中所见,菜单中包含一个项目,可以将当前 IP地址和端口号 复制到剪贴板上。 - 随后,您可以轻松地将其粘贴到聊天会话(例如Jitsi、QQ、微信)或电子邮件中。 -

- -

- Dayon! Assistant: Network IP Address Actions -

- -

- -     请注意,Assistant 主控端 不需要此 IP 地址,因为它正在侦听所有可用的网络接口, - 但您需要将这个IP地址和对应的端口号告诉 被帮助的用户(使用‘Assisted - 用户端’的用户), - 这样用户才能发起连接(稍后会详细介绍)。 - 请注意,Assistant - 主控端 应用程序并不需要此 IP 地址,因为它正在监听所有可用的网络接口; - 但您需要将此 IP 地址发送给 被帮助者(使用‘Assisted - 用户端’的用户,更多内容稍后再说)。 - -

- -

点击开始

- -

- -     单击开始按钮(左侧第一个,播放图标的按钮)后,Assistant - 主控端 开始监听传入的连接: - -

- -

- Dayon! Assistant : Start -

- -

-     现在您可以请求 被帮助者(使用‘Assisted - 用户端’的用户) 发起连接请求, - 如果一切顺利,您很快会收到是否接受传入连接的提示: -

- -

- Dayon! Assistant : Incoming Connection -

- -

-     现在您已连接到远程计算机,且能实时监控其屏幕。 - 别忘了比对 Assistant - 主控端Assisted - 用户端 的指纹。 - 警告: 如果两个指纹不匹配,则连接不可信!(意味着可能被窃听) -

- -

-
-

- -

Assisted  配置 Assisted - 用户端

- -

-     Dayon! Assisted - 用户端 作为对外发送会话请求的客户端应用程序 - ( Assisted - 用户端 发送会话连接请求到 Assistant - 主控端 ),不需要进行网络配置。 -

- -

-     首先,下载并安装 Dayon! 应用。 - 然后运行 Assisted - 用户端 (建议以管理员权限运行),并单击“播放”图标的按钮。 -

- -

- Dayon! Assisted : Ready -

- -

-     输入 帮助者(使用‘Assistant - 主控端’的用户) 提供的访问令牌,然后点击 确认按钮 —— OK: -
-

- -

- Dayon! Assisted : Token
-     (如果您最近连接过此 Assistant - 主控端 ,则可以将该字段留空) -

- -

-

其他可选:不使用访问令牌进行连接

-     输入 帮助者(使用‘Assistant - 主控端’的用户) 提供的 IP 地址和端口号,然后单击“OK”确认:
-

- -

- Dayon! Assisted : Network -
-     (可以通过双击来清除这两个字段) -

- -

-     如果一切顺利,您将在片刻后连接到 帮助者 - (帮助者使用的是 Assistant - 主控端 ,连接成功后对方就可以实时观看您的屏幕), Enjoy! -

-

- -

- Dayon! Assistant : Running -

- -

-     注意:如果您无法按照上述说明进行连接,您应该检查您的 设置 是否正确。 -

- - -

会话管理

- -

-     如果显示的 Assisted - 用户端 的桌面大小不适应您的窗口大小,您可以将其调整为自适应: -

- -

- Dayon! Assistent : Fit Screen Toggle -

- -

-     通过点击右侧 - open lock - (开锁图标的)按钮,您可以保持 Assisted - 用户端 屏幕的宽高比。 - 请注意,当窗口最大化时此功能无效。 -

- -

-     默认情况下, 远程控制模式 是关闭的;您可以使用下面这个手势图标的按钮来启用或禁用远程控制: -

- -

- Dayon! Assistant : Control Toggle -

- -

-

剪贴板传输

-

-     通过单击 向上/向下 图标的按钮,可以将 Assistant - 主控端(您的)的剪贴板内容 - 发送到 Assisted - 用户端(用户的)计算机剪贴板上(向上),或者相反(向下)。 -

- -

- Dayon! Assistent : Clipboard transfer -

- -

-

目前支持传输的有:

- - -

-

发送 Windows 或 Cmd 按键

-

-     要发送 *Windows 键的按下操作,请点击 Assistant - 主控端 控制面板中的 Windows 按钮: -

- -

- Dayon! Assistent : Windows Key -

- -

-     Windows 按键将保持按下状态,直到您再次点击该按钮(单击一次按下,再次单击是松开),如此设计允许您发送 Windows 快捷键。 -
- 例如,您需要在 Assisted - 用户端 最小化所有窗口, - 您可以单击按钮(按下 Windows 键),然后按一下 M 键,再次点击按钮(释放 Windows 键)。 -

- -

-     *注意:如果 Assisted - 用户端 运行的是 macOS,则按钮 显示/传输 的是 Cmd 键/按钮 。 -

- -

-

发送 Ctrl 按键

-

-     大多数情况下 Ctrl 键会像其他按键一样传输给 Assisted - 用户端 ,但偶尔也会失效。 - 例如, Ctrl + Alt + Delete 按键组合 - 通常会被 Assistant - 主控端 的操作系统“捕获”,而不是传输到 Assisted - 用户端 。 - 在这种情况下, Assistant - 主控端 控制面板 Windows 按钮旁边的 [Ctrl] 按钮就显得很方便。 - 此按钮的行为与 Windows 按钮相同:点一次保持按键按下状态,再次单击则释放按键。 -
-     因此,要将 Ctrl + Alt + Delete 组合键发送给 Assisted - 用户端 , - 您必须先单击 [Ctrl] 按钮, - 然后同时按下 AltDelete 键、再释放它们 - ,最后单击 [Ctrl] 。 -

-     注意:由于操作系统限制,Ctrl + Alt + Delete 组合键在 - 运行于 Windows 系统下的 Assisted - 用户端 中可能 不起作用! - 请使用诸如 Windows + R 等提供类似功能的组合按键作为代替。 -

- -

截取 Assisted - 用户端 的屏幕画面

-

-     单击“相机”图标的按钮将直接截取屏幕画面。 - 捕获的截屏存在 Assisted - 用户端 的剪贴板中,通过剪贴板传输可以将其传给 Assistant - 主控端。 -

- -

- Dayon! Assistent : Take screenshot -

- -

重置屏幕捕获

-

-     重置屏幕捕获按钮(垃圾桶图标)将清除所有缓存的屏幕捕获数据,并从 Assisted - 用户端 中重新加载新的屏幕捕获画面。 -

- -

通过在线会议进行面对面沟通

-

-     单击 Assisted - 用户端 或者 Assistant - 主控端 的证书指纹即可开启一个 Jitsi 在线会议。 -

- -

- Dayon! start chat -

- -

状态统计

- -

- Dayon! Assistant : Statistics -

- -

-     除键盘布局外, Assistant - 主控端 下方的状态栏还显示一组计数器。 -

-
    -
  1. 网络带宽使用情况
  2. -
  3. - 压缩比:初始捕获(仅差异)已被压缩的次数 -
  4. -
  5. - “图块”数量:通过网络传输的“图块”数量以及缓存命中率。 -
  6. -
  7. - 跳过的捕获:由于屏幕捕获间隔设置过低(即‘ Assistant - 主控端 - 首选项 - 屏幕捕获’ 中的‘屏幕捕获间隔’设置太低) - 导致远程计算机无法捕获的画面数量。 - 为了减少画面丢失,你必须增加屏幕捕获间隔,增大‘ Assistant - 主控端 - 首选项 - 屏幕捕获 ’中的捕获间隔值。 -
  8. - -
  9. - 合并的“图块”:传输前已被合并的屏幕捕获数量。这是由于设置的屏幕捕获频率对于当前所选的压缩方法来说太高了(压缩速度 << 捕获速度)。 - 为了减少由此导致的画面丢失(或失真), - 你必须提高 ‘Assistant - 主控端 - 首选项 - 屏幕捕获’ 中的‘屏幕捕获间隔’ 或 - 更改 ‘Assistant - 主控端 - 首选项 - 压缩 - 压缩算法’ 中的算法,请选择性能更高的压缩算法。 -
  10. - -
  11. 内存使用情况
  12. - -
  13. 当前或上次会话的持续时间
  14. -
- -

-     以上即是全部内容 !更多信息请查阅 设置 页面。 -

-
- -
- - diff --git a/docs/zh_settings.html b/docs/zh_settings.html deleted file mode 100644 index 0af53132..00000000 --- a/docs/zh_settings.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - - - - Dayon! - Remote assistance for your family and friends - - - - - - - -
-
- DE - FR - SV - EN -
- -
-

设置 Dayon!

- -

Assistant   帮助者计算机(Assistant - 主控端)

- -

-     使用这个表单来设置屏幕捕获;您可以配置两次 屏幕捕获 (又名时钟滴答,即tick)之间的时间(以毫秒为单位)和灰度级数。 - 从 Dayon 开始!15 开始,也可以使用 sRGB 颜色作为替代。在这种情况下,灰度级数将被忽略。 - 请注意,使用 "真面目" 会在 Assisted - 用户端 端消耗更多带宽和内存。 -

- -

- Dayon! Assistant: Capture Settings -

- -

-     然后,您可以设置 压缩 方式;有两种压缩算法可用:ZIP 和 XZ。 - XZ 将获得(更)好的压缩率,但需要占用更多的 CPU 和 RAM 资源,因为它比 ZIP 复杂得多, - 并且是用 JAVA 实现的(相比之下,ZIP 使用 JDK 中的一些本地代码实现的)。 -

- -

-     此外,使用 缓存 可以避免重复发送相同的位图,例如在打开和浏览菜单时。屏幕被划分为多个图块,每块都可能被缓存。 - 您需定义缓存中的最大图块数量。注意,每个图块目前是32x32像素,256 级,即1K。 -

- -

- Dayon! Assistant : Compression Settings -

- -

额外的连接设置

-

- Dayon! Assistant: Token server -

- -

-     除了可以配置 Assistant - 主控端 正在侦听的端口号之外,在网络设置对话框中还可以指定令牌服务器。 - 可以指定使用默认的令牌服务器或自定义的令牌服务器(比如使用您自托管的令牌服务器)。文章末尾是可用的令牌服务器列表,如需请自行参阅。 -
-     重要提示:务必确保 Assisted - 用户端Assistant - 主控端 使用的同一个令牌服务器!! -

- -

-
-

- -

Assisted   被帮助者计算机(Assisted - 用户端)

- -

配置 UAC

-

-     为了让 帮助者(Assistant - 主控端) 能够看到所有系统对话框,必须在 Windows 下调整 UAC(用户帐户控制)设置。 - 方便起见,UAC 设置对话框可直接从 Assisted - 用户端 的用户界面访问。 - 倒数第二项的设置已被证明是有用的(The second-lowest setting for has proven to be useful, - 这里可能是指的UAC设置中的倒数第二档 —— ‘只有当应用程序尝试更改我的计算机时才通知我(不要使桌面变暗)’)。 -

- -

- Dayon! Assisted: UAC -

- -

额外的连接设置

-

- Dayon! Assisted: Token server -

- -

-     如果您想不使用访问令牌进行连接,您可以在 Assisted - 用户端 的网络设置对话框中 - 手动配置 Assistant - 主控端 的端口号和 IP 地址。 - 您还可以启用(或禁用) Assisted - 用户端 的自动连接。 - 如果启用,Assisted - 用户端 将在下次启动时直接连接到指定主机,而无需进一步询问。 -
-     此外,您可以指定要使用的令牌服务器。可以配置标准(默认)令牌服务器或自定义服务器。 - 可用的令牌服务器列表在本页 底部,如需请自行参阅。 -
-     重要提示:务必确保 Assisted - 用户端Assistant - 主控端 使用的同一个令牌服务器!! -

- -

通过命令提示符(命令行)自动连接 Assistant - 主控端

- -

-     Assistant - 主控端 的 主机名/IP 地址 和 端口 可以通过命令行参数传递, - 其中 ah 是主机名、域名或IP(ah=【主机名、域名 或 IP 地址】),ap是端口(ap=【端口号】): -

- - - -

-     如果使用上述示例参数启动 Assisted - 用户端,它将直接连接到名为 “an.example.com” 的主机的“4242” 端口。 -

- -

使用配置文件配置 Dayon!

-

-     从版本 v11.0.5 开始,连接参数可以存储在 YAML 配置文件中。 -

-     YAML 配置文件只会在程序启动时被读取和评估(计算),所以用户仍可以在应用程序内更改设置以覆盖从YAML加载的配置, - 但这些更改仅在下次启动前有效(因为下次启动依旧会加载YAML的配置,如有不解请查看英文原文)。 -

-     YAML 配置的主要用途是供那些希望使用自托管令牌服务器而不是公共令牌服务器的组织使用, - 或希望在启动时指定 Assisted - 用户端 自动连接到特定 Assistant - 主控端 主机的情况。 -

-     Assisted - 用户端 的 YAML 配置文件结构非常简单: -

- -
-host: "an.example.com"
-port: 8080
-# autoConnect: false
-# tokenServerUrl: "https://example.org/token/"
-
- - - -

-     Assistant - 主控端 也有 YAML 配置文件。 -
-

- -

-     YAML 配置文件可以分别以 assisted.yamlassistant.yaml 的名称保存在 Dayon! 主目录、用户目录 - 或与 .jar.exe 文件相同的目录中。 - 在存在多个 YAML 配置文件的情况下,这些位置的优先级也按此顺序排列(第一个优先)。 -

- -

公共令牌服务器

- -

-     下面是可供免费使用的公共令牌服务器列表。 -
-     您想贡献您的 RVS 并添加到列表中吗? - 请告诉我!! -

-     点击链接以验证令牌服务器是否可用。如果直接显示版本号,则表示该服务器处于活动状态。 -

- -

-     您可以在 此处 找到有关如何自托管令牌服务器的说明。 -

- -
- -
- - diff --git a/docs/zh_support.html b/docs/zh_support.html deleted file mode 100644 index 75f48bce..00000000 --- a/docs/zh_support.html +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - Dayon! - 为您的家人和朋友提供远程协助 - - - - - - - -
-
- DE - FR - SV - EN -
- -
-

支持

-

-     非常欢迎您的反馈!如有问题,请在 GitHub 上提出或开启新的Issue 。 -

Dayon! 配置目录

-

-     Dayon! 会在当前登录用户的 用户文件夹 下或者 JAVA属性中的user.home 创建一个 .dayon 文件夹, - 用于存放 Dayon! 的用户配置和日志文件。 -

CRC效验

-

-     在用户端(Assisted),屏幕被分成不同的区域,这里我们称为 tiles (译者注:这里咱们就翻译成“图块”好啦)。只有那些 - 变更过的“图块”才会被发送到主控端(Assistant)。为了判断“图块”是否有变动,我通过对比同个“图块”前后的CRC编码 - 值(一个用来表示“图块”像素的唯一整数)是否一致。这个方法在效率方面并不完美,因此可能导致某个“图块”已变更,却未同步到主控端(Assistant)。 -

-     目前,我仅在对极少数像素进行强力测试时出现该问题,至于视觉上,倒是看不出有什么严重问题。 - 但是,如果这个问题已经严重影响到了你的使用体验,请先尝试点击屏幕捕获复位按钮(垃圾箱图标) - 进行画面修复(清理缓存,重新捕获屏幕),如果没有奏效请尝试重启用户端(Assisted)。 -

状态统计

- Dayon! Assistant : Statistics -

    除键盘布局外,主控器(Assistant)下方的状态栏还显示一组计数器。 -

    -
  1. 网络带宽使用情况 -
  2. 压缩比:初始捕获(仅差异)已被压缩的次数 -
  3. “图块”数量:通过网络传输的“图块”数量以及缓存命中率。 -
  4. 跳过的捕获:由于屏幕捕获间隔设置过低(即主控端Assistant-首选项-屏幕捕获中的屏幕捕获间隔设置太低)导致远程计算机无法捕获的画面数量。为了减少画面丢失,你必须增加屏幕捕获间隔,增大 Assistant-首选项-屏幕捕获 中的捕获间隔值。 -
  5. 合并的“图块”:传输前就被合并的截屏。这是由于设置的屏幕捕获频率对当前所选的压缩方法来说太高了(压缩速度 << 捕获速度)。为了减少由此导致的画面丢失(或失真),你必须提高 主控端Assistant-首选项-屏幕捕获中的屏幕捕获间隔 或 更改 主控端Assistant-首选项-压缩-压缩算法 使用更快的压缩算法。 -
  6. 内存 -
  7. 会话时长 -
- -

证书指纹

-

-     为了防止“中间人”攻击,显示连接两侧的证书指纹。 - 两个指纹必须匹配 —— 如果指纹不匹配,或许有什么异常的事情发生(比如遭到“中间人”攻击、网络环境不安全)。 - 此附加安全功能在 Dayon! 版本 13 引入。 -

-

- 指纹 -

-

-     注意:为了确保与版本 13 之前的旧客户端的连接,兼容模式 - compatibility 需要激活。
-     这只是一个临时解决方案,请尽快更新您的客户端。 -

- -

连接建立

-

-     译者注:图片所示仅供参考,中国大陆用户可能因为没有固定的公网 IP 而使用不了访问代码功能。 -

-

- Dayon! connection diagram -

-
- -
- - diff --git a/pom.xml b/pom.xml index df4c9d1f..919dfa78 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,6 @@ https://sonarcloud.io 1.10 5.10.0 - 1.3.1 5.11.3 5.14.2 @@ -78,6 +77,87 @@ + + deb + + true + + + + + org.apache.maven.plugins + maven-clean-plugin + 3.1.0 + + + clean-package + clean + + clean + + + + + ${basedir}/dist + + **/* + + + + + + + + + com.aerse.maven + deb-maven-plugin + 1.16 + + + create-deb + install + + package + + + + + root + staff + /usr/bin/ + + >=2:1.8-56 + + false + false + ${basedir}/debian/copyright + + + ${basedir}/dist/dayon.png + dayon.png + + + ${basedir}/dist/dayon.jar + dayon.jar + + + ${basedir}/dist/dayon.sh + dayon.sh + + + ${basedir}/dist/dayon_assisted.sh + dayon_assisted.sh + + + ${basedir}/resources/deb/ + deb + + + + + + + default @@ -130,7 +210,7 @@ ${dayon.mainClass} - Dayon! + Fensterkitt ${project.version} all-permissions true @@ -158,12 +238,6 @@ META-INF/** - - com.dosse.upnp:WaifUPnP - - META-INF/** - - net.java.dev.jna:jna @@ -262,8 +336,31 @@ + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + + chmod + package + + exec + + + chmod + + +x + ${basedir}/dist/dayon.sh + ${basedir}/dist/dayon_assisted.sh + ${basedir}/dist/setup.sh + + + + + - \ No newline at end of file + diff --git a/resources/dayon.png b/resources/dayon.png index f91580e4..240d8488 100644 Binary files a/resources/dayon.png and b/resources/dayon.png differ diff --git a/snap/snapcraft.core18.yaml b/snap/snapcraft.core18.yaml deleted file mode 100644 index d5606239..00000000 --- a/snap/snapcraft.core18.yaml +++ /dev/null @@ -1,82 +0,0 @@ -name: dayon -title: Dayon! -adopt-info: dayon -summary: An easy-to-use, cross-platform remote desktop assistance solution -description: | - An easy-to-use, cross-platform remote desktop support solution for everyone. - It can be used as free alternative to various commercial remote desktop and remote assistance products. - Its key features are - - no router or network configuration required on the assisted side - - friendly, multilingual (de/en/es/fr/it/ru/sv/tr/zh) user interface - - assistant and assisted functionality in one package - - secure, end-to-end encrypted communication (TLS 1.3) -license: GPL-3.0 -grade: stable -base: core18 -confinement: strict - -apps: - assisted: - extensions: - [gnome-3-28] - environment: - JAVA_HOME: $SNAP/usr/lib/jvm/java-11-openjdk-$SNAP_ARCH - PATH: $JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH - command: bin/dayon.launcher $SNAP/jar/dayon.jar $1 $2 $3 $4 $5 - desktop: ../parts/dayon/build/target/dayon.assisted.desktop - plugs: - [home, network, network-bind, desktop] - - assistant: - extensions: - [gnome-3-28] - environment: - JAVA_HOME: $SNAP/usr/lib/jvm/java-11-openjdk-$SNAP_ARCH - PATH: $JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH - command: bin/dayon.launcher $SNAP/jar/dayon.jar assistant $1 $2 $3 - desktop: ../parts/dayon/build/target/dayon.assistant.desktop - plugs: - [home, network, network-bind, desktop] - - browser: - extensions: - [gnome-3-28] - command: bin/dayon.browser - plugs: - [home, network, desktop] - -parts: - dayon: - plugin: maven - source: https://github.com/retgal/dayon.git - source-tag: master - source-type: git - maven-options: - [-Psnap] - - build-packages: - [default-jre] - - override-build: | - snapcraftctl build - cp target/dayon.browser $SNAPCRAFT_PART_INSTALL/bin/ - cp target/dayon.launcher $SNAPCRAFT_PART_INSTALL/bin/ - cp target/dayon.png $SNAPCRAFT_PART_INSTALL/bin/ - - override-pull: | - snapcraftctl pull - snapcraftctl set-version "$(git describe --tags | sed 's/^v//' | cut -d "-" -f1)" - - filesets: - exclude-original-jar: - [-jar/original-dayon.jar] - - stage: - [$exclude-original-jar] - - stage-packages: - [default-jre] - - override-prime: | - snapcraftctl prime - rm -vf usr/lib/jvm/java-11-openjdk-*/lib/security/blacklisted.certs diff --git a/snap/snapcraft.core24.yaml b/snap/snapcraft.core24.yaml deleted file mode 100644 index cd02feb6..00000000 --- a/snap/snapcraft.core24.yaml +++ /dev/null @@ -1,92 +0,0 @@ -name: dayon -title: Dayon! -adopt-info: dayon -summary: An easy-to-use, cross-platform remote desktop assistance solution -description: | - An easy-to-use, cross-platform remote desktop support solution for everyone. - It can be used as free alternative to various commercial remote desktop and remote assistance products. - Its key features are - - assistant and assisted functionality in one package - - secure, end-to-end encrypted communication (TLS 1.3) - - no network configuration required on the assisted side - - friendly, multilingual user interface - - respects your privacy 100% - no registration required - - available for Linux, Windows and macOS -license: GPL-3.0 -grade: stable -base: core24 -confinement: strict -platforms: - amd64: - arm64: - armhf: - riscv64: - -lint: - ignore: - - library: - - usr/lib/jvm/java-*/lib/*.so - -apps: - assisted: - extensions: - [gnome] - environment: - JAVA_HOME: $SNAP/usr/lib/jvm/java-21-openjdk-$SNAP_ARCH - PATH: $JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH - DISABLE_WAYLAND: 1 - command: bin/dayon.launcher $SNAP/jar/dayon.jar $1 $2 $3 $4 $5 - desktop: ../parts/dayon/build/target/dayon.assisted.desktop - plugs: - [home, network, desktop] - - assistant: - extensions: - [gnome] - environment: - JAVA_HOME: $SNAP/usr/lib/jvm/java-21-openjdk-$SNAP_ARCH - PATH: $JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH - command: bin/dayon.launcher $SNAP/jar/dayon.jar assistant $1 $2 $3 - desktop: ../parts/dayon/build/target/dayon.assistant.desktop - plugs: - [home, network, desktop] - - browser: - extensions: - [gnome] - command: bin/dayon.browser - plugs: - [home, network, desktop] - -parts: - dayon: - plugin: maven - source: https://github.com/retgal/dayon.git - source-tag: master - source-type: git - maven-parameters: - [-Psnap] - - override-pull: | - craftctl default - craftctl set version=$(git describe --tags | sed 's/^v//' | cut -d "-" -f1) - - build-packages: - [openjdk-21-jdk, maven] - - override-build: | - craftctl default - cp target/dayon.browser $CRAFT_PART_INSTALL/bin/ - cp target/dayon.launcher $CRAFT_PART_INSTALL/bin/ - cp target/dayon.png $CRAFT_PART_INSTALL/bin/ - rm $CRAFT_PART_INSTALL/jar/original-dayon.jar - rm $CRAFT_PART_INSTALL/jar/WaifUPnP-*.jar - rm $CRAFT_PART_INSTALL/jar/xz-*.jar - - stage-packages: - [openjdk-21-jre] - - override-prime: | - craftctl default - rm -r usr/share/doc - rm -r usr/share/man \ No newline at end of file diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml deleted file mode 100644 index 86ae8b1a..00000000 --- a/snap/snapcraft.yaml +++ /dev/null @@ -1,96 +0,0 @@ -name: dayon -title: Dayon! -adopt-info: dayon -summary: An easy-to-use, cross-platform remote desktop assistance solution -description: | - An easy-to-use, cross-platform remote desktop support solution for everyone. - It can be used as free alternative to various commercial remote desktop and remote assistance products. - Its key features are - - assistant and assisted functionality in one package - - secure, end-to-end encrypted communication (TLS 1.3) - - no network configuration required on the assisted side - - friendly, multilingual user interface - - respects your privacy 100% - no registration required - - available for Linux, Windows and macOS -license: GPL-3.0 -grade: stable -base: core22 -confinement: strict -architectures: - - build-on: [amd64] - build-for: [amd64] - - build-on: [arm64] - build-for: [arm64] - - build-on: [armhf] - build-for: [armhf] - - build-on: [riscv64] - build-for: [riscv64] - -lint: - ignore: - - library: - - usr/lib/jvm/java-*/lib/*.so - -apps: - assisted: - extensions: - [gnome] - environment: - JAVA_HOME: $SNAP/usr/lib/jvm/java-21-openjdk-$SNAP_ARCH - PATH: $JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH - DISABLE_WAYLAND: 1 - command: bin/dayon.launcher $SNAP/jar/dayon.jar $1 $2 $3 $4 $5 - desktop: ../parts/dayon/build/target/dayon.assisted.desktop - plugs: - [home, network, desktop] - - assistant: - extensions: - [gnome] - environment: - JAVA_HOME: $SNAP/usr/lib/jvm/java-21-openjdk-$SNAP_ARCH - PATH: $JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH - command: bin/dayon.launcher $SNAP/jar/dayon.jar assistant $1 $2 $3 - desktop: ../parts/dayon/build/target/dayon.assistant.desktop - plugs: - [home, network, desktop] - - browser: - extensions: - [gnome] - command: bin/dayon.browser - plugs: - [home, network, desktop] - -parts: - dayon: - plugin: maven - source: https://github.com/retgal/dayon.git - source-tag: master - source-type: git - maven-parameters: - [-Psnap] - - override-pull: | - craftctl default - craftctl set version=$(git describe --tags | sed 's/^v//' | cut -d "-" -f1) - - build-packages: - [openjdk-21-jdk, maven] - - override-build: | - craftctl default - cp target/dayon.browser $CRAFT_PART_INSTALL/bin/ - cp target/dayon.launcher $CRAFT_PART_INSTALL/bin/ - cp target/dayon.png $CRAFT_PART_INSTALL/bin/ - rm $CRAFT_PART_INSTALL/jar/original-dayon.jar - rm $CRAFT_PART_INSTALL/jar/WaifUPnP-*.jar - rm $CRAFT_PART_INSTALL/jar/xz-*.jar - - stage-packages: - [openjdk-21-jre] - - override-prime: | - craftctl default - rm -r usr/share/doc - rm -r usr/share/man \ No newline at end of file diff --git a/src/main/java/mpo/dayon/assistant/AssistantRunner.java b/src/main/java/mpo/dayon/assistant/AssistantRunner.java deleted file mode 100644 index 725e2471..00000000 --- a/src/main/java/mpo/dayon/assistant/AssistantRunner.java +++ /dev/null @@ -1,26 +0,0 @@ -package mpo.dayon.assistant; - -import mpo.dayon.assistant.gui.Assistant; -import mpo.dayon.common.Runner; - -import java.util.Arrays; - -import static mpo.dayon.common.Runner.readPresetFile; - -public class AssistantRunner { - - public static void main(String[] args) { - Runner.main(appendAssistant(args)); - } - - private static String[] appendAssistant(String[] args) { - String[] combined = Arrays.copyOf(args, args.length + 1); - String[] additional = new String[]{"assistant"}; - System.arraycopy(additional, 0, combined, args.length, 1); - return combined; - } - - public static void launchAssistant(String language) { - new Assistant(readPresetFile("assistant.yaml").get("tokenServerUrl"), language); - } -} diff --git a/src/main/java/mpo/dayon/assistant/control/ControlEngine.java b/src/main/java/mpo/dayon/assistant/control/ControlEngine.java deleted file mode 100644 index 3ed9159b..00000000 --- a/src/main/java/mpo/dayon/assistant/control/ControlEngine.java +++ /dev/null @@ -1,142 +0,0 @@ -package mpo.dayon.assistant.control; - -import java.awt.event.MouseEvent; -import java.util.HashMap; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; - -import mpo.dayon.assistant.gui.AssistantFrameListener; -import mpo.dayon.assistant.network.NetworkAssistantEngine; -import mpo.dayon.common.concurrent.DefaultThreadFactoryEx; -import mpo.dayon.common.concurrent.Executable; -import mpo.dayon.common.log.Log; -import mpo.dayon.common.network.message.NetworkKeyControlMessage; -import mpo.dayon.common.network.message.NetworkMouseControlMessage; - -import static java.lang.String.format; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static mpo.dayon.common.network.message.NetworkKeyControlMessage.KeyState.PRESSED; -import static mpo.dayon.common.network.message.NetworkKeyControlMessage.KeyState.RELEASED; - -public class ControlEngine implements AssistantFrameListener { - private final NetworkAssistantEngine network; - - private final ThreadPoolExecutor executor; - - public ControlEngine(NetworkAssistantEngine network) { - this.network = network; - executor = new ThreadPoolExecutor(1, 1, 0L, MILLISECONDS, new LinkedBlockingQueue<>()); - executor.setThreadFactory(new DefaultThreadFactoryEx("ControlEngine")); - } - - @Override - public void onMouseMove(final int xs, final int ys) { - executor.execute(new Executable(executor) { - @Override - protected void execute() { - network.sendMouseControl(new NetworkMouseControlMessage(xs, ys)); - } - }); - } - - @Override - public void onMousePressed(final int xs, final int ys, final int button) { - executor.execute(new Executable(executor) { - @Override - protected void execute() { - int xbutton = getActingMouseButton(button); - if (xbutton != NetworkMouseControlMessage.UNDEFINED) { - network.sendMouseControl(new NetworkMouseControlMessage(xs, ys, NetworkMouseControlMessage.ButtonState.PRESSED, xbutton)); - } - } - }); - } - - @Override - public void onMouseReleased(final int x, final int y, final int button) { - executor.execute(new Executable(executor) { - @Override - protected void execute() { - int xbutton = getActingMouseButton(button); - if (xbutton != NetworkMouseControlMessage.UNDEFINED) { - network.sendMouseControl(new NetworkMouseControlMessage(x, y, NetworkMouseControlMessage.ButtonState.RELEASED, xbutton)); - } - } - }); - } - - private int getActingMouseButton(final int button) { - if (MouseEvent.BUTTON1 == button) { - return NetworkMouseControlMessage.BUTTON1; - } - if (MouseEvent.BUTTON2 == button) { - return NetworkMouseControlMessage.BUTTON2; - } - if (MouseEvent.BUTTON3 == button) { - return NetworkMouseControlMessage.BUTTON3; - } - return NetworkMouseControlMessage.UNDEFINED; - } - - @Override - public void onMouseWheeled(final int x, final int y, final int rotations) { - executor.execute(new Executable(executor) { - @Override - protected void execute() { - network.sendMouseControl(new NetworkMouseControlMessage(x, y, rotations)); - } - }); - } - - /** - * Fix missing pair'd PRESSED event from RELEASED - */ - private final HashMap pressedKeys = new HashMap<>(); - - /** - * From AWT thread (!) - */ - @Override - public void onKeyPressed(final int keyCode, final char keyChar) { - executor.execute(new Executable(executor) { - @Override - protected void execute() { - pressedKeys.put(keyCode, keyChar); - network.sendKeyControl(new NetworkKeyControlMessage(PRESSED, keyCode, keyChar)); - } - }); - } - - /** - * From AWT thread (!) - */ - @Override - public void onKeyReleased(final int keyCode, final char keyChar) { - // ------------------------------------------------------------------------------------------------------------- - // E.g., Windows + R : [Windows.PRESSED] and then the focus is LOST => - // missing RELEASED events - // - // Currently trying to lease the 'assisted' in a consistent state - not - // sure I should send the - // [Windows] key and the like (e.g.,CTRL-ALT-DEL, etc...) at all ... - // ------------------------------------------------------------------------------------------------------------- - if (keyCode == -1) { - Log.warn(format("Got keyCode %s keyChar '%s' - releasing all keys", keyCode, keyChar)); - pressedKeys.forEach(this::onKeyReleased); - return; - } - - if (!pressedKeys.containsKey(keyCode)) { - Log.warn(format("Not releasing unpressed keyCode %s keyChar '%s'", keyCode, keyChar)); - return; - } - - executor.execute(new Executable(executor) { - @Override - protected void execute() { - pressedKeys.remove(keyCode); - network.sendKeyControl(new NetworkKeyControlMessage(RELEASED, keyCode, keyChar)); - } - }); - } -} diff --git a/src/main/java/mpo/dayon/assistant/decompressor/DeCompressorEngine.java b/src/main/java/mpo/dayon/assistant/decompressor/DeCompressorEngine.java deleted file mode 100644 index 4699f4ae..00000000 --- a/src/main/java/mpo/dayon/assistant/decompressor/DeCompressorEngine.java +++ /dev/null @@ -1,128 +0,0 @@ -package mpo.dayon.assistant.decompressor; - -import java.io.IOException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.Semaphore; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -import mpo.dayon.common.compressor.CompressorEngineConfiguration; -import mpo.dayon.common.capture.Capture; -import mpo.dayon.common.concurrent.DefaultThreadFactoryEx; -import mpo.dayon.common.concurrent.Executable; -import mpo.dayon.common.error.FatalErrorHandler; -import mpo.dayon.common.event.Listeners; -import mpo.dayon.common.log.Log; -import mpo.dayon.common.network.message.NetworkCaptureMessage; -import mpo.dayon.common.network.message.NetworkCaptureMessageHandler; -import mpo.dayon.common.squeeze.Compressor; -import mpo.dayon.common.squeeze.NullTileCache; -import mpo.dayon.common.squeeze.RegularTileCache; -import mpo.dayon.common.squeeze.TileCache; - -public class DeCompressorEngine implements NetworkCaptureMessageHandler { - private final Listeners listeners = new Listeners<>(); - - private ThreadPoolExecutor executor; - - private Semaphore semaphore; - - private TileCache cache; - - public DeCompressorEngine(DeCompressorEngineListener listener) { - listeners.add(listener); - } - - public void start(int queueSize) { - // THREAD = 1 - // - // The parallel processing is within the de-compressor itself - here we - // want - // to ensure a certain order of processing - if need more than one - // thread then - // have a look how the de-compressed data are sent to the GUI (!) - - executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); - - executor.setThreadFactory(new DefaultThreadFactoryEx("DeCompressorEngine")); - - // Rejection Policy - // - // Blocking pattern when queue full; that means we're not decompressing - // fast enough; when our queue is full - // then the network receiving thread is going to stop reading from the - // assisted side which in turn is going - // to slow down sending its capture leaving us some time to catch up. - // - // Having our queue full is quite unlikely; I would say the network will - // limit the number of capture/tiles - // being sent and I guess that decompressing is much faster then - // compressing (unless our PC is quite weak - // compared to the assisted one; let's not forget the JAVA capture is - // awful regarding the performance as - // well => should be fine here. - - semaphore = new Semaphore(queueSize, true); - } - - /** - * Should not block as called from the network incoming message thread (!) - */ - @Override - public void handleCapture(NetworkCaptureMessage capture) { - try { - semaphore.acquire(); - executor.execute(new MyExecutable(executor, semaphore, capture)); - } catch (InterruptedException ex) { - FatalErrorHandler.bye("The [" + Thread.currentThread().getName() + "] thread is has been interrupted!", ex); - Thread.currentThread().interrupt(); - } catch (RejectedExecutionException ex) { - semaphore.release(); // unlikely as we have an unbounded queue - // (!) - } - } - - private class MyExecutable extends Executable { - private final NetworkCaptureMessage message; - - MyExecutable(ExecutorService executor, Semaphore semaphore, NetworkCaptureMessage message) { - super(executor, semaphore); - - this.message = message; - } - - @Override - protected void execute() throws IOException { - try { - final Compressor compressor = Compressor.get(message.getCompressionMethod()); - - final CompressorEngineConfiguration configuration = message.getCompressionConfiguration(); - if (configuration != null) { - cache = configuration.useCache() ? new RegularTileCache(configuration.getCacheMaxSize(), configuration.getCachePurgeSize()) - : new NullTileCache(); - - Log.info("De-Compressor engine has been reconfigured [tile:" + message.getId() + "]" + configuration); - } - - cache.clearHits(); - - final Capture capture = compressor.decompress(cache, message.getPayload()); - final double ratio = capture - .computeCompressionRatio(1/* magic-number */ + message.getWireSize()); - - fireOnDeCompressed(capture, cache.getHits(), ratio); - } finally { - if (cache != null) { - cache.onCaptureProcessed(); - } - } - } - - private void fireOnDeCompressed(Capture capture, int cacheHits, double compressionRatio) { - listeners.getListeners().forEach(listener -> listener.onDeCompressed(capture, cacheHits, compressionRatio)); - } - } - -} diff --git a/src/main/java/mpo/dayon/assistant/decompressor/DeCompressorEngineListener.java b/src/main/java/mpo/dayon/assistant/decompressor/DeCompressorEngineListener.java deleted file mode 100644 index e34fb62a..00000000 --- a/src/main/java/mpo/dayon/assistant/decompressor/DeCompressorEngineListener.java +++ /dev/null @@ -1,11 +0,0 @@ -package mpo.dayon.assistant.decompressor; - -import mpo.dayon.common.capture.Capture; -import mpo.dayon.common.event.Listener; - -public interface DeCompressorEngineListener extends Listener { - /** - * Called from within a de-compressor engine thread (!) - */ - void onDeCompressed(Capture capture, int cacheHits, double compressionRatio); -} diff --git a/src/main/java/mpo/dayon/assistant/gui/Assistant.java b/src/main/java/mpo/dayon/assistant/gui/Assistant.java deleted file mode 100644 index 53095a3a..00000000 --- a/src/main/java/mpo/dayon/assistant/gui/Assistant.java +++ /dev/null @@ -1,938 +0,0 @@ -package mpo.dayon.assistant.gui; - -//import com.dosse.upnp.UPnP; -import mpo.dayon.assistant.control.ControlEngine; -import mpo.dayon.assistant.decompressor.DeCompressorEngine; -import mpo.dayon.assistant.decompressor.DeCompressorEngineListener; -import mpo.dayon.assistant.network.NetworkAssistantEngineConfiguration; -import mpo.dayon.assistant.network.NetworkAssistantEngine; -import mpo.dayon.assistant.network.NetworkAssistantEngineListener; -import mpo.dayon.assistant.utils.NetworkUtilities; -import mpo.dayon.common.capture.CaptureEngineConfiguration; -import mpo.dayon.common.compressor.CompressorEngineConfiguration; -import mpo.dayon.common.capture.Capture; -import mpo.dayon.common.capture.Gray8Bits; -import mpo.dayon.common.error.FatalErrorHandler; -import mpo.dayon.common.gui.common.DialogFactory; -import mpo.dayon.common.gui.common.ImageNames; -import mpo.dayon.common.log.Log; -import mpo.dayon.common.monitoring.counter.*; -import mpo.dayon.common.network.TransferableImage; -import mpo.dayon.common.network.message.NetworkMouseLocationMessageHandler; -import mpo.dayon.common.squeeze.CompressionMethod; -import mpo.dayon.common.network.FileUtilities; -import mpo.dayon.common.utils.Language; -import mpo.dayon.common.version.Version; - -import javax.swing.*; -import java.awt.*; -import java.awt.datatransfer.*; -import java.awt.event.ActionEvent; -import java.awt.geom.AffineTransform; -import java.awt.image.AffineTransformOp; -import java.awt.image.BufferedImage; -import java.awt.image.ImagingOpException; -import java.io.File; -import java.io.IOException; -import java.net.Socket; -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.time.Duration; -import java.util.List; -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.stream.Stream; - -import static java.awt.image.BufferedImage.TYPE_BYTE_GRAY; -import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE; -import static java.lang.Math.*; -import static java.lang.String.format; -import static java.lang.String.valueOf; -import static javax.swing.SwingConstants.HORIZONTAL; -import static mpo.dayon.common.babylon.Babylon.translate; -import static mpo.dayon.common.gui.common.ImageUtilities.getOrCreateIcon; -import static mpo.dayon.common.utils.SystemUtilities.*; - -public class Assistant implements ClipboardOwner { - - private static final String PORT_PARAM = "?port=%s"; - private static final String WHATSMYIP_SERVER_URL = "https://fensterkitt.ch/dayon/whatismyip.php"; - private final String tokenServerUrl; - - private final NetworkAssistantEngine networkEngine; - - private BitCounter receivedBitCounter; - - private TileCounter receivedTileCounter; - - private SkippedTileCounter skippedTileCounter; - - private MergedTileCounter mergedTileCounter; - - private CaptureCompressionCounter captureCompressionCounter; - - private ArrayList> counters; - - private AssistantFrame frame; - - private AssistantConfiguration configuration; - - private final NetworkAssistantEngineConfiguration networkConfiguration; - - private CaptureEngineConfiguration captureEngineConfiguration; - - private CompressorEngineConfiguration compressorEngineConfiguration; - - private final Object prevBufferLOCK = new Object(); - - private final Object upnpEnabledLOCK = new Object(); - - private byte[] prevBuffer = null; - - private int prevWidth = -1; - - private int prevHeight = -1; - - private String token; - - private Boolean upnpEnabled; - - private String publicIp; - - private final AtomicBoolean compatibilityModeActive = new AtomicBoolean(false); - - public Assistant(String tokenServerUrl, String language) { - networkConfiguration = new NetworkAssistantEngineConfiguration(); - - if (tokenServerUrl != null) { - this.tokenServerUrl = tokenServerUrl + PORT_PARAM; - } else if (!networkConfiguration.getTokenServerUrl().isEmpty()) { - this.tokenServerUrl = networkConfiguration.getTokenServerUrl() + PORT_PARAM; - } else { - this.tokenServerUrl = DEFAULT_TOKEN_SERVER_URL + PORT_PARAM; - } - - if (!this.tokenServerUrl.startsWith(DEFAULT_TOKEN_SERVER_URL)) { - System.setProperty("dayon.custom.tokenServer", this.tokenServerUrl); - } - - this.configuration = new AssistantConfiguration(); - // has not been overridden by command line - if (language == null && !Locale.getDefault().getLanguage().equals(configuration.getLanguage())) { - Locale.setDefault(Locale.forLanguageTag(configuration.getLanguage())); - } - - initUpnp(); - - DeCompressorEngine decompressor = new DeCompressorEngine(new MyDeCompressorEngineListener()); - decompressor.start(8); - - NetworkMouseLocationMessageHandler mouseHandler = mouse -> frame.onMouseLocationUpdated(mouse.getX(), mouse.getY()); - networkEngine = new NetworkAssistantEngine(decompressor, mouseHandler, this); - networkEngine.configure(networkConfiguration); - networkEngine.addListener(new MyNetworkAssistantEngineListener()); - - captureEngineConfiguration = new CaptureEngineConfiguration(); - compressorEngineConfiguration = new CompressorEngineConfiguration(); - - final String lnf = getDefaultLookAndFeel(); - try { - UIManager.setLookAndFeel(lnf); - } catch (Exception ex) { - Log.warn("Could not set the [" + lnf + "] L&F!", ex); - } - initGui(); - } - - private void initGui() { - createCounters(); - if (frame != null) { - frame.setVisible(false); - } - frame = new AssistantFrame(createAssistantActions(), counters, createLanguageSelection(), compatibilityModeActive.get(), this); - FatalErrorHandler.attachFrame(frame); - frame.addListener(new ControlEngine(networkEngine)); - frame.setVisible(true); - } - - private void createCounters() { - receivedBitCounter = new BitCounter("receivedBits", translate("networkBandwidth")); - receivedBitCounter.start(1000); - receivedTileCounter = new TileCounter("receivedTiles", translate("receivedTileNumber")); - receivedTileCounter.start(1000); - skippedTileCounter = new SkippedTileCounter("skippedTiles", translate("skippedCaptureNumber")); - skippedTileCounter.start(1000); - mergedTileCounter = new MergedTileCounter("mergedTiles", translate("mergedCaptureNumber")); - mergedTileCounter.start(1000); - captureCompressionCounter = new CaptureCompressionCounter("captureCompression", translate("captureCompression")); - captureCompressionCounter.start(1000); - counters = new ArrayList<>(Arrays.asList(receivedBitCounter, receivedTileCounter, skippedTileCounter, mergedTileCounter, captureCompressionCounter)); - } - - public NetworkAssistantEngine getNetworkEngine() { - return networkEngine; - } - - private AssistantActions createAssistantActions() { - AssistantActions assistantActions = new AssistantActions(); - assistantActions.setIpAddressAction(createWhatIsMyIpAction()); - assistantActions.setCaptureEngineConfigurationAction(createCaptureConfigurationAction()); - assistantActions.setCompressionEngineConfigurationAction(createCompressionConfigurationAction()); - assistantActions.setResetAction(createResetAction()); - assistantActions.setTokenAction(createTokenAction()); - assistantActions.setRemoteClipboardRequestAction(createRemoteClipboardRequestAction()); - assistantActions.setRemoteClipboardSetAction(createRemoteClipboardUpdateAction()); - assistantActions.setScreenshotRequestAction(createScreenshotRequestAction()); - assistantActions.setStartAction(createStartAction()); - assistantActions.setStopAction(createStopAction()); - assistantActions.setToggleCompatibilityModeAction(createToggleCompatibilityModeAction()); - return assistantActions; - } - - private void stopNetwork() { - frame.hideSpinner(); - networkEngine.cancel(); - } - - @Override - public void lostOwnership(Clipboard clipboard, Transferable transferable) { - Log.error("Lost clipboard ownership"); - } - - private Action createWhatIsMyIpAction() { - final Action ip = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ev) { - final JButton button = (JButton) ev.getSource(); - final JPopupMenu choices = new JPopupMenu(); - - final JMenuItem publicIpItem = new JMenuItem(translate("ipAddressPublic", publicIp)); - publicIpItem.addActionListener(ev15 -> button.setText(publicIp)); - choices.add(publicIpItem); - - if (publicIp == null) { - CompletableFuture.supplyAsync(() -> { - try { - resolvePublicIp(); - } catch (IOException | InterruptedException ex) { - Log.error("Could not determine public IP", ex); - JOptionPane.showMessageDialog(frame, translate("ipAddress.msg2"), translate("ipAddress"), JOptionPane.ERROR_MESSAGE); - if (ex instanceof InterruptedException) { - Thread.currentThread().interrupt(); - } - } - return publicIp; - }).thenAcceptAsync(ip -> { - if (ip != null) { - button.setText(ip); - publicIpItem.setText(translate("ipAddressPublic", ip)); - } - }); - } - - NetworkUtilities.getInetAddresses().stream().map(JMenuItem::new).forEach(item -> { - item.addActionListener(ev14 -> button.setText(item.getText())); - choices.add(item); - }); - - choices.addSeparator(); - choices.add(getJMenuItemCopyIpAndPort(button)); - - // -- display the menu - // --------------------------------------------------------------------------------- - - final Point where = MouseInfo.getPointerInfo().getLocation(); - - SwingUtilities.convertPointFromScreen(where, frame); - choices.show(frame, where.x, where.y); - final Point frameLocation = frame.getLocationOnScreen(); - final Point toolbarLocation = frame.getToolBar().getLocationOnScreen(); - choices.setLocation(frameLocation.x + 20, toolbarLocation.y + frame.getToolBar().getHeight()); - } - - private void resolvePublicIp() throws IOException, InterruptedException { - // HttpClient doesn't implement AutoCloseable nor close before Java 21! - @java.lang.SuppressWarnings("squid:S2095") - HttpClient client = HttpClient.newHttpClient(); - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(WHATSMYIP_SERVER_URL)) - .timeout(Duration.ofSeconds(5)) - .build(); - publicIp = client.send(request, HttpResponse.BodyHandlers.ofString()).body().trim(); - } - }; - ip.putValue("DISPLAY_NAME", publicIp); // always a selection - // ... - ip.putValue(Action.SHORT_DESCRIPTION, translate("ipAddress.msg1")); - ip.putValue(Action.SMALL_ICON, getOrCreateIcon(ImageNames.NETWORK_ADDRESS)); - return ip; - } - - private JMenuItem getJMenuItemCopyIpAndPort(JButton button) { - final JMenuItem menuItem = new JMenuItem(translate("copy.msg")); - menuItem.addActionListener(ev12 -> { - final String url = button.getText() + " " + networkConfiguration.getPort(); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(url), this); - }); - return menuItem; - } - - private Action createRemoteClipboardRequestAction() { - final Action getRemoteClipboard = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ev) { - sendRemoteClipboardRequest(); - } - }; - getRemoteClipboard.putValue(Action.SHORT_DESCRIPTION, translate("clipboard.getRemote")); - getRemoteClipboard.putValue(Action.SMALL_ICON, getOrCreateIcon(ImageNames.DOWN)); - return getRemoteClipboard; - } - - private Action createRemoteClipboardUpdateAction() { - final Action setRemoteClipboard = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ev) { - sendLocalClipboard(); - } - }; - setRemoteClipboard.putValue(Action.SHORT_DESCRIPTION, translate("clipboard.setRemote")); - setRemoteClipboard.putValue(Action.SMALL_ICON, getOrCreateIcon(ImageNames.UP)); - return setRemoteClipboard; - } - - private void sendLocalClipboard() { - Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - Transferable content = clipboard.getContents(this); - - if (content == null) return; - - try { - if (content.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { - // noinspection unchecked - List files = (List) clipboard.getData(DataFlavor.javaFileListFlavor); - if (!files.isEmpty()) { - final long totalFilesSize = FileUtilities.calculateTotalFileSize(files); - Log.debug("Clipboard contains files with size: %s", () -> String.valueOf(totalFilesSize)); - // Ok as very few of that (!) - new Thread(() -> networkEngine.sendClipboardFiles(files, totalFilesSize, files.get(0).getParent()), "sendClipboardFiles").start(); - frame.onClipboardSending(); - } - } else if (content.isDataFlavorSupported(DataFlavor.imageFlavor) ){ - final BufferedImage image = (BufferedImage) clipboard.getData(DataFlavor.imageFlavor); - Log.debug("Clipboard contains graphics: %s", () -> format("%dx%d", image.getWidth(), image.getHeight())); - // Ok as very few of that (!) - new Thread(() -> networkEngine.sendClipboardGraphic(new TransferableImage(image)), "sendClipboardGraphic").start(); - frame.onClipboardSending(); - } else if (content.isDataFlavorSupported(DataFlavor.stringFlavor)) { - String text = valueOf(clipboard.getData(DataFlavor.stringFlavor)); - Log.debug("Clipboard contains text: " + text); - // Ok as very few of that (!) - new Thread(() -> networkEngine.sendClipboardText(text), "sendClipboardText").start(); - frame.onClipboardSending(); - } else { - Log.debug("Clipboard contains no supported data"); - } - } catch (IOException | UnsupportedFlavorException ex) { - Log.error("Clipboard error " + ex.getMessage()); - frame.onClipboardSent(); - } - } - - /** - * Should not block (!) - */ - private void sendRemoteClipboardRequest() { - Log.info("Requesting remote clipboard"); - frame.onClipboardRequested(); - // Ok as very few of that (!) - new Thread(networkEngine::sendRemoteClipboardRequest, "RemoteClipboardRequest").start(); - } - - private Action createCaptureConfigurationAction() { - final Action configure = new AbstractAction() { - - @Override - public void actionPerformed(ActionEvent ev) { - JFrame captureFrame = (JFrame) SwingUtilities.getRoot((Component) ev.getSource()); - - final JPanel pane = new JPanel(); - pane.setLayout(new GridLayout(3, 2, 10, 10)); - - final JLabel tickLbl = new JLabel(translate("tick")); - tickLbl.setToolTipText(translate("tick.tooltip")); - final JSlider tickMillisSlider = new JSlider(HORIZONTAL, 50, 1000, captureEngineConfiguration.getCaptureTick()); - final Properties tickLabelTable = new Properties(3); - JLabel actualTick = new JLabel(format(" %dms ", tickMillisSlider.getValue())); - tickLabelTable.put(50, new JLabel(translate("min"))); - tickLabelTable.put(550, actualTick); - tickLabelTable.put(1000, new JLabel(translate("max"))); - tickMillisSlider.setLabelTable(tickLabelTable); - tickMillisSlider.setMajorTickSpacing(50); - tickMillisSlider.setPaintTicks(true); - tickMillisSlider.setPaintLabels(true); - pane.add(tickLbl); - pane.add(tickMillisSlider); - - final JLabel grayLevelsLbl = new JLabel(translate("grays")); - final JSlider grayLevelsSlider = new JSlider(HORIZONTAL, 0, 6, 6 - captureEngineConfiguration.getCaptureQuantization().ordinal()); - final Properties grayLabelTable = new Properties(3); - JLabel actualLevels = new JLabel(format(" %d ", toGrayLevel(grayLevelsSlider.getValue()).getLevels())); - if (!networkConfiguration.isMonochromePeer()) { - grayLabelTable.put(0, new JLabel(translate("min"))); - grayLabelTable.put(3, actualLevels); - } else { - grayLabelTable.put(3, new JLabel(translate("min"))); - grayLevelsSlider.setMinimum(3); - } - grayLabelTable.put(6, new JLabel(translate("max"))); - grayLevelsSlider.setLabelTable(grayLabelTable); - grayLevelsSlider.setMajorTickSpacing(1); - grayLevelsSlider.setPaintTicks(true); - grayLevelsSlider.setPaintLabels(true); - grayLevelsSlider.setSnapToTicks(true); - pane.add(grayLevelsLbl).setEnabled(!captureEngineConfiguration.isCaptureColors()); - pane.add(grayLevelsSlider).setEnabled(!captureEngineConfiguration.isCaptureColors()); - - final JLabel colorsLbl = new JLabel(translate("colors")); - final JCheckBox colorsCb = new JCheckBox(); - colorsCb.setSelected(captureEngineConfiguration.isCaptureColors()); - pane.add(colorsLbl).setEnabled(!networkConfiguration.isMonochromePeer()); - pane.add(colorsCb).setEnabled(!networkConfiguration.isMonochromePeer()); - - tickMillisSlider.addChangeListener(e -> { - actualTick.setText(tickMillisSlider.getValue() < 1000 ? format("%dms", tickMillisSlider.getValue()) : "1s"); - if (!tickMillisSlider.getValueIsAdjusting()) { - sendCaptureConfiguration(new CaptureEngineConfiguration(tickMillisSlider.getValue(), - toGrayLevel(grayLevelsSlider.getValue()), captureEngineConfiguration.isCaptureColors())); - } - }); - grayLevelsSlider.addChangeListener(e -> { - actualLevels.setText(format("%d", toGrayLevel(grayLevelsSlider.getValue()).getLevels())); - if (!grayLevelsSlider.getValueIsAdjusting() && !captureEngineConfiguration.isCaptureColors()) { - sendCaptureConfiguration(new CaptureEngineConfiguration(tickMillisSlider.getValue(), - toGrayLevel(grayLevelsSlider.getValue()), false)); - } - }); - colorsCb.addActionListener(e -> { - grayLevelsLbl.setEnabled(!colorsCb.isSelected()); - grayLevelsSlider.setEnabled(!colorsCb.isSelected()); - }); - - final boolean ok = DialogFactory.showOkCancel(captureFrame, translate("capture"), pane, true, null); - - if (ok) { - final CaptureEngineConfiguration newCaptureEngineConfiguration = new CaptureEngineConfiguration(tickMillisSlider.getValue(), - toGrayLevel(grayLevelsSlider.getValue()), colorsCb.isSelected()); - updateCaptureConfiguration(newCaptureEngineConfiguration); - } - } - }; - configure.putValue(Action.SHORT_DESCRIPTION, translate("capture.settings")); - configure.putValue(Action.SMALL_ICON, getOrCreateIcon(ImageNames.CAPTURE_SETTINGS)); - return configure; - } - - private void updateCaptureConfiguration(CaptureEngineConfiguration newCaptureEngineConfiguration) { - if (!newCaptureEngineConfiguration.equals(captureEngineConfiguration)) { - captureEngineConfiguration = newCaptureEngineConfiguration; - captureEngineConfiguration.persist(); - sendCaptureConfiguration(captureEngineConfiguration); - } - } - - private Gray8Bits toGrayLevel(int value) { - switch (value) { - case 6: - return Gray8Bits.X_256; - case 5: - return Gray8Bits.X_128; - case 4: - return Gray8Bits.X_64; - case 3: - return Gray8Bits.X_32; - case 2: - return Gray8Bits.X_16; - case 1: - return Gray8Bits.X_8; - default: - return Gray8Bits.X_4; - } - } - - /** - * Should not block (!) - */ - private void sendCaptureConfiguration(final CaptureEngineConfiguration captureEngineConfiguration) { - // Ok as very few of that (!) - new Thread(() -> networkEngine.sendCaptureConfiguration(captureEngineConfiguration), "CaptureEngineSettingsSender").start(); - } - - private Action createCompressionConfigurationAction() { - final Action configure = new AbstractAction() { - - @Override - public void actionPerformed(ActionEvent ev) { - JFrame compressionFrame = (JFrame) SwingUtilities.getRoot((Component) ev.getSource()); - - final JPanel pane = new JPanel(); - pane.setLayout(new GridLayout(4, 2, 10, 10)); - - final JLabel methodLbl = new JLabel(translate("compression.method")); - // testing only: final JComboBox methodCb = new JComboBox<>(CompressionMethod.values()); - final JComboBox methodCb = new JComboBox<>(Stream.of(CompressionMethod.values()).filter(e -> !e.equals(CompressionMethod.NONE)).toArray(CompressionMethod[]::new)); - methodCb.setSelectedItem(compressorEngineConfiguration.getMethod()); - pane.add(methodLbl); - pane.add(methodCb); - - final JLabel useCacheLbl = new JLabel(translate("compression.cache.usage")); - final JCheckBox useCacheCb = new JCheckBox(); - useCacheCb.setSelected(compressorEngineConfiguration.useCache()); - pane.add(useCacheLbl); - pane.add(useCacheCb); - - final JLabel maxSizeLbl = new JLabel(translate("compression.cache.max")); - maxSizeLbl.setToolTipText(translate("compression.cache.max.tooltip")); - final JTextField maxSizeTf = new JTextField(valueOf(compressorEngineConfiguration.getCacheMaxSize())); - pane.add(maxSizeLbl); - pane.add(maxSizeTf); - - final JLabel purgeSizeLbl = new JLabel(translate("compression.cache.purge")); - purgeSizeLbl.setToolTipText(translate("compression.cache.purge.tooltip")); - final JTextField purgeSizeTf = new JTextField(valueOf(compressorEngineConfiguration.getCachePurgeSize())); - pane.add(purgeSizeLbl); - pane.add(purgeSizeTf); - - useCacheCb.addActionListener(ev1 -> { - maxSizeLbl.setEnabled(useCacheCb.isSelected()); - maxSizeTf.setEnabled(useCacheCb.isSelected()); - purgeSizeLbl.setEnabled(useCacheCb.isSelected()); - purgeSizeTf.setEnabled(useCacheCb.isSelected()); - }); - - maxSizeLbl.setEnabled(useCacheCb.isSelected()); - maxSizeTf.setEnabled(useCacheCb.isSelected()); - purgeSizeLbl.setEnabled(useCacheCb.isSelected()); - purgeSizeTf.setEnabled(useCacheCb.isSelected()); - - final boolean ok = DialogFactory.showOkCancel(compressionFrame, translate("compression"), pane, true, () -> { - final String max = maxSizeTf.getText(); - if (max.isEmpty()) { - return translate("compression.cache.max.msg1"); - } - final int maxValue; - try { - maxValue = Integer.parseInt(max); - } catch (NumberFormatException ex) { - return translate("compression.cache.max.msg2"); - } - if (maxValue <= 0) { - return translate("compression.cache.max.msg3"); - } - return validatePurgeValue(purgeSizeTf, maxValue); - }); - - if (ok) { - final CompressorEngineConfiguration newCompressorEngineConfiguration = new CompressorEngineConfiguration((CompressionMethod) methodCb.getSelectedItem(), - useCacheCb.isSelected(), Integer.parseInt(maxSizeTf.getText()), Integer.parseInt(purgeSizeTf.getText())); - if (!newCompressorEngineConfiguration.equals(compressorEngineConfiguration)) { - compressorEngineConfiguration = newCompressorEngineConfiguration; - compressorEngineConfiguration.persist(); - - sendCompressorConfiguration(compressorEngineConfiguration); - } - } - } - }; - configure.putValue(Action.SHORT_DESCRIPTION, translate("compression.settings")); - configure.putValue(Action.SMALL_ICON, getOrCreateIcon(ImageNames.COMPRESSION_SETTINGS)); - return configure; - } - - private String validatePurgeValue(JTextField purgeSizeTf, int maxValue) { - final String purge = purgeSizeTf.getText(); - if (purge.isEmpty()) { - return translate("compression.cache.purge.msg1"); - } - final int purgeValue; - try { - purgeValue = Integer.parseInt(purge); - } catch (NumberFormatException ex) { - return translate("compression.cache.purge.msg2"); - } - if (purgeValue <= 0) { - return translate("compression.cache.purge.msg3"); - } - if (purgeValue >= maxValue) { - return translate("compression.cache.purge.msg4"); - } - return null; - } - - /** - * Should not block (!) - */ - private void sendCompressorConfiguration(final CompressorEngineConfiguration compressorEngineConfiguration) { - // Ok as very few of that (!) - new Thread(() -> networkEngine.sendCompressorConfiguration(compressorEngineConfiguration), "CompressorEngineSettingsSender").start(); - } - - private Action createResetAction() { - final Action configure = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ev) { - // Currently making a RESET within the assisted ... - sendCaptureConfiguration(captureEngineConfiguration); - } - }; - configure.putValue(Action.SHORT_DESCRIPTION, translate("capture.reset")); - configure.putValue(Action.SMALL_ICON, getOrCreateIcon(ImageNames.RESET_CAPTURE)); - return configure; - } - - private Action createTokenAction() { - - final Action tokenAction = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ev) { - final JButton button = (JButton) ev.getSource(); - - if (token == null) { - CompletableFuture.supplyAsync(() -> { - try { - requestToken(); - } catch (IOException | InterruptedException ex) { - Log.error("Could not obtain token", ex); - JOptionPane.showMessageDialog(frame, translate("token.create.error.msg"), translate("connection.settings.token"), JOptionPane.ERROR_MESSAGE); - if (ex instanceof InterruptedException) { - Thread.currentThread().interrupt(); - } - } - return token; - }).thenAcceptAsync(tokenString -> { - if (tokenString != null) { - button.setText(format(" %s", tokenString)); - button.setToolTipText(translate("token.copy.msg")); - } - }); - } - final StringSelection value = new StringSelection(token); - final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - clipboard.setContents(value, value); - } - - private void requestToken() throws IOException, InterruptedException { - // HttpClient doesn't implement AutoCloseable nor close before Java 21! - @java.lang.SuppressWarnings("squid:S2095") - HttpClient client = HttpClient.newBuilder().build(); - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(format(tokenServerUrl, networkConfiguration.getPort()))) - .timeout(Duration.ofSeconds(5)) - .build(); - token = client.send(request, HttpResponse.BodyHandlers.ofString()).body().trim(); - } - }; - tokenAction.putValue("token", token); - tokenAction.putValue(Action.SHORT_DESCRIPTION, translate("token.create.msg")); - tokenAction.putValue(Action.SMALL_ICON, getOrCreateIcon(ImageNames.KEY)); - return tokenAction; - } - - private Action createStartAction() { - final Action startAction = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ev) { - new Assistant.NetWorker().execute(); - } - }; - startAction.setEnabled(false); - startAction.putValue(Action.SHORT_DESCRIPTION, translate("start.session")); - startAction.putValue(Action.SMALL_ICON, getOrCreateIcon(ImageNames.START)); - return startAction; - } - - private Action createStopAction() { - final Action stopAction = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ev) { - stopNetwork(); - } - }; - stopAction.setEnabled(false); - stopAction.putValue(Action.SHORT_DESCRIPTION, translate("stop.session")); - stopAction.putValue(Action.SMALL_ICON, getOrCreateIcon(ImageNames.STOP)); - return stopAction; - } - - private Action createToggleCompatibilityModeAction() { - final Action compatibilityMode = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ev) { - compatibilityModeActive.set(!compatibilityModeActive.get()); - if (compatibilityModeActive.get()) { - JOptionPane.showMessageDialog(frame, translate("compatibility.mode.info"), - translate("compatibility.mode.active"), JOptionPane.WARNING_MESSAGE); - } - frame.repaint(); - } - }; - compatibilityMode.putValue(Action.SHORT_DESCRIPTION, translate("compatibility.mode")); - compatibilityMode.putValue(Action.SMALL_ICON, getOrCreateIcon(ImageNames.COMPATIBILITY)); - return compatibilityMode; - } - - private JComboBox createLanguageSelection() { - final JComboBox languageSelection = new JComboBox<>(Language.values()); - languageSelection.setMaximumRowCount(languageSelection.getItemCount()); - languageSelection.setBorder(BorderFactory.createEmptyBorder(7, 3, 6, 2)); - languageSelection.setFocusable(false); - languageSelection.setToolTipText(translate("changeLanguage")); - languageSelection.setSelectedItem(Arrays.stream(Language.values()).filter(e -> e.getShortName().equals(Locale.getDefault().getLanguage())).findFirst().orElse(Language.EN)); - languageSelection.setRenderer(new LanguageRenderer()); - languageSelection.addActionListener(ev -> { - Locale.setDefault(Locale.forLanguageTag(valueOf(languageSelection.getSelectedItem()))); - Log.info(format("New language %s", Locale.getDefault().getLanguage())); - configuration = new AssistantConfiguration(Locale.getDefault().getLanguage()); - configuration.persist(); - initGui(); - } - ); - return languageSelection; - } - - private static class LanguageRenderer extends DefaultListCellRenderer { - @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - super.getListCellRendererComponent(list, ((Language) value).getName(), index, isSelected, cellHasFocus); - return this; - } - } - - private Action createScreenshotRequestAction() { - final Action screenshotAction = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ev) { - new Thread(networkEngine::sendScreenshotRequest, "ScreenshotRequest").start(); - } - }; - screenshotAction.setEnabled(false); - screenshotAction.putValue(Action.SHORT_DESCRIPTION, translate("send.prtScrKey")); - screenshotAction.putValue(Action.SMALL_ICON, getOrCreateIcon(ImageNames.CAM)); - return screenshotAction; - } - - private class NetWorker extends SwingWorker { - @Override - protected String doInBackground() { - if (!isCancelled()) { - startNetwork(); - } - return null; - } - - private void startNetwork() { - frame.onGettingReady(); - networkEngine.start(compatibilityModeActive.get()); - } - - @Override - protected void done() { - try { - if (!isCancelled()) { - super.get(); - Log.debug("NetWorker is done"); - } - } catch (InterruptedException | ExecutionException ie) { - Log.info("NetWorker was cancelled"); - Thread.currentThread().interrupt(); - } - } - } - - public boolean isUpnpEnabled() { - synchronized (upnpEnabledLOCK) { - while (upnpEnabled == null) { - try { - upnpEnabledLOCK.wait(); - } catch (InterruptedException e) { - Log.warn("Swallowed", e); - Thread.currentThread().interrupt(); - } - } - return upnpEnabled; - } - } - - private void initUpnp() { - synchronized (upnpEnabledLOCK) { - CompletableFuture.supplyAsync(UPnP::isUPnPAvailable).thenApply(enabled -> { - Log.info(format("UPnP is %s", enabled.booleanValue() ? "enabled" : "disabled")); - upnpEnabled = enabled; - return enabled; - }); - upnpEnabledLOCK.notifyAll(); - } - } - - private class MyDeCompressorEngineListener implements DeCompressorEngineListener { - /** - * Called from within THE de-compressor engine thread => prevBuffer - * usage (!) - */ - @Override - public void onDeCompressed(Capture capture, int cacheHits, double compressionRatio) { - final AbstractMap.SimpleEntry image; - // synchronized because of the reset onStarting() - synchronized (prevBufferLOCK) { - image = capture.createBufferedImage(prevBuffer, prevWidth, prevHeight); - prevBuffer = image.getValue(); - prevWidth = image.getKey().getWidth(); - prevHeight = image.getKey().getHeight(); - } - if (frame.getFitToScreenActivated()) { - if (frame.getCanvas() == null) { - Log.debug(format("ComputeScaleFactors for w: %s h: %s", prevWidth, prevHeight)); - frame.computeScaleFactors(prevWidth, prevHeight, frame.getKeepAspectRatioActivated()); - } - // required as the canvas might have been reset if keepAspectRatio caused a resizing of the window - final Dimension canvasDimension = frame.getCanvas(); - if (canvasDimension != null) { - frame.onCaptureUpdated(scaleImage(image.getKey(), canvasDimension.width, canvasDimension.height)); - } - } else { - frame.onCaptureUpdated(image.getKey()); - } - receivedTileCounter.add(capture.getDirtyTileCount(), cacheHits); - skippedTileCounter.add(capture.getSkipped()); - mergedTileCounter.add(capture.getMerged()); - captureCompressionCounter.add(capture.getDirtyTileCount(), compressionRatio); - } - - private BufferedImage scaleImage(BufferedImage image, int width, int height) { - AffineTransform scaleTransform = AffineTransform.getScaleInstance(frame.getxFactor(), frame.getyFactor()); - try { - AffineTransformOp bilinearScaleOp = new AffineTransformOp(scaleTransform, AffineTransformOp.TYPE_BILINEAR); - return bilinearScaleOp.filter(image, new BufferedImage(abs(width), abs(height), image.getType() == 0 ? TYPE_INT_ARGB_PRE : TYPE_BYTE_GRAY)); - } catch (ImagingOpException e) { - Log.error(e.getMessage()); - return image; - } - } - } - - - private class MyNetworkAssistantEngineListener implements NetworkAssistantEngineListener { - @Override - public void onReady() { - frame.onReady(); - } - - /** - * Should not block as called from the network receiving thread (!) - */ - @Override - public void onStarting(int port) { - frame.onHttpStarting(port); - synchronized (prevBufferLOCK) { - prevBuffer = null; - prevWidth = -1; - prevHeight = -1; - } - } - - /** - * Should not block as called from the network receiving thread (!) - */ - @Override - public boolean onAccepted(Socket connection) { - return frame.onAccepted(connection); - } - - /** - * Should not block as called from the network receiving thread (!) - */ - @Override - public void onConnected(Socket connection, char osId, String inputLocale, int peerMajorVersion) { - assureCompatibility(peerMajorVersion); - sendCaptureConfiguration(captureEngineConfiguration); - sendCompressorConfiguration(compressorEngineConfiguration); - frame.resetCanvas(); - frame.onSessionStarted(osId, inputLocale, peerMajorVersion); - } - - private void assureCompatibility(int peerMajorVersion) { - if (!Version.isColoredVersion(peerMajorVersion) && (captureEngineConfiguration.isCaptureColors() || captureEngineConfiguration.getCaptureQuantization().getLevels() < Gray8Bits.X_32.getLevels())) { - Log.warn(format("Pre color v%d.x.x peer detected: CaptureEngineConfiguration adjusted to %s", peerMajorVersion, Gray8Bits.X_128)); - captureEngineConfiguration = new CaptureEngineConfiguration(captureEngineConfiguration.getCaptureTick(), Gray8Bits.X_128, false); - captureEngineConfiguration.persist(); - } - } - - @Override - public void onFingerprinted(String fingerprints) { - if (null == fingerprints) { - fingerprints = translate("compatibility.mode.enable"); - } - frame.setFingerprints(fingerprints); - } - - /** - * Should not block as called from the network receiving thread (!) - */ - @Override - public void onByteReceived(int count) { - receivedBitCounter.add(8d * count); - } - - /** - * Should not block as called from the network receiving thread (!) - */ - @Override - public void onClipboardReceived() { - frame.onClipboardReceived(); - } - - /** - * Should not block as called from the network receiving thread (!) - */ - @Override - public void onClipboardSent() { - frame.onClipboardSent(); - } - - /** - * Should not block as called from the network receiving thread (!) - */ - @Override - public void onResizeScreen(int width, int height) { - frame.computeScaleFactors(width, height, false); - } - - /** - * Should not block as called from the network receiving thread (!) - */ - @Override - public void onDisconnecting() { - frame.onDisconnecting(); - networkConfiguration.setMonochromePeer(false); - } - - @Override - public void onTerminating() { - Log.info("Session got terminated by peer"); - frame.onTerminating(); - networkConfiguration.setMonochromePeer(false); - } - - @Override - public void onIOError(IOException error) { - frame.onIOError(error); - networkConfiguration.setMonochromePeer(false); - } - - } -} diff --git a/src/main/java/mpo/dayon/assistant/gui/AssistantActions.java b/src/main/java/mpo/dayon/assistant/gui/AssistantActions.java deleted file mode 100644 index a1d024e2..00000000 --- a/src/main/java/mpo/dayon/assistant/gui/AssistantActions.java +++ /dev/null @@ -1,116 +0,0 @@ -package mpo.dayon.assistant.gui; - -import javax.swing.Action; - -class AssistantActions { - - private Action ipAddressAction; - private Action networkConfigurationAction; - private Action captureEngineConfigurationAction; - private Action compressionEngineConfigurationAction; - private Action resetAction; - private Action remoteClipboardRequestAction; - private Action remoteClipboardSetAction; - private Action screenshotRequestAction; - private Action startAction; - private Action stopAction; - private Action tokenAction; - private Action toggleCompatibilityModeAction; - - Action getIpAddressAction() { - return ipAddressAction; - } - - void setIpAddressAction(Action ipAddressAction) { - this.ipAddressAction = ipAddressAction; - } - - Action getNetworkConfigurationAction() { - return networkConfigurationAction; - } - - void setNetworkConfigurationAction(Action networkConfigurationAction) { - this.networkConfigurationAction = networkConfigurationAction; - } - - Action getCaptureEngineConfigurationAction() { - return captureEngineConfigurationAction; - } - - void setCaptureEngineConfigurationAction(Action captureEngineConfigurationAction) { - this.captureEngineConfigurationAction = captureEngineConfigurationAction; - } - - Action getCompressionEngineConfigurationAction() { - return compressionEngineConfigurationAction; - } - - void setCompressionEngineConfigurationAction(Action compressionEngineConfigurationAction) { - this.compressionEngineConfigurationAction = compressionEngineConfigurationAction; - } - - Action getResetAction() { - return resetAction; - } - - void setResetAction(Action resetAction) { - this.resetAction = resetAction; - } - - - Action getRemoteClipboardRequestAction() { - return remoteClipboardRequestAction; - } - - void setRemoteClipboardRequestAction(Action remoteClipboardRequestAction) { - this.remoteClipboardRequestAction = remoteClipboardRequestAction; - } - - Action getRemoteClipboardSetAction() { - return remoteClipboardSetAction; - } - - void setRemoteClipboardSetAction(Action remoteClipboardSetAction) { - this.remoteClipboardSetAction = remoteClipboardSetAction; - } - - Action getScreenshotRequestAction() { - return screenshotRequestAction; - } - - void setScreenshotRequestAction(Action screenshotRequestAction) { - this.screenshotRequestAction = screenshotRequestAction; - } - - Action getStartAction() { - return startAction; - } - - void setStartAction(Action startAction) { - this.startAction = startAction; - } - - Action getStopAction() { - return stopAction; - } - - void setStopAction(Action stopAction) { - this.stopAction = stopAction; - } - - Action getTokenAction() { - return tokenAction; - } - - void setTokenAction(Action tokenAction) { - this.tokenAction = tokenAction; - } - - Action getToggleCompatibilityModeAction() { - return toggleCompatibilityModeAction; - } - - void setToggleCompatibilityModeAction(Action toggleCompatibilityModeAction) { - this.toggleCompatibilityModeAction = toggleCompatibilityModeAction; - } -} diff --git a/src/main/java/mpo/dayon/assistant/gui/AssistantConfiguration.java b/src/main/java/mpo/dayon/assistant/gui/AssistantConfiguration.java deleted file mode 100644 index 7c45d3ac..00000000 --- a/src/main/java/mpo/dayon/assistant/gui/AssistantConfiguration.java +++ /dev/null @@ -1,65 +0,0 @@ -package mpo.dayon.assistant.gui; - -import mpo.dayon.common.configuration.Configuration; - -import java.util.Locale; - -import static mpo.dayon.common.preference.Preferences.*; - -public class AssistantConfiguration extends Configuration { - private static final String PREF_VERSION = "assistant.version"; - - private static final String PREF_LOOK_AND_FEEL = "assistant.lookAndFeel"; - - private static final String PREF_LANGUAGE = "assistant.language"; - - private final String language; - - /** - * Default : takes its values from the current preferences. - * - * @see mpo.dayon.common.preference.Preferences - */ - public AssistantConfiguration() { - language = getPreferences().getStringPreference(PREF_LANGUAGE, Locale.getDefault().getLanguage()); - } - - AssistantConfiguration(String language) { - this.language = language; - } - - String getLanguage() { - return language; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - final AssistantConfiguration that = (AssistantConfiguration) o; - return language.equals(that.getLanguage()); - } - - @Override - public int hashCode() { - return language.hashCode(); - } - - /** - * @param clear - * allows for clearing properties from previous version - */ - @Override - protected void persist(boolean clear) { - final Props props = new Props(); - props.set(PREF_VERSION, String.valueOf(1)); - props.set(PREF_LANGUAGE, language); - props.clear(PREF_LOOK_AND_FEEL); - getPreferences().update(props); // atomic (!) - } - -} diff --git a/src/main/java/mpo/dayon/assistant/gui/AssistantFrame.java b/src/main/java/mpo/dayon/assistant/gui/AssistantFrame.java deleted file mode 100644 index 06a23acc..00000000 --- a/src/main/java/mpo/dayon/assistant/gui/AssistantFrame.java +++ /dev/null @@ -1,671 +0,0 @@ -package mpo.dayon.assistant.gui; - -import mpo.dayon.common.event.Listeners; -import mpo.dayon.common.gui.common.BaseFrame; -import mpo.dayon.common.gui.common.FrameType; -import mpo.dayon.common.gui.common.ImageNames; -import mpo.dayon.common.gui.statusbar.StatusBar; -import mpo.dayon.common.gui.toolbar.ToolBar; -import mpo.dayon.common.log.Log; -import mpo.dayon.common.monitoring.counter.Counter; -import mpo.dayon.common.utils.Language; -import mpo.dayon.common.version.Version; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import java.awt.im.InputContext; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.net.Socket; -import java.time.Instant; -import java.util.ArrayList; -import java.util.concurrent.atomic.AtomicBoolean; - -import static java.awt.event.KeyEvent.*; -import static java.lang.Math.abs; -import static java.lang.String.format; -import static mpo.dayon.common.babylon.Babylon.translate; -import static mpo.dayon.common.gui.common.ImageUtilities.getOrCreateIcon; - -class AssistantFrame extends BaseFrame { - - private static final int OFFSET = 6; - - private static final int DEFAULT_FACTOR = 1; - - private static final char EMPTY_CHAR = ' '; - - private final transient Listeners listeners = new Listeners<>(); - - private final JScrollPane assistantPanelWrapper; - - private final AssistantPanel assistantPanel; - - private final transient AssistantActions actions; - - private Timer sessionTimer; - - private JComponent center; - - private final JToggleButton controlToggleButton; - - private final JToggleButton compatibilityToggleButton; - - private final JToggleButton windowsKeyToggleButton; - - private final JToggleButton ctrlKeyToggleButton; - - private final JToggleButton fitToScreenToggleButton; - - private final JToggleButton keepAspectRatioToggleButton; - - private final JButton startButton; - - private final JButton stopButton; - - private final JButton screenshotButton; - - private final AtomicBoolean controlActivated = new AtomicBoolean(false); - - private final AtomicBoolean windowsKeyActivated = new AtomicBoolean(false); - - private final AtomicBoolean ctrlKeyActivated = new AtomicBoolean(false); - - private final AtomicBoolean fitToScreenActivated = new AtomicBoolean(false); - - private final AtomicBoolean keepAspectRatioActivated = new AtomicBoolean(false); - - private final AtomicBoolean isImmutableWindowsSize = new AtomicBoolean(false); - - private double xFactor = DEFAULT_FACTOR; - - private double yFactor = DEFAULT_FACTOR; - - private Dimension canvas; - - private JTabbedPane tabbedPane; - - private final JComboBox languageSelection; - - private char osId; - - AssistantFrame(AssistantActions actions, ArrayList> counters, JComboBox languageSelection, boolean compatibilityModeActive, Assistant assistant) { - RepeatingReleasedEventsFixer.install(); - super.setFrameType(FrameType.ASSISTANT); - this.actions = actions; - this.actions.setNetworkConfigurationAction(createConnectionSettingsAction(assistant)); - this.startButton = createButton(actions.getStartAction()); - this.stopButton = createButton(actions.getStopAction(), false); - this.compatibilityToggleButton = createToggleButton(actions.getToggleCompatibilityModeAction(), true, compatibilityModeActive); - this.controlToggleButton = createToggleButton(createToggleControlMode()); - this.fitToScreenToggleButton = createToggleButton(createToggleFixScreenAction()); - this.keepAspectRatioToggleButton = createToggleButton(createToggleKeepAspectRatioAction(), false); - this.windowsKeyToggleButton = createToggleButton(createSendWindowsKeyAction()); - this.ctrlKeyToggleButton = createToggleButton(createSendCtrlKeyAction()); - this.screenshotButton = createButton(actions.getScreenshotRequestAction()); - this.languageSelection = languageSelection; - setupToolBar(createToolBar()); - setupStatusBar(createStatusBar(counters)); - assistantPanel = new AssistantPanel(); - assistantPanel.setFocusable(false); - assistantPanelWrapper = new JScrollPane(assistantPanel); - // ------------------------------------------------------------------------------------------------------------- - // Not really needed for the time being - allows for seeing the TAB with a regular KEY listener ... - setFocusTraversalKeysEnabled(false); - addListeners(); - // the network has been before we've been registered as a listener ... - onReady(); - } - - private void addListeners() { - addFocusListener(); - addKeyListeners(); - addMouseListeners(); - addResizeListener(); - addMinMaximizedListener(); - } - - Dimension getCanvas() { - return canvas; - } - - double getxFactor() { - return xFactor; - } - - double getyFactor() { - return yFactor; - } - - boolean getFitToScreenActivated() { - return fitToScreenActivated.get(); - } - boolean getKeepAspectRatioActivated() { - return keepAspectRatioActivated.get(); - } - - private void addMouseListeners() { - assistantPanel.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent ev) { - if (controlActivated.get()) { - fireOnMousePressed(ev.getX(), ev.getY(), ev.getButton()); - } - } - - @Override - public void mouseReleased(MouseEvent ev) { - if (controlActivated.get()) { - fireOnMouseReleased(ev.getX(), ev.getY(), ev.getButton()); - } - } - }); - - assistantPanel.addMouseMotionListener(new MouseMotionListener() { - @Override - public void mouseDragged(MouseEvent ev) { - if (controlActivated.get()) { - fireOnMouseMove(ev.getX(), ev.getY()); - } - } - - @Override - public void mouseMoved(MouseEvent ev) { - if (controlActivated.get()) { - fireOnMouseMove(ev.getX(), ev.getY()); - } - } - }); - - assistantPanel.addMouseWheelListener(ev -> { - if (controlActivated.get()) { - fireOnMouseWheeled(ev.getX(), ev.getY(), ev.getWheelRotation()); - } - }); - } - - private void addKeyListeners() { - addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(KeyEvent ev) { - if (controlActivated.get()) { - fireOnKeyPressed(ev.getKeyCode(), ev.getKeyChar()); - } - } - - @Override - public void keyReleased(KeyEvent ev) { - if (controlActivated.get()) { - fireOnKeyReleased(ev.getKeyCode(), ev.getKeyChar()); - } - } - }); - } - - private void addResizeListener() { - addComponentListener(new ComponentAdapter() { - private Timer resizeTimer; - @Override - public void componentResized(ComponentEvent ev) { - if (resizeTimer != null) { - resizeTimer.stop(); - } - resizeTimer = new Timer(500, e -> resetCanvas()); - resizeTimer.setRepeats(false); - resizeTimer.start(); - } - }); - } - - private void addMinMaximizedListener() { - addWindowStateListener(event -> isImmutableWindowsSize.set((event.getNewState() & Frame.ICONIFIED) == Frame.ICONIFIED || (event.getNewState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH)); - } - - private void addFocusListener() { - addFocusListener(new FocusAdapter() { - @Override - public void focusLost(FocusEvent ev) { - if (controlActivated.get()) { - fireOnKeyReleased(-1, Character.MIN_VALUE); - } - } - }); - } - - public void addListener(AssistantFrameListener listener) { - listeners.add(listener); - } - - private ToolBar createToolBar() { - ToolBar toolbar = new ToolBar(); - toolbar.add(createTabbedPane()); - return toolbar; - } - - private JTabbedPane createTabbedPane() { - JPanel connectionPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); - connectionPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); - connectionPanel.add(startButton); - connectionPanel.add(stopButton); - connectionPanel.add(createTokenButton(actions.getTokenAction())); - connectionPanel.add(createButton(actions.getIpAddressAction())); - connectionPanel.add(compatibilityToggleButton); - - JPanel sessionPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); - sessionPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); - sessionPanel.add(fitToScreenToggleButton); - sessionPanel.add(keepAspectRatioToggleButton); - sessionPanel.add(controlToggleButton); - sessionPanel.add(windowsKeyToggleButton); - sessionPanel.add(ctrlKeyToggleButton); - sessionPanel.add(screenshotButton); - sessionPanel.add(createButton(actions.getRemoteClipboardRequestAction())); - sessionPanel.add(createButton(actions.getRemoteClipboardSetAction())); - sessionPanel.add(createButton(actions.getResetAction())); - - JPanel settingsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); - settingsPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); - settingsPanel.add(createButton(actions.getNetworkConfigurationAction())); - settingsPanel.add(createButton(actions.getCaptureEngineConfigurationAction())); - settingsPanel.add(createButton(actions.getCompressionEngineConfigurationAction())); - settingsPanel.add(languageSelection); - - tabbedPane = new JTabbedPane(); - tabbedPane.addTab(translate("connection"), connectionPanel); - tabbedPane.addTab(translate("session"), sessionPanel); - tabbedPane.addTab(translate("settings"), settingsPanel); - // must not be focusable or the key listener won't work - tabbedPane.setFocusable(false); - return tabbedPane; - } - - private Component createTokenButton(Action tokenAction) { - String token = (String) tokenAction.getValue("token"); - JButton button = createButton(tokenAction); - if (token != null) { - button.setText(format(" %s", token)); - button.setToolTipText(translate("token.copy.msg")); - } - return button; - } - - private StatusBar createStatusBar(ArrayList> counters) { - final StatusBar statusBar = new StatusBar(); - final Component horizontalStrut = Box.createHorizontalStrut(10); - statusBar.add(horizontalStrut); - for (Counter counter : counters) { - statusBar.addSeparator(); - statusBar.addCounter(counter, counter.getWidth()); - } - statusBar.addSeparator(); - statusBar.addRamInfo(); - statusBar.addSeparator(); - statusBar.addConnectionDuration(); - statusBar.add(horizontalStrut); - return statusBar; - } - - private Action createToggleControlMode() { - final Action remoteControl = new AbstractAction() { - - @Override - public void actionPerformed(ActionEvent ev) { - controlActivated.set(!controlActivated.get()); - windowsKeyToggleButton.setEnabled(controlActivated.get()); - ctrlKeyToggleButton.setEnabled(controlActivated.get()); - } - }; - remoteControl.putValue(Action.SHORT_DESCRIPTION, translate("control.mode")); - remoteControl.putValue(Action.SMALL_ICON, getOrCreateIcon(ImageNames.WATCH)); - remoteControl.putValue(ROLLOVER_ICON, getOrCreateIcon(ImageNames.WATCH)); - remoteControl.putValue(SELECTED_ICON, getOrCreateIcon(ImageNames.CONTROL)); - return remoteControl; - } - - private Action createSendWindowsKeyAction() { - final Action sendWindowsKey = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ev) { - final int virtualKey = osId != 'm' ? VK_WINDOWS : VK_META; - if (windowsKeyActivated.get()) { - fireOnKeyReleased(virtualKey, EMPTY_CHAR); - } else { - fireOnKeyPressed(virtualKey, EMPTY_CHAR); - } - windowsKeyActivated.set(!windowsKeyActivated.get()); - } - }; - sendWindowsKey.putValue(Action.SHORT_DESCRIPTION, translate("send.windowsKey")); - sendWindowsKey.putValue(Action.SMALL_ICON, getOrCreateIcon(ImageNames.WIN)); - return sendWindowsKey; - } - - private Action createSendCtrlKeyAction() { - final Action sendCtrlKey = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ev) { - if (ctrlKeyActivated.get()) { - fireOnKeyReleased(VK_CONTROL, EMPTY_CHAR); - } else { - fireOnKeyPressed(VK_CONTROL, EMPTY_CHAR); - } - ctrlKeyActivated.set(!ctrlKeyActivated.get()); - } - }; - sendCtrlKey.putValue(Action.SHORT_DESCRIPTION, translate("send.ctrlKey")); - sendCtrlKey.putValue(Action.SMALL_ICON, getOrCreateIcon(ImageNames.CTRL)); - return sendCtrlKey; - } - - private Action createToggleFixScreenAction() { - final Action fitScreen = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ev) { - fitToScreenActivated.set(!fitToScreenActivated.get()); - if (!fitToScreenActivated.get()) { - keepAspectRatioToggleButton.setVisible(false); - resetFactors(); - } else { - keepAspectRatioToggleButton.setVisible(true); - resetCanvas(); - } - repaint(); - } - }; - fitScreen.putValue(Action.SHORT_DESCRIPTION, translate("toggle.screen.mode")); - fitScreen.putValue(Action.SMALL_ICON, getOrCreateIcon(ImageNames.FULLSCREEN)); - fitScreen.putValue(ROLLOVER_ICON, getOrCreateIcon(ImageNames.FULLSCREEN)); - fitScreen.putValue(SELECTED_ICON, getOrCreateIcon(ImageNames.FIT)); - return fitScreen; - } - - private Action createToggleKeepAspectRatioAction() { - final Action keepAspectRatio = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ev) { - keepAspectRatioActivated.set(!keepAspectRatioActivated.get()); - resetCanvas(); - repaint(); - } - }; - keepAspectRatio.putValue(Action.SHORT_DESCRIPTION, translate("toggle.keep.aspect")); - keepAspectRatio.putValue(Action.SMALL_ICON, getOrCreateIcon(ImageNames.UNLOCKED)); - keepAspectRatio.putValue(ROLLOVER_ICON, getOrCreateIcon(ImageNames.UNLOCKED)); - keepAspectRatio.putValue(SELECTED_ICON, getOrCreateIcon(ImageNames.LOCK)); - return keepAspectRatio; - } - - void onReady() { - hideSpinner(); - validate(); - repaint(); - this.setCursor(Cursor.getDefaultCursor()); - // connection - actions.getStartAction().setEnabled(true); - actions.getStopAction().setEnabled(false); - startButton.setVisible(true); - stopButton.setVisible(false); - actions.getTokenAction().setEnabled(true); - actions.getToggleCompatibilityModeAction().setEnabled(true); - actions.getIpAddressAction().setEnabled(true); - // session - screenshotButton.setEnabled(false); - actions.getResetAction().setEnabled(false); - // settings - actions.getNetworkConfigurationAction().setEnabled(true); - actions.getCaptureEngineConfigurationAction().setEnabled(true); - languageSelection.setEnabled(true); - disableControls(); - clearFingerprints(); - getStatusBar().setMessage(translate("ready")); - } - - void onHttpStarting(int port) { - this.setCursor(Cursor.getDefaultCursor()); - // connection - startButton.setVisible(false); - actions.getStopAction().setEnabled(true); - stopButton.setVisible(true); - actions.getToggleCompatibilityModeAction().setEnabled(false); - actions.getIpAddressAction().setEnabled(false); - // settings - actions.getNetworkConfigurationAction().setEnabled(false); - languageSelection.setEnabled(false); - clearFingerprints(); - getStatusBar().setMessage(translate("listening", port)); - } - - void onGettingReady() { - this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - actions.getStartAction().setEnabled(false); - showSpinner(); - } - - private void showSpinner() { - center = new Spinner(); - add(center, BorderLayout.CENTER); - } - - boolean onAccepted(Socket connection) { - if (JOptionPane.showOptionDialog(this, translate("connection.incoming.msg1"), - translate("connection.incoming", connection.getInetAddress().getHostAddress()), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, - getOrCreateIcon(ImageNames.USERS), okCancelOptions, okCancelOptions[1]) == 0) { - return false; - } - hideSpinner(); - getStatusBar().setMessage(translate("connection.incoming.msg2", connection.getInetAddress().getHostAddress())); - center = assistantPanelWrapper; - add(center, BorderLayout.CENTER); - screenshotButton.setEnabled(true); - actions.getResetAction().setEnabled(true); - actions.getTokenAction().setEnabled(false); - enableControls(); - validate(); - repaint(); - return true; - } - - void onClipboardRequested() { - toggleTransferControls(false); - } - - void onClipboardSending() { - toggleTransferControls(false); - } - - void onClipboardSent() { - toggleTransferControls(true); - } - - void onClipboardReceived() { - toggleTransferControls(true); - } - - void onSessionStarted(char osId, String inputLocale, int assistedMajorVersion) { - this.osId = osId; - if (osId == 'm') { - windowsKeyToggleButton.setIcon(getOrCreateIcon(ImageNames.CMD)); - windowsKeyToggleButton.setToolTipText(translate("send.cmdKey")); - } else { - windowsKeyToggleButton.setIcon(getOrCreateIcon(ImageNames.WIN)); - windowsKeyToggleButton.setToolTipText(translate("send.winKey")); - } - if (Version.isOutdatedVersion(Version.get().getMajor(), assistedMajorVersion)) { - String infoMessage = format("%s%n%s", translate("outdated.msg1"), translate("outdated.msg2")); - JOptionPane.showMessageDialog(this, infoMessage, "", JOptionPane.INFORMATION_MESSAGE); - } - if (!inputLocale.isEmpty() && !inputLocale.equals(InputContext.getInstance().getLocale().toString())) { - String infoMessage = format("%s%n%s%n%s", translate("keyboardlayout.msg1", inputLocale), translate("keyboardlayout.msg2"), translate("keyboardlayout.msg3")); - JOptionPane.showMessageDialog(this, infoMessage, "", JOptionPane.INFORMATION_MESSAGE); - } - long sessionStartTime = Instant.now().getEpochSecond(); - sessionTimer = new Timer(1000, e -> { - final long seconds = Instant.now().getEpochSecond() - sessionStartTime; - getStatusBar().setSessionDuration(format("%02d:%02d:%02d", seconds / 3600, (seconds % 3600) / 60, seconds % 60)); - }); - sessionTimer.start(); - tabbedPane.setSelectedIndex(1); - } - - void onDisconnecting() { - stopSessionTimer(); - tabbedPane.setSelectedIndex(0); - } - - void onTerminating() { - actions.getStartAction().setEnabled(false); - actions.getStopAction().setEnabled(false); - actions.getResetAction().setEnabled(false); - disableControls(); - stopSessionTimer(); - tabbedPane.setSelectedIndex(0); - } - - void onIOError(IOException error) { - onTerminating(); - hideSpinner(); - validate(); - repaint(); - String errorMessage = error.getMessage() != null ? translate("comm.error.msg1", translate(error.getMessage())) : translate("comm.error.msg1", "!"); - JOptionPane.showMessageDialog(this, errorMessage, translate("comm.error"), JOptionPane.ERROR_MESSAGE); - } - - void computeScaleFactors(int sourceWidth, int sourceHeight, boolean keepAspectRatio) { - canvas = assistantPanelWrapper.getSize(); - canvas.setSize(canvas.getWidth() - OFFSET, canvas.getHeight() - OFFSET); - xFactor = canvas.getWidth() / sourceWidth; - yFactor = canvas.getHeight() / sourceHeight; - if (keepAspectRatio && !isImmutableWindowsSize.get() && abs(xFactor - yFactor) > 0.01) { - resizeWindow(sourceWidth, sourceHeight); - } - } - - private void resizeWindow(int sourceWidth, int sourceHeight) { - Log.debug("%s", () -> format("Resize W:H %s:%s x:y %s:%s", this.getWidth(), this.getHeight(), xFactor, yFactor)); - int menuHeight = this.getHeight() - canvas.height; - final Rectangle maximumWindowBounds = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds(); - if (xFactor < yFactor) { - if ((sourceWidth * yFactor) + OFFSET < maximumWindowBounds.width) { - xFactor = yFactor; - Log.debug("Get wider"); - this.setSize((int) (sourceWidth * xFactor) + OFFSET, this.getHeight()); - } else { - yFactor = xFactor; - Log.debug("Get lower"); - this.setSize(this.getWidth(), (int) (sourceHeight * yFactor) + menuHeight + OFFSET); - } - } else { - if ((sourceHeight * xFactor) + menuHeight + OFFSET < maximumWindowBounds.height) { - yFactor = xFactor; - Log.debug("Get higher"); - this.setSize(this.getWidth(), (int) (sourceHeight * yFactor) + menuHeight + OFFSET); - } else { - xFactor = yFactor; - Log.debug("Get narrower"); - this.setSize((int) (sourceWidth * xFactor) + OFFSET, this.getHeight()); - } - } - Log.debug("%s", () -> format("Resized W:H %s:%s x:y %s:%s", this.getWidth(), this.getHeight(), xFactor, yFactor)); - } - - private void resetFactors() { - xFactor = DEFAULT_FACTOR; - yFactor = DEFAULT_FACTOR; - } - - void resetCanvas() { - canvas = null; - } - - private void disableControls() { - controlActivated.set(false); - windowsKeyActivated.set(false); - controlToggleButton.setEnabled(false); - windowsKeyToggleButton.setEnabled(false); - ctrlKeyToggleButton.setEnabled(false); - toggleTransferControls(false); - } - - private void toggleTransferControls(boolean enabled) { - actions.getRemoteClipboardSetAction().setEnabled(enabled); - actions.getRemoteClipboardRequestAction().setEnabled(enabled); - } - - private void enableControls() { - controlToggleButton.setSelected(false); - controlToggleButton.setEnabled(true); - windowsKeyToggleButton.setSelected(false); - ctrlKeyToggleButton.setSelected(false); - toggleTransferControls(true); - } - - private void stopSessionTimer() { - if (sessionTimer != null) { - sessionTimer.stop(); - } - } - - void hideSpinner() { - if (center != null) { - remove(center); - } - } - - void onCaptureUpdated(final BufferedImage captureImage) { - assistantPanel.onCaptureUpdated(captureImage); - } - - /** - * Should not block as called from the network incoming message thread (!) - */ - void onMouseLocationUpdated(int x, int y) { - int xs = (int) Math.round(x * xFactor); - int ys = (int) Math.round(y * yFactor); - assistantPanel.onMouseLocationUpdated(xs, ys); - } - - private void fireOnMouseMove(int x, int y) { - listeners.getListeners().forEach(listener -> listener.onMouseMove(scaleXPosition(x), scaleYPosition(y))); - } - - private void fireOnMousePressed(int x, int y, int button) { - listeners.getListeners().forEach(listener -> listener.onMousePressed(scaleXPosition(x), scaleYPosition(y), button)); - } - - private void fireOnMouseReleased(int x, int y, int button) { - listeners.getListeners().forEach(listener -> listener.onMouseReleased(scaleXPosition(x), scaleYPosition(y), button)); - } - - private void fireOnMouseWheeled(int x, int y, int rotations) { - listeners.getListeners().forEach(listener -> listener.onMouseWheeled(scaleXPosition(x), scaleYPosition(y), rotations)); - } - - private int scaleYPosition(int y) { - return (int) Math.round(y / yFactor); - } - - private int scaleXPosition(int x) { - return (int) Math.round(x / xFactor); - } - - private void fireOnKeyPressed(int keyCode, char keyChar) { - listeners.getListeners().forEach(listener -> listener.onKeyPressed(keyCode, keyChar)); - } - - private void fireOnKeyReleased(int keyCode, char keyChar) { - listeners.getListeners().forEach(listener -> listener.onKeyReleased(keyCode, keyChar)); - } - - private static class Spinner extends JPanel { - final ImageIcon waiting = getOrCreateIcon(ImageNames.WAITING); - - @Override - protected void paintComponent(Graphics g) { - super.paintComponent(g); - final int x = (getWidth() - waiting.getIconWidth()) / 2; - final int y = (getHeight() - waiting.getIconHeight()) / 2; - g.drawImage(waiting.getImage(), x, y, this); - } - } -} diff --git a/src/main/java/mpo/dayon/assistant/gui/AssistantFrameListener.java b/src/main/java/mpo/dayon/assistant/gui/AssistantFrameListener.java deleted file mode 100644 index 2a05afc3..00000000 --- a/src/main/java/mpo/dayon/assistant/gui/AssistantFrameListener.java +++ /dev/null @@ -1,17 +0,0 @@ -package mpo.dayon.assistant.gui; - -import mpo.dayon.common.event.Listener; - -public interface AssistantFrameListener extends Listener { - void onMouseMove(int x, int y); - - void onMousePressed(int x, int y, int button); - - void onMouseReleased(int x, int y, int button); - - void onMouseWheeled(int x, int y, int rotations); - - void onKeyPressed(int keyCode, char keyChar); - - void onKeyReleased(int keyCode, char keyChar); -} diff --git a/src/main/java/mpo/dayon/assistant/gui/AssistantPanel.java b/src/main/java/mpo/dayon/assistant/gui/AssistantPanel.java deleted file mode 100644 index c75c54a8..00000000 --- a/src/main/java/mpo/dayon/assistant/gui/AssistantPanel.java +++ /dev/null @@ -1,77 +0,0 @@ -package mpo.dayon.assistant.gui; - -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Image; -import java.awt.image.BufferedImage; - -import javax.swing.JPanel; -import javax.swing.SwingUtilities; - -import static mpo.dayon.common.gui.common.ImageNames.MOUSE_YELLOW; -import static mpo.dayon.common.gui.common.ImageUtilities.getOrCreateIcon; - -class AssistantPanel extends JPanel { - - private static final Image MOUSE_CURSOR = getOrCreateIcon(MOUSE_YELLOW).getImage(); - - private static final int MOUSE_CURSOR_WIDTH = 12; - private static final int MOUSE_CURSOR_HEIGHT = 20; - - private int captureWidth = -1; - private int captureHeight = -1; - - private int mouseX = -1; - private int mouseY = -1; - - private transient BufferedImage captureImage; - - AssistantPanel() { - setOpaque(true); - } - - @Override - protected void paintComponent(Graphics g) { - super.paintComponent(g); - if (captureImage != null) { - g.drawImage(captureImage, 0, 0, this); - } - paintMouse(g); - } - - private void paintMouse(Graphics g) { - if (mouseX > -1 && mouseY > -1) { - g.drawImage(MOUSE_CURSOR, mouseX, mouseY, this); - } - } - - /** - * Called from within the de-compressor engine thread (!) - */ - void onCaptureUpdated(final BufferedImage captureImage) { - SwingUtilities.invokeLater(() -> { - final int captureImageWidth = captureImage.getWidth(); - final int captureImageHeight = captureImage.getHeight(); - if (captureWidth != captureImageWidth || captureHeight != captureImageHeight) { - this.captureWidth = captureImageWidth; - this.captureHeight = captureImageHeight; - final Dimension size = new Dimension(captureImageWidth, captureImageHeight); - setSize(size); - setPreferredSize(size); - } - this.captureImage = captureImage; - repaint(); - }); - } - - void onMouseLocationUpdated(final int x, final int y) { - SwingUtilities.invokeLater(() -> { - if (this.mouseX > -1 && this.mouseY > -1) { - repaint(this.mouseX, this.mouseY, MOUSE_CURSOR_WIDTH, MOUSE_CURSOR_HEIGHT); - } - this.mouseX = x; - this.mouseY = y; - repaint(x, y, MOUSE_CURSOR_WIDTH, MOUSE_CURSOR_HEIGHT); - }); - } -} diff --git a/src/main/java/mpo/dayon/assistant/gui/RepeatingReleasedEventsFixer.java b/src/main/java/mpo/dayon/assistant/gui/RepeatingReleasedEventsFixer.java deleted file mode 100644 index 9d315114..00000000 --- a/src/main/java/mpo/dayon/assistant/gui/RepeatingReleasedEventsFixer.java +++ /dev/null @@ -1,229 +0,0 @@ -package mpo.dayon.assistant.gui; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.AWTEventListener; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.util.HashMap; -import java.util.Map; - -/** - * From the original @author Endre Stølsvik: - * - * This {@link AWTEventListener} tries to work around a 12 yo - * bug in the Linux KeyEvent handling for keyboard repeat. Linux apparently implements repeating keypresses by - * repeating both the {@link KeyEvent#KEY_PRESSED} and {@link KeyEvent#KEY_RELEASED}, while on Windows, one only - * gets repeating PRESSES, and then a final RELEASE when the key is released. The Windows way is obviously much more - * useful, as one then can easily distinguish between a user holding a key pressed, and a user hammering away on the - * key. - *

- * This class is an {@link AWTEventListener} that should be installed as the application's first ever - * {@link AWTEventListener} using the following code, but it is simpler to invoke {@link #install() install(new - * instance)}: - *

- *

- *

- * Toolkit.getDefaultToolkit().addAWTEventListener(new {@link RepeatingReleasedEventsFixer}, AWTEvent.KEY_EVENT_MASK); - *

- *

- *

- *

- * Remember to remove it and any other installed {@link AWTEventListener} if your application have some "reboot" - * functionality that can potentially install it again - or else you'll end up with multiple instances, which isn't too - * hot. - *

- * Notice: Read up on the {@link Reposted} interface if you have other AWTEventListeners that resends KeyEvents - * (as this one does) - or else we'll get the event back. - *

- *

- *

- * Mode of operation - *

- * The class makes use of the fact that the subsequent PRESSED event comes right after the RELEASED event - one thus - * have a sequence like this: - *

- *

- *

- * PRESSED - * -wait between key repeats- - * RELEASED - * PRESSED - * -wait between key repeats- - * RELEASED - * PRESSED - * etc. - *

- *

- *

- *

- * A timer is started when receiving a RELEASED event, and if a PRESSED comes soon afterwards, the RELEASED is dropped - * (consumed) - while if the timer times out, the event is reposted and thus becomes the final, wanted RELEASED that - * denotes that the key actually was released. - *

- * Inspired by http://www.arco.in-berlin.de/keyevent.html - * - * @author Endre Stølsvik - * - * Refactored by Reto Galante into a proper Singleton, so you may ignore the remove method, if you are instantiating it - * as such by calling RepeatingReleasedEventsFixer.install(); - * - */ - -public final class RepeatingReleasedEventsFixer implements AWTEventListener { - - private final Map map = new HashMap<>(); - - private static RepeatingReleasedEventsFixer instance; - - private RepeatingReleasedEventsFixer() { - // singleton - } - - public static RepeatingReleasedEventsFixer install() { - synchronized (RepeatingReleasedEventsFixer.class) { - if (instance == null) { - final RepeatingReleasedEventsFixer fixer = new RepeatingReleasedEventsFixer(); - Toolkit.getDefaultToolkit().addAWTEventListener(fixer, AWTEvent.KEY_EVENT_MASK); - instance = fixer; - } - } - return instance; - } - - public static void remove() { - if (instance != null) { - Toolkit.getDefaultToolkit().removeAWTEventListener(instance); - } - } - - @Override - public void eventDispatched(AWTEvent event) { - if (!(event instanceof KeyEvent)) { - throw new AssertionError("Shall only listen to KeyEvents, so no other events shall come here"); - } - assert assertEDT(); // REMEMBER THAT THIS IS SINGLE THREADED, so no need for synch. - - // ?: Is this one of our synthetic RELEASED events? - if (event instanceof Reposted) { - // -> Yes, so we shalln't process it again. - return; - } - - // ?: KEY_TYPED event? (We're only interested in KEY_PRESSED and KEY_RELEASED). - if (event.getID() == KeyEvent.KEY_TYPED) { - // -> Yes, TYPED, don't process. - return; - } - - final KeyEvent keyEvent = (KeyEvent) event; - - // ?: Is this already consumed? - // (Note how events are passed on to all AWTEventListeners even though a previous one consumed it) - if (keyEvent.isConsumed()) { - return; - } - - // ?: Is this RELEASED? (the problem we're trying to fix!) - if (keyEvent.getID() == KeyEvent.KEY_RELEASED) { - // -> Yes, so stick in wait - /* - * Really just wait until "immediately", as the point is that the subsequent PRESSED shall already have been - * posted on the event queue, and shall thus be the direct next event no matter which events are posted - * afterwards. The code with the ReleasedAction handles if the Timer thread actually fires the action due to - * lags, by cancelling the action itself upon the PRESSED. - */ - final Timer timer = new Timer(2, null); - ReleasedAction action = new ReleasedAction(keyEvent, timer); - timer.addActionListener(action); - timer.start(); - - map.put(keyEvent.getKeyCode(), action); - - // Consume the original - keyEvent.consume(); - } else if (keyEvent.getID() == KeyEvent.KEY_PRESSED) { - // Remember that this is single threaded (EDT), so we can't have races. - ReleasedAction action = map.remove(keyEvent.getKeyCode()); - // ?: Do we have a corresponding RELEASED waiting? - if (action != null) { - // -> Yes, so dump it - action.cancel(); - } - // System.out.println("PRESSED: [" + keyEvent + "]"); - } else { - throw new AssertionError("All IDs should be covered."); - } - } - - /** - * The ActionListener that posts the RELEASED {@link RepostedKeyEvent} if the {@link Timer} times out (and hence the - * repeat-action was over). - */ - private class ReleasedAction implements ActionListener { - - private final KeyEvent originalKeyEvent; - private Timer timer; - - ReleasedAction(KeyEvent originalReleased, Timer timer) { - this.timer = timer; - originalKeyEvent = originalReleased; - } - - void cancel() { - assert assertEDT(); - timer.stop(); - timer = null; - map.remove(originalKeyEvent.getKeyCode()); - } - - @Override - public void actionPerformed(@SuppressWarnings("unused") ActionEvent e) { - assert assertEDT(); - // ?: Are we already cancelled? - // (Judging by Timer and TimerQueue code, we can theoretically be raced to be posted onto EDT by TimerQueue, - // due to some lag, unfair scheduling) - if (timer == null) { - // -> Yes, so don't post the new RELEASED event. - return; - } - // Stop Timer and clean. - cancel(); - // Creating new KeyEvent (we've consumed the original). - KeyEvent newEvent = new RepostedKeyEvent((Component) originalKeyEvent.getSource(), - originalKeyEvent.getID(), originalKeyEvent.getWhen(), originalKeyEvent.getModifiersEx(), - originalKeyEvent.getKeyCode(), originalKeyEvent.getKeyChar(), originalKeyEvent.getKeyLocation()); - // Posting to EventQueue. - Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(newEvent); - // System.out.println("Posted synthetic RELEASED [" + newEvent + "]."); - } - } - - /** - * Marker interface that denotes that the {@link KeyEvent} in question is reposted from some - * {@link AWTEventListener}, including this. It denotes that the event shall not be "hack processed" by this class - * again. (The problem is that it is not possible to state "inject this event from this point in the pipeline" - one - * have to inject it to the event queue directly, thus it will come through this {@link AWTEventListener} too. - */ - private interface Reposted { - // marker - } - - /** - * Dead simple extension of {@link KeyEvent} that implements {@link Reposted}. - */ - static class RepostedKeyEvent extends KeyEvent implements Reposted { - RepostedKeyEvent(@SuppressWarnings("hiding") Component source, @SuppressWarnings("hiding") int id, - long when, int modifiers, int keyCode, char keyChar, int keyLocation) { - super(source, id, when, modifiers, keyCode, keyChar, keyLocation); - } - } - - private static boolean assertEDT() { - if (!EventQueue.isDispatchThread()) { - throw new AssertionError("Not EDT, but [" + Thread.currentThread() + "]."); - } - return true; - } -} diff --git a/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngine.java b/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngine.java deleted file mode 100644 index 94dfbece..00000000 --- a/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngine.java +++ /dev/null @@ -1,392 +0,0 @@ -package mpo.dayon.assistant.network; - -//import com.dosse.upnp.UPnP; -import mpo.dayon.common.compressor.CompressorEngineConfiguration; -import mpo.dayon.common.capture.CaptureEngineConfiguration; -import mpo.dayon.common.concurrent.RunnableEx; -import mpo.dayon.common.configuration.ReConfigurable; -import mpo.dayon.common.event.Listeners; -import mpo.dayon.common.log.Log; -import mpo.dayon.common.network.NetworkEngine; -import mpo.dayon.common.network.message.*; -import mpo.dayon.common.security.CustomTrustManager; -import mpo.dayon.common.version.Version; - -import javax.net.ssl.SSLServerSocket; -import javax.net.ssl.SSLServerSocketFactory; -import javax.net.ssl.SSLSocket; -import java.awt.*; -import java.awt.datatransfer.ClipboardOwner; -import java.awt.datatransfer.DataFlavor; -import java.io.*; -import java.net.Socket; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateEncodingException; - -import static java.lang.String.format; -import static mpo.dayon.common.utils.SystemUtilities.safeClose; -import static mpo.dayon.common.version.Version.isColoredVersion; -import static mpo.dayon.common.version.Version.isCompatibleVersion; - -public class NetworkAssistantEngine extends NetworkEngine implements ReConfigurable { - - private final NetworkCaptureMessageHandler captureMessageHandler; - - private final NetworkMouseLocationMessageHandler mouseMessageHandler; - - private final ClipboardOwner clipboardOwner; - - private final Listeners listeners = new Listeners<>(); - - private NetworkAssistantEngineConfiguration configuration; - - private SSLServerSocketFactory ssf; - - private static final String APP_NAME = "Dayon!"; - - public NetworkAssistantEngine(NetworkCaptureMessageHandler captureMessageHandler, NetworkMouseLocationMessageHandler mouseMessageHandler, ClipboardOwner clipboardOwner) { - this.captureMessageHandler = captureMessageHandler; - this.mouseMessageHandler = mouseMessageHandler; - this.clipboardOwner = clipboardOwner; - fireOnReady(); - } - - @Override - public void configure(NetworkAssistantEngineConfiguration configuration) { - this.configuration = configuration; - } - - @Override - public void reconfigure(NetworkAssistantEngineConfiguration configuration) { - this.configuration = configuration; - } - - public void addListener(NetworkAssistantEngineListener listener) { - listeners.add(listener); - } - - /** - * Called from a GUI action => do not block the AWT thread (!) - */ - public void start(boolean compatibilityMode) { - if (cancelling.get() || receiver != null) { - return; - } -// if (UPnP.isUPnPAvailable() && !UPnP.isMappedTCP(configuration.getPort())) { -// UPnP.openPortTCP(configuration.getPort(), APP_NAME); -// } - receiver = new Thread(new RunnableEx() { - @Override - protected void doRun() throws NoSuchAlgorithmException, KeyManagementException { - NetworkAssistantEngine.this.receivingLoop(compatibilityMode); - } - }, "NetworkReceiver"); - receiver.start(); - } - - /** - * Called from a GUI action => do not block the AWT thread (!) - */ - public void cancel() { - Log.info("Cancelling the network assistant engine..."); - cancelling.set(true); - safeClose(server, connection, fileServer, fileConnection); - fireOnDisconnecting(); - } - - public void manageRouterPorts(int oldPort, int newPort) { -// if (UPnP.isUPnPAvailable()) { -// UPnP.closePortTCP(oldPort); -// UPnP.openPortTCP(newPort, APP_NAME); -// } - } - - // right, keep streams open - forever! - @java.lang.SuppressWarnings({"squid:S2189", "squid:S2093"}) - private void receivingLoop(boolean compatibilityMode) throws NoSuchAlgorithmException, KeyManagementException { - in = null; - boolean introduced = false; - boolean proceed = true; - - try { - awaitConnections(compatibilityMode); - startFileReceiver(); - initSender(8); - initInputStream(); - - while (proceed) { - NetworkMessage.unmarshallMagicNumber(in); // blocking read (!) - NetworkMessageType type = NetworkMessage.unmarshallEnum(in, NetworkMessageType.class); - Log.debug("Received %s", type::name); - - if (introduced) { - proceed = processIntroduced(type, in); - } else { - introduced = processUnIntroduced(type, in); - } - } - } catch (IOException ex) { - handleIOException(ex); - } catch (CertificateEncodingException ex) { - Log.error(ex.getMessage()); - } catch (ClassNotFoundException e) { - throw new IllegalArgumentException(e); - } finally { - closeConnections(); - //UPnP.closePortTCP(configuration.getPort()); - fireOnReady(); - } - - } - - private void awaitConnections(boolean compatibilityMode) throws NoSuchAlgorithmException, IOException, KeyManagementException, CertificateEncodingException { - fireOnStarting(configuration.getPort()); - ssf = CustomTrustManager.initSslContext(compatibilityMode).getServerSocketFactory(); - Log.info(format("Dayon! server [port:%d]", configuration.getPort())); - if (compatibilityMode) { - Log.warn("Compatibility mode enabled, using legacy certificate"); - } - if (server != null && server.isBound()) { - safeClose(server); - } - server = (SSLServerSocket) ssf.createServerSocket(configuration.getPort()); - server.setNeedClientAuth(true); - Log.info("Accepting..."); - - do { - if (connection != null && connection.isBound()) { - safeClose(connection); // we might have refused the accepted connection (!) - } - connection = (SSLSocket) server.accept(); - Toolkit.getDefaultToolkit().beep(); - if (!connection.getSession().isValid()) { - fireOnFingerprinted(null); - throw new IOException("Certificate error, try enabling compatibility mode!"); - } - fireOnFingerprinted(CustomTrustManager.calculateFingerprints(connection.getSession(), this.getClass().getSimpleName())); - Log.info(format("Incoming connection from %s", connection.getInetAddress().getHostAddress())); - } while (!fireOnAccepted(connection) && !cancelling.get()); - - if (server.isBound()) { - safeClose(server); - } - server = null; - } - - private void startFileReceiver() { - fileReceiver = new Thread(new RunnableEx() { - @Override - protected void doRun() { - NetworkAssistantEngine.this.fileReceivingLoop(); - } - }, "FileReceiver"); - - fileReceiver.start(); - } - - // right, keep streams open - forever! - @java.lang.SuppressWarnings({"squid:S2189", "squid:S2093"}) - private void fileReceivingLoop() { - fileIn = null; - Log.info(format("Dayon! file server [port:%d]", configuration.getPort())); - - try { - fileServer = (SSLServerSocket) ssf.createServerSocket(configuration.getPort()); - fileConnection = (SSLSocket) fileServer.accept(); - initFileSender(); - fileIn = new ObjectInputStream(new BufferedInputStream(fileConnection.getInputStream())); - - handleIncomingClipboardFiles(fileIn, clipboardOwner); - } catch (IOException ex) { - closeConnections(); - } - } - - private boolean processIntroduced(NetworkMessageType type, ObjectInputStream in) throws IOException, ClassNotFoundException { - switch (type) { - case CAPTURE: - final NetworkCaptureMessage capture = NetworkCaptureMessage.unmarshall(in); - fireOnByteReceived(1 + capture.getWireSize()); // +1 : magic number (byte) - captureMessageHandler.handleCapture(capture); - return true; - - case MOUSE_LOCATION: - final NetworkMouseLocationMessage mouse = NetworkMouseLocationMessage.unmarshall(in); - fireOnByteReceived(1 + mouse.getWireSize()); // +1 : magic number (byte) - mouseMessageHandler.handleLocation(mouse); - return true; - - case CLIPBOARD_TEXT: - final NetworkClipboardTextMessage clipboardTextMessage = NetworkClipboardTextMessage.unmarshall(in); - fireOnByteReceived(1 + clipboardTextMessage.getWireSize()); // +1 : magic number (byte) - setClipboardContents(clipboardTextMessage.getText(), clipboardOwner); - fireOnClipboardReceived(); - return true; - - case CLIPBOARD_GRAPHIC: - final NetworkClipboardGraphicMessage clipboardGraphicMessage = NetworkClipboardGraphicMessage.unmarshall(in); - fireOnByteReceived(1 + clipboardGraphicMessage.getWireSize()); // +1 : magic number (byte) - setClipboardContents(clipboardGraphicMessage.getGraphic().getTransferData(DataFlavor.imageFlavor), clipboardOwner); - fireOnClipboardReceived(); - return true; - - case PING: - fireOnClipboardSent(); - return true; - - case RESIZE: - final NetworkResizeScreenMessage resize = NetworkResizeScreenMessage.unmarshall(in); - fireOnByteReceived(1 + resize.getWireSize()); // +1 : magic number (byte) - fireOnResizeScreen(resize.getWidth(), resize.getHeight()); - return true; - - case GOODBYE: - fireOnTerminating(); - return false; - - case HELLO: - throw new IllegalArgumentException("Unexpected message [HELLO]!"); - - default: - throw new IllegalArgumentException(format(UNSUPPORTED_TYPE, type)); - } - } - - private boolean processUnIntroduced(NetworkMessageType type, ObjectInputStream in) throws IOException { - switch (type) { - case HELLO: - fireOnConnected(connection, introduce(in)); - return true; - - case PING: - return false; - - case CAPTURE: - case MOUSE_LOCATION: - case CLIPBOARD_TEXT: - case CLIPBOARD_GRAPHIC: - case CLIPBOARD_FILES: - case GOODBYE: - throw new IllegalArgumentException(format("Unexpected message [%s]!", type.name())); - - default: - throw new IllegalArgumentException(format(UNSUPPORTED_TYPE, type)); - } - } - - private NetworkHelloMessage introduce(ObjectInputStream in) throws IOException { - final NetworkHelloMessage hello = NetworkHelloMessage.unmarshall(in); - fireOnByteReceived(1 + hello.getWireSize()); // +1 : magic number (byte) - if (!isCompatibleVersion(hello.getMajor(), hello.getMinor(), Version.get())) { - Log.error(format("Incompatible assisted version: %d.%d", hello.getMajor(), hello.getMinor())); - throw new IOException("version.wrong"); - } - configuration.setMonochromePeer(!isColoredVersion(hello.getMajor())); - return hello; - } - - /** - * Might be blocking if the sender queue is full (!) - */ - public void sendCaptureConfiguration(CaptureEngineConfiguration configuration) { - if (sender != null) { - sender.sendCaptureConfiguration(configuration, this.configuration.isMonochromePeer()); - } - } - - /** - * Might be blocking if the sender queue is full (!) - */ - public void sendCompressorConfiguration(CompressorEngineConfiguration configuration) { - if (sender != null) { - sender.sendCompressorConfiguration(configuration); - } - } - - /** - * Might be blocking if the sender queue is full (!) - */ - public void sendMouseControl(NetworkMouseControlMessage message) { - if (sender != null) { - sender.sendMouseControl(message); - } - } - - /** - * Might be blocking if the sender queue is full (!) - */ - public void sendKeyControl(NetworkKeyControlMessage message) { - if (sender != null) { - sender.sendKeyControl(message); - } - } - - /** - * Might be blocking if the sender queue is full (!) - */ - public void sendRemoteClipboardRequest() { - if (sender != null) { - sender.sendRemoteClipboardRequest(); - } - } - - /** - * Might be blocking if the sender queue is full (!) - */ - public void sendScreenshotRequest() { - if (sender != null) { - sender.sendScreenshotRequest(); - } - } - - private void fireOnReady() { - listeners.getListeners().forEach(NetworkAssistantEngineListener::onReady); - } - - private void fireOnStarting(int port) { - listeners.getListeners().forEach(listener -> listener.onStarting(port)); - } - - private boolean fireOnAccepted(Socket connection) { - return listeners.getListeners().stream().allMatch(listener -> listener.onAccepted(connection)); - } - - private void fireOnConnected(Socket connection, NetworkHelloMessage hello) { - listeners.getListeners().forEach(listener -> listener.onConnected(connection, hello.getOsId(), hello.getInputLocale(), hello.getMajor())); - } - - private void fireOnByteReceived(int count) { - listeners.getListeners().forEach(listener -> listener.onByteReceived(count)); - } - - @Override - protected void fireOnClipboardReceived() { - listeners.getListeners().forEach(NetworkAssistantEngineListener::onClipboardReceived); - } - - private void fireOnClipboardSent() { - listeners.getListeners().forEach(NetworkAssistantEngineListener::onClipboardSent); - } - - private void fireOnResizeScreen(int width, int height) { - listeners.getListeners().forEach(listener -> listener.onResizeScreen(width, height)); - } - - private void fireOnDisconnecting() { - listeners.getListeners().forEach(NetworkAssistantEngineListener::onDisconnecting); - } - - private void fireOnTerminating() { - listeners.getListeners().forEach(NetworkAssistantEngineListener::onTerminating); - } - - @Override - protected void fireOnIOError(IOException error) { - listeners.getListeners().forEach(listener -> listener.onIOError(error)); - } - - private void fireOnFingerprinted(String fingerprints) { - listeners.getListeners().forEach(listener -> listener.onFingerprinted(fingerprints)); - } -} diff --git a/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngineConfiguration.java b/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngineConfiguration.java deleted file mode 100644 index ca47fe91..00000000 --- a/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngineConfiguration.java +++ /dev/null @@ -1,89 +0,0 @@ -package mpo.dayon.assistant.network; - -import mpo.dayon.common.configuration.Configuration; -import mpo.dayon.common.preference.Preferences; - -import java.util.Objects; - -import static mpo.dayon.common.utils.SystemUtilities.DEFAULT_TOKEN_SERVER_URL; - -public class NetworkAssistantEngineConfiguration extends Configuration { - private static final String PREF_VERSION = "assistant.network.version"; - - private static final String PREF_PORT_NUMBER = "assistant.network.portNumber"; - - private static final String PREF_TOKEN_SERVER_URL = "assistant.network.tokenServerUrl"; - - private final int port; - - private final String tokenServerUrl; - - private boolean monochromePeer = false; - - /** - * Default : takes its values from the current preferences. - */ - public NetworkAssistantEngineConfiguration() { - port = Preferences.getPreferences().getIntPreference(PREF_PORT_NUMBER, 8080); - tokenServerUrl = Preferences.getPreferences().getStringPreference(PREF_TOKEN_SERVER_URL, DEFAULT_TOKEN_SERVER_URL); - } - - public NetworkAssistantEngineConfiguration(int port, String tokenServerUrl) { - this.port = port; - this.tokenServerUrl = tokenServerUrl; - } - - public int getPort() { - return port; - } - - public String getTokenServerUrl() { - return tokenServerUrl; - } - - public boolean isMonochromePeer() { - return monochromePeer; - } - - public void setMonochromePeer(boolean monochromePeer) { - this.monochromePeer = monochromePeer; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - final NetworkAssistantEngineConfiguration that = (NetworkAssistantEngineConfiguration) o; - - return port == that.getPort() && tokenServerUrl.equals(that.getTokenServerUrl()); - } - - @Override - public int hashCode() { - return Objects.hash(port, tokenServerUrl); - } - - /** - * @param clear - * allows for clearing properties from previous version - */ - @Override - protected void persist(boolean clear) { - final Preferences.Props props = new Preferences.Props(); - props.set(PREF_VERSION, String.valueOf(1)); - props.set(PREF_PORT_NUMBER, String.valueOf(port)); - props.set(PREF_TOKEN_SERVER_URL, tokenServerUrl); - - if (clear) // migration support (!) - { - props.clear("assistantPortNumber"); - } - Preferences.getPreferences().update(props); // atomic (!) - } - -} diff --git a/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngineListener.java b/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngineListener.java deleted file mode 100644 index 21e6af80..00000000 --- a/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngineListener.java +++ /dev/null @@ -1,56 +0,0 @@ -package mpo.dayon.assistant.network; - -import java.io.IOException; -import java.net.Socket; - -import mpo.dayon.common.event.Listener; - -public interface NetworkAssistantEngineListener extends Listener { - void onReady(); - - /** - * Should not block as called from the network receiving thread (!) - */ - void onStarting(int port); - - /** - * Should not block as called from the network receiving thread (!) - */ - boolean onAccepted(Socket connection); - - /** - * Should not block as called from the network receiving thread (!) - */ - void onConnected(Socket connection, char osId, String inputLocale, int peerMajorVersion); - - /** - * Should not block as called from the network receiving thread (!) - */ - void onByteReceived(int count); - - /** - * Should not block as called from the network receiving thread (!) - */ - void onClipboardReceived(); - - /** - * Should not block as called from the network receiving thread (!) - */ - void onClipboardSent(); - - /** - * Should not block as called from the network receiving thread (!) - */ - void onResizeScreen(int width, int height); - - /** - * Should not block as called from the network receiving thread (!) - */ - void onDisconnecting(); - - void onTerminating(); - - void onIOError(IOException error); - - void onFingerprinted(String fingerprints); -} diff --git a/src/main/java/mpo/dayon/assistant/utils/NetworkUtilities.java b/src/main/java/mpo/dayon/assistant/utils/NetworkUtilities.java deleted file mode 100644 index b52ead55..00000000 --- a/src/main/java/mpo/dayon/assistant/utils/NetworkUtilities.java +++ /dev/null @@ -1,42 +0,0 @@ -package mpo.dayon.assistant.utils; - -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; - -import mpo.dayon.common.log.Log; - -public interface NetworkUtilities { - static List getInetAddresses() { - final List addresses = new ArrayList<>(); - - try { - InetAddress loopback = null; - - final Enumeration nintfs = NetworkInterface.getNetworkInterfaces(); - while (nintfs.hasMoreElements()) { - final Enumeration inetAddresses = nintfs.nextElement().getInetAddresses(); - while (inetAddresses.hasMoreElements()) { - final InetAddress inetAddress = inetAddresses.nextElement(); - if (!inetAddress.isLoopbackAddress()) { - addresses.add(inetAddress.getHostAddress()); - } else { - loopback = inetAddress; - } - } - } - - if (loopback != null) { - addresses.add(loopback.getHostAddress()); - } - } catch (SocketException ex) { - Log.warn("Inet Addresses error!", ex); - } - - return addresses; - } - -} diff --git a/src/main/java/mpo/dayon/assisted/gui/AssistedFrame.java b/src/main/java/mpo/dayon/assisted/gui/AssistedFrame.java index 39fbb899..12a1c496 100755 --- a/src/main/java/mpo/dayon/assisted/gui/AssistedFrame.java +++ b/src/main/java/mpo/dayon/assisted/gui/AssistedFrame.java @@ -33,7 +33,7 @@ class AssistedFrame extends BaseFrame { this.startAction = startAction; this.startButton = createButton(this.startAction); this.stopButton = createButton(this.stopAction, false); - this.connectionSettingsButton = createButton(createConnectionSettingsAction(null)); + this.connectionSettingsButton = createButton(createConnectionSettingsAction()); this.toggleMultiScreenCaptureAction = toggleMultiScreenCaptureAction; setupToolBar(createToolBar()); setupStatusBar(createStatusBar()); diff --git a/src/main/java/mpo/dayon/common/gui/common/BaseFrame.java b/src/main/java/mpo/dayon/common/gui/common/BaseFrame.java index c7fc0ae9..84907cf3 100644 --- a/src/main/java/mpo/dayon/common/gui/common/BaseFrame.java +++ b/src/main/java/mpo/dayon/common/gui/common/BaseFrame.java @@ -10,6 +10,7 @@ import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.Duration; +import java.util.Locale; import java.util.concurrent.ExecutionException; import java.util.concurrent.CompletableFuture; import java.util.regex.Pattern; @@ -17,10 +18,6 @@ import javax.swing.*; import javax.swing.border.EmptyBorder; -import com.dosse.upnp.UPnP; -import mpo.dayon.assistant.gui.Assistant; -import mpo.dayon.assistant.network.NetworkAssistantEngine; -import mpo.dayon.assistant.network.NetworkAssistantEngineConfiguration; import mpo.dayon.assisted.network.NetworkAssistedEngineConfiguration; import mpo.dayon.common.gui.statusbar.StatusBar; import mpo.dayon.common.gui.toolbar.ToolBar; @@ -99,7 +96,6 @@ private void doExit() { protected void setFrameType(FrameType frameType) { this.frameType = frameType; setupWindow(); - setTitle(format("Dayon! (%s) %s", translate(frameType.getPrefix()), Version.get())); } private void setupWindow() { @@ -110,8 +106,18 @@ private void setupWindow() { this.position = new Position(configuration.getX() + dimension.width < maximumWindowBounds.width ? configuration.getX() : (maximumWindowBounds.width - dimension.width) / 2, configuration.getY() + dimension.height < maximumWindowBounds.height ? configuration.getY() : (maximumWindowBounds.height - dimension.height) / 2); this.setSize(dimension.width, dimension.height); - setTitle(format("Fensterkitt Support App %s", Version.get())); - this.setLocation(position.getX(), position.getY()); + String titleString = "Fensterkitt Support App"; + updateTitle(titleString, Version.get()); + } + + private void updateTitle(String titleString, Version version) { + setTitle(titleString, version); + new Timer(5000, e -> setTitle(titleString, version)).start(); + } + + private void setTitle(String titleString, Version version) { + Locale locale = InputContext.getInstance().getLocale(); + setTitle(format("%s %s %s", titleString, version, locale != null ? locale.toString() : "")); } protected void setupToolBar(ToolBar toolBar) { @@ -121,12 +127,7 @@ protected void setupToolBar(ToolBar toolBar) { fingerprints.setBorder(BorderFactory.createEmptyBorder(0, 10, 35, 0)); } toolBar.add(fingerprints); - //toolBar.addAction(createShowInfoAction(), alignmentY); - //toolBar.addAction(createShowHelpAction(), alignmentY); toolBar.addAction(createExitAction(), alignmentY); - if (FrameType.ASSISTANT.equals(frameType)) { - toolBar.add(DEFAULT_SPACER); - } add(toolBar, BorderLayout.NORTH); toolBar.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); this.toolBar = toolBar; @@ -275,7 +276,7 @@ public void actionPerformed(ActionEvent ev) { return showSystemInfo; } - protected Action createConnectionSettingsAction(Assistant assistant) { + protected Action createConnectionSettingsAction() { final Action conf = new AbstractAction() { @Override public void actionPerformed(ActionEvent ev) { @@ -287,7 +288,7 @@ public void actionPerformed(ActionEvent ev) { final ButtonGroup tokenRadioGroup = new ButtonGroup(); final JTextField customTokenTextField = new JTextField(); - JPanel panel = createPanel(addressTextField, portNumberTextField, autoConnectCheckBox, tokenRadioGroup, customTokenTextField, (assistant != null && assistant.isUpnpEnabled())); + JPanel panel = createPanel(addressTextField, portNumberTextField, autoConnectCheckBox, tokenRadioGroup, customTokenTextField, false); final boolean ok = DialogFactory.showOkCancel(networkFrame, translate("connection.network"), panel, true, () -> validateInputFields(addressTextField, portNumberTextField, tokenRadioGroup, customTokenTextField)); @@ -296,11 +297,7 @@ public void actionPerformed(ActionEvent ev) { final String newTokenServerUrl = tokenRadioGroup.getSelection().getActionCommand().equals(CUSTOM) && isValidUrl(customTokenTextField.getText()) ? customTokenTextField.getText() : ""; updateSystemProperty(newTokenServerUrl); - if (assistant == null) { - updateAssistedNetworkConfiguration(addressTextField, portNumberTextField, autoConnectCheckBox, newTokenServerUrl); - } else { - updateAssistantNetworkConfiguration(portNumberTextField, newTokenServerUrl, assistant.getNetworkEngine()); - } + updateAssistedNetworkConfiguration(addressTextField, portNumberTextField, autoConnectCheckBox, newTokenServerUrl); } } }; @@ -318,7 +315,6 @@ private JPanel createPanel(JTextField addressTextField, JTextField portNumberTex if (frameType.equals(FrameType.ASSISTED)) { final NetworkAssistedEngineConfiguration networkConfiguration = new NetworkAssistedEngineConfiguration(); - currentTokenServer = networkConfiguration.getTokenServerUrl(); final JLabel hostLbl = new JLabel(toUpperFirst(translate("assistant"))); hostLbl.setFont(titleFont); panel.add(hostLbl, createGridBagConstraints(gridy++)); @@ -337,69 +333,8 @@ private JPanel createPanel(JTextField addressTextField, JTextField portNumberTex autoConnectCheckBox.setSelected(networkConfiguration.isAutoConnect()); assistantPanel.add(autoConnectCheckBox); panel.add(assistantPanel, createGridBagConstraints(gridy++)); - } else { - final NetworkAssistantEngineConfiguration networkConfiguration = new NetworkAssistantEngineConfiguration(); - currentTokenServer = networkConfiguration.getTokenServerUrl(); - final JLabel hostLbl = new JLabel(toUpperFirst(translate("host"))); - hostLbl.setFont(titleFont); - panel.add(hostLbl, createGridBagConstraints(gridy++)); - - final JPanel upnpPanel = new JPanel(new GridLayout(1, 1, 10, 0)); - upnpPanel.setBorder(BorderFactory.createEmptyBorder(10,0,0,0)); - boolean upnpActive = assistant.isUpnpEnabled(); - final JLabel upnpStatus = new JLabel(format("%s
%s", format(translate(format("connection.settings.upnp.%s", upnpActive)), null), translate(format("connection.settings.portforward.%s", upnpActive)))); - upnpPanel.add(upnpStatus); - panel.add(upnpPanel, createGridBagConstraints(gridy++)); - - final JPanel portPanel = new JPanel(new GridLayout(1, 2, 10, 0)); - portPanel.setBorder(BorderFactory.createEmptyBorder(10,0,20,0)); - final JLabel portNumberLbl = new JLabel(translate("connection.settings.portNumber")); - portNumberLbl.setToolTipText(translate("connection.settings.portNumber.tooltip")); - portNumberTextField.setText(format("%d", networkConfiguration.getPort())); - portPanel.add(portNumberLbl); - portPanel.add(portNumberTextField); - panel.add(portPanel, createGridBagConstraints(gridy++)); - } - - final JLabel tokenServerLbl = new JLabel(toUpperFirst(translate("token.server"))); - tokenServerLbl.setFont(titleFont); - panel.add(tokenServerLbl, createGridBagConstraints(gridy++)); - - final JPanel tokenPanel = new JPanel(new GridLayout(3, 2, 10, 0)); - tokenPanel.setBorder(BorderFactory.createEmptyBorder(10,0,0,0)); - - final ButtonGroup tokenRadioGroup = new ButtonGroup(); - final JRadioButton defaultTokenRadio = new JRadioButton(translate("token.default.server")); - defaultTokenRadio.setActionCommand("default"); - final JRadioButton customTokenRadio = new JRadioButton(translate("token.custom.server")); - customTokenRadio.setActionCommand(custom); - tokenRadioGroup.add(defaultTokenRadio); - tokenRadioGroup.add(customTokenRadio); - boolean customTextFieldEditable = false; - if (currentTokenServer.isEmpty() || currentTokenServer.equals(DEFAULT_TOKEN_SERVER_URL)) { - currentTokenServer = ""; - defaultTokenRadio.setSelected(true); - } else { - customTokenRadio.setSelected(true); - customTextFieldEditable = true; } - final JTextField defaultTokenTextField = new JTextField(DEFAULT_TOKEN_SERVER_URL); - defaultTokenTextField.setEditable(false); - defaultTokenTextField.setFocusable(false); - customTokenTextField.setText(currentTokenServer); - customTokenTextField.setEditable(customTextFieldEditable); - - defaultTokenRadio.addActionListener(evt -> {defaultTokenRadio.requestFocus(); customTokenTextField.setEditable(false);}); - customTokenRadio.addActionListener(evt -> {customTokenTextField.requestFocus(); customTokenTextField.setEditable(true);}); - - tokenPanel.add(defaultTokenRadio); - tokenPanel.add(defaultTokenTextField); - - tokenPanel.add(customTokenRadio); - tokenPanel.add(customTokenTextField); - panel.add(tokenPanel, createGridBagConstraints(gridy)); - return panel; } @@ -439,18 +374,6 @@ private void updateAssistedNetworkConfiguration(JTextField addressTextField, JTe } } - private void updateAssistantNetworkConfiguration(JTextField portNumberTextField, String newTokenServerUrl, NetworkAssistantEngine networkEngine) { - final NetworkAssistantEngineConfiguration newNetworkConfiguration = new NetworkAssistantEngineConfiguration( - Integer.parseInt(portNumberTextField.getText()), newTokenServerUrl); - - NetworkAssistantEngineConfiguration networkConfiguration = new NetworkAssistantEngineConfiguration(); - if (!newNetworkConfiguration.equals(networkConfiguration)) { - networkEngine.manageRouterPorts(networkConfiguration.getPort(), newNetworkConfiguration.getPort()); - newNetworkConfiguration.persist(); - networkEngine.reconfigure(newNetworkConfiguration); - } - } - private void updateSystemProperty(String newTokenServerUrl) { if (newTokenServerUrl.isEmpty()) { System.clearProperty("dayon.custom.tokenServer"); diff --git a/src/main/resources/Babylon.properties b/src/main/resources/Babylon.properties index 36c7f5be..b38bb19a 100644 --- a/src/main/resources/Babylon.properties +++ b/src/main/resources/Babylon.properties @@ -22,8 +22,7 @@ max = Max start.session = Start accepting incoming connection stop.session = Stop the current session - -connect.assistant = Connect to assistant +connect.assistant=Connect to Fensterkitt control.mode = Toggle remote control @@ -33,7 +32,7 @@ host = Host exit = Exit exit.confirm = Are you sure you want to exit? -exit.dayon = Exit Dayon! +exit.dayon = Exit! # System ... diff --git a/src/main/resources/Babylon_de.properties b/src/main/resources/Babylon_de.properties index 01a815bf..6697c207 100644 --- a/src/main/resources/Babylon_de.properties +++ b/src/main/resources/Babylon_de.properties @@ -20,8 +20,7 @@ min = Min max = Max start.session = Akzeptiere eingehende Verbindungen stop.session = Stoppe aktuelle Sitzung - -connect.assistant = Verbinde mit Assistent +connect.assistant=Verbinde mit Fensterkitt control.mode = Fernbedienung ein/ausschalten @@ -29,7 +28,7 @@ control.mode = Fernbedienung ein/ausschalten exit = Beenden exit.confirm = Wollen Sie wirklich beenden? -exit.dayon = Beende Dayon! +exit.dayon = Beenden! # System ... diff --git a/src/main/resources/Babylon_es.properties b/src/main/resources/Babylon_es.properties index 56a56a27..f79737a8 100644 --- a/src/main/resources/Babylon_es.properties +++ b/src/main/resources/Babylon_es.properties @@ -22,8 +22,7 @@ max = M\u00E1x start.session = Comenzar a aceptar conexiones entrantes stop.session = Terminar sesi\u00F3n actual - -connect.assistant = Conectarse al asistente +connect.assistant=Conectarse al Fensterkitt control.mode = Alternar control remoto @@ -33,7 +32,7 @@ host = Acogida exit = Terminar exit.confirm = \u00BFEst\u00E1s seguro de que quieres terminar la aplicaci\u00F3n? -exit.dayon = Terminar Dayon! +exit.dayon = Terminar # System ... diff --git a/src/main/resources/Babylon_fr.properties b/src/main/resources/Babylon_fr.properties index 1f46f13e..b790bc47 100644 --- a/src/main/resources/Babylon_fr.properties +++ b/src/main/resources/Babylon_fr.properties @@ -22,8 +22,7 @@ max = Max start.session = D\u00E9marrer une session stop.session = Arr\u00EAter la session en cours - -connect.assistant = Connectez-vous \u00E0 l'assistant +connect.assistant=Connectez-vous avec Fensterkitt control.mode = Activer/D\u00E9sactiver le control \u00E0 distance @@ -33,7 +32,7 @@ host = H\u00F4te exit = Quitter exit.confirm = \u00CAtes-vous s\u00FBr de vouloir quitter l'application? -exit.dayon = Quitter Dayon! +exit.dayon = Quitter! # System ... diff --git a/src/main/resources/Babylon_it.properties b/src/main/resources/Babylon_it.properties index d62b27d7..615657bc 100644 --- a/src/main/resources/Babylon_it.properties +++ b/src/main/resources/Babylon_it.properties @@ -22,8 +22,7 @@ max = Max start.session = Inizia ad accettare la connessione in entrata stop.session = Ferma la sessione corrente - -connect.assistant = Connettiti all'assistente +connect.assistant=Connettiti a Fensterkitt control.mode = Attiva / disattiva il telecomando @@ -33,7 +32,7 @@ host = Ospite exit = Esci exit.confirm = Sei sicuro di voler uscire? -exit.dayon = Esci da Dayon! +exit.dayon = Esci! # System ... diff --git a/src/main/resources/Babylon_ru.properties b/src/main/resources/Babylon_ru.properties index 9c62c4bb..d1a9f749 100644 --- a/src/main/resources/Babylon_ru.properties +++ b/src/main/resources/Babylon_ru.properties @@ -22,8 +22,7 @@ max = \u041C\u0430\u043A\u0441 start.session = \u041D\u0430\u0447\u0430\u0442\u044C \u043F\u0440\u0438\u0435\u043C \u0432\u0445\u043E\u0434\u044F\u0449\u0435\u0433\u043E \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u044F stop.session = \u041E\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u0442\u0435\u043A\u0443\u0449\u0438\u0439 \u0441\u0435\u0430\u043D\u0441 - -connect.assistant = \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u0441\u044F \u043A \u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A\u0443 +connect.assistant=\u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u0441\u044F \u043A Fensterkitt control.mode = \u041F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u0443\u0434\u0430\u043B\u0435\u043D\u043D\u043E\u0435 \u0443\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 @@ -33,7 +32,7 @@ host = \u0425\u043E\u0437\u044F\u0438\u043D exit = \u0412\u044B\u0445\u043E\u0434 exit.confirm = \u0412\u044B \u0443\u0432\u0435\u0440\u0435\u043D\u044B, \u0447\u0442\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u0432\u044B\u0439\u0442\u0438? -exit.dayon = \u0412\u044B\u0439\u0442\u0438 \u0438\u0437 Dayon! +exit.dayon = \u0412\u044B\u0445\u043E\u0434! # System ... diff --git a/src/main/resources/Babylon_sv.properties b/src/main/resources/Babylon_sv.properties index 5fde21e8..51e66221 100644 --- a/src/main/resources/Babylon_sv.properties +++ b/src/main/resources/Babylon_sv.properties @@ -22,8 +22,7 @@ max = Max start.session = Acceptera inkommande anslutning stop.session = Avbryt nuvarande anslutning - -connect.assistant = Anslut till hj\u00E4lpgivare +connect.assistant=Anslut till Fensterkitt control.mode = Distanskontroll p\u00E5/av @@ -33,7 +32,7 @@ host = V\u00E4rd exit = Avsluta exit.confirm = \u00C4r du s\u00E4ker p\u00E5 att du vill avsluta? -exit.dayon = Avsluta Dayon! +exit.dayon = Avsluta! # System ... diff --git a/src/main/resources/Babylon_tr.properties b/src/main/resources/Babylon_tr.properties index a140ef32..ac17868d 100644 --- a/src/main/resources/Babylon_tr.properties +++ b/src/main/resources/Babylon_tr.properties @@ -22,8 +22,7 @@ max = Maks start.session = Oturum ba\u015Flat stop.session = Mevcut oturumu sonland\u0131r - -connect.assistant = Asistana ba\u011Flan +connect.assistant=Fensterkitt ba\u011Flan control.mode = Uzaktan kontrol\u00FC a\u00E7/kapat @@ -33,7 +32,7 @@ host = Ev sahibi exit = \u00C7\u0131k\u0131\u015F exit.confirm = \u00C7\u0131kmak istedi\u011Finize emin misiniz? -exit.dayon = Dayon!'dan \u00E7\u0131k +exit.dayon = \u00C7\u0131k\u0131\u015F! # System ... diff --git a/src/main/resources/Babylon_zh.properties b/src/main/resources/Babylon_zh.properties index e671cc96..db042ec3 100644 --- a/src/main/resources/Babylon_zh.properties +++ b/src/main/resources/Babylon_zh.properties @@ -46,8 +46,8 @@ host = \u4E3B\u673A # Exit ... exit = \u9000\u51FA # Are you sure you want to exit? -exit.confirm = \u662F\u5426\u5173\u95ED Dayon! \uFF1F -exit.dayon = \u9000\u51FA Dayon! +exit.confirm = \u662F\u5426\u5173\u95ED\uFF1F +exit.dayon = \u9000\u51FA! # System ... # System information diff --git a/src/test/java/mpo/dayon/assistant/control/ControlEngineTest.java b/src/test/java/mpo/dayon/assistant/control/ControlEngineTest.java deleted file mode 100644 index d658af76..00000000 --- a/src/test/java/mpo/dayon/assistant/control/ControlEngineTest.java +++ /dev/null @@ -1,73 +0,0 @@ -package mpo.dayon.assistant.control; - -import mpo.dayon.assistant.network.NetworkAssistantEngine; -import mpo.dayon.common.network.message.NetworkKeyControlMessage; -import mpo.dayon.common.network.message.NetworkMouseControlMessage; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.mockito.Mockito.*; - -class ControlEngineTest { - private static NetworkAssistantEngine network; - private static ControlEngine controlEngine; - - @BeforeAll - static void init() { - network = mock(NetworkAssistantEngine.class); - controlEngine = new ControlEngine(network); - } - - @Test - void onMouseMove() { - // when - controlEngine.onMouseMove(1, 1); - // then - verify(network, timeout(100).atLeastOnce()).sendMouseControl(any(NetworkMouseControlMessage.class)); - } - - @Test - void onMouseWheeled() { - // when - controlEngine.onMouseWheeled(1, 2, 3); - // then - verify(network, timeout(100).atLeastOnce()).sendMouseControl(any(NetworkMouseControlMessage.class)); - } - - @Test - void onMousePressed() { - // when - controlEngine.onMousePressed(1, 1, 1); - // then - verify(network, timeout(100).atLeastOnce()).sendMouseControl(any(NetworkMouseControlMessage.class)); - } - - @Test - void onMouseReleased() { - // when - controlEngine.onMouseReleased(1, 1, 2); - // then - verify(network, timeout(100).atLeastOnce()).sendMouseControl(any(NetworkMouseControlMessage.class)); - } - - @Test - void keyMustBePressedBeforeReleased() { - // given - final int keyD = 68; - final char charD = 'D'; - // when - controlEngine.onKeyReleased(keyD, charD); - // then - verify(network, never()).sendKeyControl(any(NetworkKeyControlMessage.class)); - - // when - controlEngine.onKeyPressed(keyD, charD); - // then - verify(network, timeout(50).atLeastOnce()).sendKeyControl(any(NetworkKeyControlMessage.class)); - - // when - controlEngine.onKeyReleased(keyD, charD); - // then - verify(network, timeout(50).atLeast(2)).sendKeyControl(any(NetworkKeyControlMessage.class)); - } -} \ No newline at end of file diff --git a/src/test/java/mpo/dayon/assistant/network/NetworkAssistantEngineTest.java b/src/test/java/mpo/dayon/assistant/network/NetworkAssistantEngineTest.java deleted file mode 100644 index b1d91d6e..00000000 --- a/src/test/java/mpo/dayon/assistant/network/NetworkAssistantEngineTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package mpo.dayon.assistant.network; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.mockito.Mockito.*; - -class NetworkAssistantEngineTest { - - private NetworkAssistantEngine engine; - private NetworkAssistantEngineListener listener; - - @BeforeEach - void init() { - engine = new NetworkAssistantEngine(null, null, null); - listener = mock(NetworkAssistantEngineListener.class); - engine.addListener(listener); - } - - @Test - void testReconfigureStart() { - // given - engine.configure(new NetworkAssistantEngineConfiguration()); - final NetworkAssistantEngineConfiguration configuration = new NetworkAssistantEngineConfiguration(12345, "http://localhost/"); - engine.reconfigure(configuration); - - // when - engine.start(false); - - // then - verify(listener, timeout(2000).atLeastOnce()).onStarting(configuration.getPort()); - } - - @Test - void testCancel() { - // given - - // when - engine.cancel(); - - // then - verify(listener).onDisconnecting(); - } -} \ No newline at end of file diff --git a/src/test/java/mpo/dayon/assistant/utils/NetworkUtilitiesTest.java b/src/test/java/mpo/dayon/assistant/utils/NetworkUtilitiesTest.java deleted file mode 100644 index 47ee1207..00000000 --- a/src/test/java/mpo/dayon/assistant/utils/NetworkUtilitiesTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package mpo.dayon.assistant.utils; - -import org.junit.jupiter.api.Test; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; - -class NetworkUtilitiesTest { - - @Test - void getInetAddresses() { - // given - String loopBack = "127.0.0.1"; - - // when - final List inetAddresses = NetworkUtilities.getInetAddresses(); - - // then - assertFalse(inetAddresses.isEmpty()); - assertEquals(loopBack, inetAddresses.get(inetAddresses.size()-1)); - } -} \ No newline at end of file