Compare commits

...

19 commits
v0.5.3 ... main

Author SHA1 Message Date
578fdb0c1b
fix gui issue with receiver 2023-08-19 18:46:26 +02:00
61903d6140
readme update 2023-08-19 16:37:10 +02:00
bc28d99f87
specifiy iui fallback version 2023-08-19 16:31:48 +02:00
a0989bdc73
add delay option 2023-08-19 16:30:50 +02:00
9b7577ce65
migrate gui to a feature flag, drastically speed up send times 2023-08-19 16:14:35 +02:00
69081acc51
fix stdio 2023-03-02 18:00:55 +01:00
a10ebcd10c
Update README.md 2022-11-15 14:26:14 +01:00
74fc62483b lockfile thing 2022-10-28 14:14:37 +02:00
f2d49809ac version bump 2022-10-28 14:07:03 +02:00
7766698c68 fix a x/0 crash 2022-10-28 14:06:29 +02:00
0d34f49564 bump version 2022-10-03 18:59:57 +02:00
783116217d Merge branch 'main' of github.com:TudbuT/qft 2022-10-03 18:48:21 +02:00
c8074ef4b6 better style 2022-10-03 18:48:18 +02:00
29fbb2de67
Merge pull request #5 from amatgil/main
Speed indicator
2022-10-03 18:44:30 +02:00
amatgil
15c4327c85 Should be working correctly :)) 2022-10-03 18:22:03 +02:00
amatgil
93d5806e49 Attempted to add speed indicator on both sender and receiver (untested) 2022-10-03 00:56:32 +02:00
f5caf49c92 Merge branch 'main' of github.com:TudbuT/qft 2022-09-06 18:04:24 +02:00
5347a60057 remove unused code 2022-09-06 18:04:14 +02:00
934a86d5b7
Update COPYING 2022-09-01 21:18:12 +02:00
6 changed files with 249 additions and 149 deletions

24
COPYING
View file

@ -1,16 +1,16 @@
QFT: An application for Quick (and really reliable) Peer-To-Peer file transfer.
QFT: An application for Quick (and really reliable) Peer-To-Peer file transfer.
Copyright (C) 2022 Daniel H. / TudbuT
Copyright (C) 2022 Daniel H. / TudbuT
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

180
Cargo.lock generated
View file

@ -4,9 +4,9 @@ version = 3
[[package]]
name = "addr2line"
version = "0.17.0"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3"
dependencies = [
"gimli",
]
@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
version = "0.7.18"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a"
dependencies = [
"memchr",
]
@ -48,9 +48,9 @@ dependencies = [
[[package]]
name = "backtrace"
version = "0.3.66"
version = "0.3.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7"
checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12"
dependencies = [
"addr2line",
"cc",
@ -93,9 +93,12 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cc"
version = "1.0.73"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01"
dependencies = [
"libc",
]
[[package]]
name = "cexpr"
@ -145,10 +148,16 @@ dependencies = [
]
[[package]]
name = "embed-resource"
version = "1.7.3"
name = "deranged"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "936c1354206a875581696369aef920e12396e93bbd251c43a7a3f3fa85023a7d"
checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929"
[[package]]
name = "embed-resource"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e62abb876c07e4754fae5c14cafa77937841f01740637e17d78dc04352f32a5e"
dependencies = [
"cc",
"rustc_version",
@ -194,9 +203,9 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.2.7"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
dependencies = [
"cfg-if 1.0.0",
"libc",
@ -205,15 +214,15 @@ dependencies = [
[[package]]
name = "gimli"
version = "0.26.2"
version = "0.27.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
[[package]]
name = "glob"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "hermit-abi"
@ -236,13 +245,11 @@ dependencies = [
[[package]]
name = "iui"
version = "0.3.0"
source = "git+https://github.com/rust-native-ui/libui-rs#6ff94425b341cf718e29d07067dbf82f9215a6d5"
source = "git+https://github.com/rust-native-ui/libui-rs#3496903ae9c4fd68731587dc11739da90a4f0e12"
dependencies = [
"bitflags",
"failure",
"lazy_static",
"libc",
"regex",
"ui-sys",
]
@ -260,9 +267,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.132"
version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]]
name = "libloading"
@ -276,12 +283,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.17"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if 1.0.0",
]
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "memchr"
@ -291,37 +295,28 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "miniz_oxide"
version = "0.5.3"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
dependencies = [
"adler",
]
[[package]]
name = "nom"
version = "5.1.2"
version = "5.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b"
dependencies = [
"memchr",
"version_check",
]
[[package]]
name = "num_threads"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
dependencies = [
"libc",
]
[[package]]
name = "object"
version = "0.29.0"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1"
dependencies = [
"memchr",
]
@ -334,28 +329,28 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "pkg-config"
version = "0.3.25"
version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "ppv-lite86"
version = "0.2.16"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.43"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "qft"
version = "0.5.3"
version = "0.5.6"
dependencies = [
"iui",
"rand",
@ -370,9 +365,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
name = "quote"
version = "1.0.21"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
@ -400,18 +395,30 @@ dependencies = [
[[package]]
name = "rand_core"
version = "0.6.3"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "regex"
version = "1.6.0"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69"
dependencies = [
"aho-corasick",
"memchr",
@ -420,15 +427,15 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.6.27"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
[[package]]
name = "rustc-demangle"
version = "0.1.21"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustc-hash"
@ -447,15 +454,15 @@ dependencies = [
[[package]]
name = "semver"
version = "1.0.13"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711"
checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
[[package]]
name = "serde"
version = "1.0.143"
version = "1.0.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553"
checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9"
[[package]]
name = "shlex"
@ -471,9 +478,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "syn"
version = "1.0.99"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
@ -494,9 +501,9 @@ dependencies = [
[[package]]
name = "termcolor"
version = "1.1.3"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
dependencies = [
"winapi-util",
]
@ -512,19 +519,26 @@ dependencies = [
[[package]]
name = "time"
version = "0.3.14"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b"
checksum = "a79d09ac6b08c1ab3906a2f7cc2e81a0e27c7ae89c63812df75e52bef0751e07"
dependencies = [
"libc",
"num_threads",
"deranged",
"serde",
"time-core",
]
[[package]]
name = "toml"
version = "0.5.8"
name = "time-core"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
[[package]]
name = "toml"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
dependencies = [
"serde",
]
@ -532,7 +546,7 @@ dependencies = [
[[package]]
name = "ui-sys"
version = "0.2.1"
source = "git+https://github.com/rust-native-ui/libui-rs#6ff94425b341cf718e29d07067dbf82f9215a6d5"
source = "git+https://github.com/rust-native-ui/libui-rs#3496903ae9c4fd68731587dc11739da90a4f0e12"
dependencies = [
"bindgen",
"cc",
@ -543,21 +557,21 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.3"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]]
name = "unicode-width"
version = "0.1.9"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]]
name = "unicode-xid"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "vec_map"
@ -583,9 +597,9 @@ dependencies = [
[[package]]
name = "vswhom-sys"
version = "0.1.1"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22025f6d8eb903ebf920ea6933b70b1e495be37e2cb4099e62c80454aaf57c39"
checksum = "d3b17ae1f6c8a2b28506cd96d412eebf83b4a0ff2cbefeeb952f2f9dfa44ba18"
dependencies = [
"cc",
"libc",

View file

@ -1,11 +1,14 @@
[package]
name = "qft"
version = "0.5.3"
version = "0.5.6"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
iui.git = "https://github.com/rust-native-ui/libui-rs"
rand = "0"
time = "0"
iui = { git = "https://github.com/rust-native-ui/libui-rs", optional = true, version = "0.3" }
rand = { version = "0.8", optional = true }
time = "0.3"
[features]
gui = [ "dep:iui", "dep:rand" ]

View file

@ -6,7 +6,7 @@ QFT is a small application for Quick (and really reliable) Peer-To-Peer UDP file
...look at the "Releases" section on the sidebar. You should see a link titled vX.Y.Z. Click on
that, and then choose the right file for your OS: `qft` for Linux, `qft-mac` for Mac, and `qft.exe`
for Windows (currently unavailable, sorry.). Download this file, make it executable in case of Linux or Mac, and then follow your
for Windows. Download this file, make it executable in case of Linux or Mac, and then follow your
friend's instructions on how to receive the file they wanted to send you.
## Usage:
@ -19,13 +19,13 @@ OR
- On both PCs, enter `qft gui`.
- Select mode
- Select file to send and file to save to
- Update the shared phrases to match
- Update the shared phrases and bitrate to match
- Click start
### Arguments:
```
qft helper <bind-port>
qft sender <helper-address>:<helper-port> <phrase> <filename> [bitrate] [skip]
qft sender <helper-address>:<helper-port> <phrase> <filename> [send-delay] [bitrate] [skip]
qft receiver <helper-address>:<helper-port> <phrase> <filename> [bitrate] [skip]
```
@ -72,8 +72,11 @@ here as an indicator that no more data will be exchanged between the "previously
## Tips 'n Tricks
- You can add a number to the end of both of your commands (after the filename) to
boost transfer speeds (higher = faster), but a too large number might cause unreliability
due to local network conditions or VPNs. The maximum possible is 65532 (65535 - 3).
boost transfer speeds (lower = faster), but a too small number might cause unreliability
due to local network conditions, VPNs, etc (default is 500). This will modify the delay between
packets sent.
- You can also add a number *after that*. It will modify packet size, and a higher number here has
similar effects as a lower one in the previous arg.
- You can run a helper yourself, as the "helper" mode argument suggests. This helper should simply
be run on a server which is reachable from all over the web (a cheap VPS will definitely do).
- Helpers don't **have to** be run on a public server, they work in LAN too, but that way, only

View file

@ -116,8 +116,41 @@ pub fn gui() -> Result<(), iui::UIError> {
LayoutStrategy::Compact,
);
let mut delay = VerticalBox::new(&ui);
let mut delay_slider = Slider::new(&ui, 100, 3_000);
let delayb = Ref::new(&delay_slider);
let mut delay_box = Entry::new(&ui);
delay_slider.set_value(&ui, 500);
delay_box.set_value(&ui, "500");
// We know that ui.main() will wait until the UI is dead, so these are safe.
let sb = RefMut::new(&mut delay_slider);
let bb = RefMut::new(&mut delay_box);
let uib = Ref::new(&ui);
let uib1 = uib.clone();
delay_box.on_changed(&ui, move |val| {
sb.get().set_value(
uib.get(),
u16::from_str_radix(val.as_str(), 10).unwrap_or(256) as i32,
);
});
delay_slider.on_changed(&ui, move |val| {
bb.get().set_value(uib1.get(), val.to_string().as_str());
});
delay.set_padded(&ui, true);
delay.append(&ui, delay_slider, LayoutStrategy::Compact);
delay.append(&ui, delay_box, LayoutStrategy::Compact);
vbox.append(
&ui,
wrap(
&ui,
"Delay in µs: (higher = more reliable, lower = faster)",
delay,
),
LayoutStrategy::Compact,
);
let mut speed = VerticalBox::new(&ui);
let mut speed_slider = Slider::new(&ui, 100, 10_000);
let mut speed_slider = Slider::new(&ui, 100, 3_000);
let speedb = Ref::new(&speed_slider);
let mut speed_box = Entry::new(&ui);
speed_slider.set_value(&ui, 256);
@ -183,6 +216,10 @@ pub fn gui() -> Result<(), iui::UIError> {
args.push(a);
let a = pathb.get().clone();
args.push(a);
if modeb.get().selected(uib.get()) == 1 {
let a = delayb.get().value(uib.get()).to_string();
args.push(a);
}
let a = speedb.get().value(uib.get()).to_string();
args.push(a);
let a = skipb.get().value(uib.get());
@ -307,12 +344,6 @@ pub fn gui() -> Result<(), iui::UIError> {
window.set_child(&ui, vbox);
window.show(&ui);
/*si.on_should_quit(move || {
let quit_window = Window::new(&ui, "Really quit?", 300, 100, WindowType::NoMenubar);
let label = Label::new(&ui, "Do you really want to quit? Data is currently being transferred.");
ui.quit();
});*/
ui.event_loop().run(&ui);
println!("GUI done");

View file

@ -1,3 +1,4 @@
#[cfg(feature = "gui")]
mod gui;
use std::{
@ -21,6 +22,7 @@ enum SafeReadWritePacket {
ResendRequest,
End,
}
use SafeReadWritePacket::*;
struct SafeReadWrite {
socket: UdpSocket,
@ -50,12 +52,12 @@ impl SafeReadWrite {
}
}
pub fn write_safe(&mut self, buf: &[u8]) -> Result<(), Error> {
self.write_flush_safe(buf, false)
pub fn write_safe(&mut self, buf: &[u8], delay: u64) -> Result<(), Error> {
self.write_flush_safe(buf, false, delay)
}
pub fn write_flush_safe(&mut self, buf: &[u8], flush: bool) -> Result<(), Error> {
self.internal_write_safe(buf, SafeReadWritePacket::Write, flush, false)
pub fn write_flush_safe(&mut self, buf: &[u8], flush: bool, delay: u64) -> Result<(), Error> {
self.internal_write_safe(buf, Write, flush, false, delay)
}
pub fn read_safe(&mut self, buf: &[u8]) -> Result<(Vec<u8>, usize), Error> {
@ -85,7 +87,7 @@ impl SafeReadWrite {
let id = u16::from_be_bytes([buf[0], buf[1]]);
if id <= self.packet_count_in as u16 {
self.socket
.send(&[buf[0], buf[1], SafeReadWritePacket::Ack as u8])
.send(&[buf[0], buf[1], Ack as u8])
.expect("send error");
}
if id == self.packet_count_in as u16 {
@ -109,10 +111,10 @@ impl SafeReadWrite {
// ask to resend, then do nothing
let id = (self.packet_count_in as u16).to_be_bytes();
self.socket
.send(&[id[0], id[1], SafeReadWritePacket::ResendRequest as u8])
.send(&[id[0], id[1], ResendRequest as u8])
.expect("send error");
}
if buf[2] == SafeReadWritePacket::End as u8 {
if buf[2] == End as u8 {
return Ok((vec![], 0));
}
}
@ -127,7 +129,7 @@ impl SafeReadWrite {
}
pub fn end(mut self) -> UdpSocket {
let _ = self.internal_write_safe(&mut [], SafeReadWritePacket::End, true, true);
let _ = self.internal_write_safe(&mut [], End, true, true, 3000);
self.socket
}
@ -138,6 +140,7 @@ impl SafeReadWrite {
packet: SafeReadWritePacket,
flush: bool,
exit_on_lost: bool,
delay: u64,
) -> Result<(), Error> {
if buf.len() > 0xfffc {
panic!(
@ -167,6 +170,7 @@ impl SafeReadWrite {
continue;
}
}
thread::sleep(Duration::from_micros(delay));
self.last_transmitted.insert(idn, vbuf);
break;
}
@ -185,12 +189,22 @@ impl SafeReadWrite {
}
let mut is_catching_up = false;
loop {
match self.socket.recv(&mut buf).ok() {
match (
if !wait {
self.socket.set_nonblocking(true).unwrap()
} else {
()
},
self.socket.recv(&mut buf).ok(),
self.socket.set_nonblocking(false).unwrap(),
)
.1
{
Some(x) => {
if x != 3 {
continue;
}
if buf[2] == SafeReadWritePacket::Ack as u8 {
if buf[2] == Ack as u8 {
let n = u16::from_be_bytes([buf[0], buf[1]]);
self.last_transmitted.remove(&n);
if n == idn {
@ -202,35 +216,40 @@ impl SafeReadWrite {
// previous ones must be as well.
}
}
if buf[2] == SafeReadWritePacket::ResendRequest as u8 {
if buf[2] == ResendRequest as u8 {
let mut n = u16::from_be_bytes([buf[0], buf[1]]);
thread::sleep(Duration::from_millis(100));
while let Some(_) = self.socket.recv(&mut buf).ok() {}
if !is_catching_up && !env::var("QFT_HIDE_DROPS").is_ok() {
println!("\r\x1b[KA packet dropped: {}", &n);
}
wait = true;
is_catching_up = true;
while n <= idn && !(idn == 0xffff && n == 0) {
let buf = self.last_transmitted.get(&n);
if let Some(buf) = buf {
loop {
// resend until success
match self.socket.send(&buf.as_slice()) {
Ok(x) => {
if x != buf.len() {
if !is_catching_up {
wait = true;
is_catching_up = true;
while n <= idn && !(idn == 0xffff && n == 0) {
let buf = self.last_transmitted.get(&n);
if let Some(buf) = buf {
loop {
// resend until success
match self.socket.send(&buf.as_slice()) {
Ok(x) => {
if x != buf.len() {
continue;
}
}
Err(_) => {
continue;
}
}
Err(_) => {
continue;
}
};
};
thread::sleep(Duration::from_millis(4));
break;
}
} else {
break;
}
} else {
break;
// do NOT remove from last_transmitted yet, wait for Ack to do that.
n += 1;
}
// do NOT remove from last_transmitted yet, wait for Ack to do that.
n += 1;
}
}
}
@ -252,6 +271,7 @@ impl SafeReadWrite {
continue;
}
}
thread::sleep(Duration::from_millis(4));
break;
}
start = unix_millis();
@ -278,10 +298,13 @@ fn main() {
panic!("no args");
}
if args.len() == 1 {
#[cfg(feature = "gui")]
match gui::gui() {
Ok(_) => (),
Err(_) => print_args(&args),
}
#[cfg(not(feature = "gui"))]
print_args(&args)
}
match args
.get(1)
@ -291,7 +314,10 @@ fn main() {
"helper" => helper(&args),
"sender" => sender(&args, |_| {}),
"receiver" => receiver(&args, |_| {}),
#[cfg(feature = "gui")]
"gui" => gui::gui().expect("can't use gui"),
#[cfg(not(feature = "gui"))]
"gui" => println!("Feature 'gui' was not enabled during compilation. GUI not available."),
"version" => println!("QFT version: {}", env!("CARGO_PKG_VERSION")),
_ => print_args(&args),
}
@ -367,13 +393,18 @@ pub fn helper(args: &Vec<String>) {
pub fn sender<F: Fn(f32)>(args: &Vec<String>, on_progress: F) {
let connection = holepunch(args);
let br = args
let dly = args
.get(5)
.map(|s| u64::from_str_radix(s, 10))
.unwrap_or(Ok(500))
.expect("bad delay operand");
let br = args
.get(6)
.map(|s| u32::from_str_radix(s, 10))
.unwrap_or(Ok(256))
.expect("bad bitrate argument");
let begin = args
.get(6)
.get(7)
.map(|s| u64::from_str_radix(s, 10))
.unwrap_or(Ok(0))
.expect("bad begin operand");
@ -396,9 +427,10 @@ pub fn sender<F: Fn(f32)>(args: &Vec<String>, on_progress: F) {
let mut bytes_sent: u64 = 0;
let mut last_update = unix_millis();
let len = file.metadata().expect("bad metadata").len();
sc.write_safe(&len.to_be_bytes())
sc.write_safe(&len.to_be_bytes(), 3000)
.expect("unable to send file length");
println!("Length: {}", &len);
let mut time = unix_millis();
loop {
let read = file.read(&mut buf).expect("file read error");
if read == 0 && !env::var("QFT_STREAM").is_ok() {
@ -408,11 +440,19 @@ pub fn sender<F: Fn(f32)>(args: &Vec<String>, on_progress: F) {
return;
}
sc.write_safe(&buf[..read]).expect("send error");
sc.write_safe(&buf[..read], dly).expect("send error");
bytes_sent += read as u64;
if (bytes_sent % (br * 20) as u64) < (br as u64) {
print!("\r\x1b[KSent {} bytes", bytes_sent);
let elapsed = unix_millis() - time;
let elapsed = if elapsed == 0 { 1 } else { elapsed };
print!(
"\r\x1b[KSent {} bytes; Speed: {} kb/s",
bytes_sent,
br as usize * 20 / elapsed as usize
);
stdout().flush().unwrap();
time = unix_millis();
}
if unix_millis() - last_update > 100 {
on_progress((bytes_sent + begin) as f32 / len as f32);
@ -463,8 +503,9 @@ pub fn receiver<F: Fn(f32)>(args: &Vec<String>, on_progress: F) {
let len = u64::from_be_bytes([
len[0], len[1], len[2], len[3], len[4], len[5], len[6], len[7],
]);
file.set_len(len).expect("unable to set file length");
let _ = file.set_len(len);
println!("Length: {}", &len);
let mut time = unix_millis();
loop {
let (mbuf, amount) = sc.read_safe(buf).expect("read error");
let buf = &mbuf.leak()[..amount];
@ -478,8 +519,16 @@ pub fn receiver<F: Fn(f32)>(args: &Vec<String>, on_progress: F) {
file.flush().expect("file flush error");
bytes_received += amount as u64;
if (bytes_received % (br * 20) as u64) < (br as u64) {
print!("\r\x1b[KReceived {} bytes", bytes_received);
let elapsed = unix_millis() - time;
let elapsed = if elapsed == 0 { 1 } else { elapsed };
print!(
"\r\x1b[KReceived {} bytes; Speed: {} kb/s",
bytes_received,
br as usize * 20 / elapsed as usize
);
stdout().flush().unwrap();
time = unix_millis();
}
if unix_millis() - last_update > 100 {
on_progress((bytes_received + begin) as f32 / len as f32);
@ -581,7 +630,7 @@ fn print_args(args: &Vec<String>) {
println!(
"No arguments. Needed: \n\
| {} helper <bind-port>\n\
| {} sender <helper-address>:<helper-port> <phrase> <filename> [bitrate] [skip]\n\
| {} sender <helper-address>:<helper-port> <phrase> <filename> [send-dly] [bitrate] [skip]\n\
| {} receiver <helper-address>:<helper-port> <phrase> <filename> [bitrate] [skip]\n\
| {} gui\n\
| {} version\n",